Translating to Diagram - softworkz/ffmpeg_output_apis GitHub Wiki
The graph visualization could have been implemented locally to graphprint.c, but should there be another case in the future where data/diagram output is desired, this would have created once another copy-paste situation, so the printing was done as just as another textformatter.
To enable this for universal use, a number of extensions to the API are introduced.
The following new section flags are added:
- AV_TEXTFORMAT_SECTION_FLAG_IS_SUBGRAPH
Each section of this tzpe should be rendered as a subgraph enclosing all contained elements - AV_TEXTFORMAT_SECTION_FLAG_IS_SHAPE
Each section with this flag is rendered as a shape Shapes can have content but cannot contain other shapes nor subgraphs - AV_TEXTFORMAT_SECTION_PRINT_TAGS
This flag indicate that the content in this section should be used and printed in the contex of the current parent element - AV_TEXTFORMAT_SECTION_FLAG_HAS_LINKS This indicates that a section represents a link when it prints the corresponding fiels Links are always printed out-of-band, i.e. they are written to a buffer and that buffer is written ro to the actual output only short before the end of printing.
For graph visualization there are a number of cases where the text/diagram formatter needs additional inforrmation. In most of these cases the information is printed anyway already, the formatter just doesn't know which of the data fields holds which information.
The following members are added to AVTextFormatSection:
const char *id_key; ///< name of the key to be used as the id
const char *src_id_key; ///< name of the key to be used as the source id for diagram connections
const char *dest_id_key; ///< name of the key to be used as the target id for diagram connections
const char *linktype_key; ///< name of the key to be used as the link type for diagram connections
This allows the diagram formatter to collect this information while an element in a section is still open and print that (.d)
This is an alternative method to the above. A new AVTextFormatSectionContext
structure is added with members like shown below:
typedef struct AVTextFormatSectionContext {
const char *context_id;
const char *context_type;
int context_flags;
} AVTextFormatSectionContext;
This leverages the existing way for supplying extra data in the second parameter of the avtext_print_section_header()
API function.
The current logic for this (opaque) data is that one can set a function get_type()
in the AVTextFormatSection
structure and when that is defined, a formatter can call it, supplying the opaque data pointer.
The intended logic for extending would be:
=> If no get_type()
function is defined for the section but the the data
parameter is non-NULL, then it can be assumed that it can be cast to an AVTextFormatSectionContext
structure.
Note
There exists a certain overlap between the latter two methods but also differences, so this might need further discussion.
With the new section flags from above, the individual sections can be marked appropriately to define the way(s) how they are contributing to the diagram creation. Also notable: All sections having none of those flags are simply ignored.
This table shows the mapping of execution graph sections to diagram content:
Subgraph | Shape | Link | PrintTags | Notes | |
---|---|---|---|---|---|
root | All ignored | ||||
graphs | |||||
graph | |||||
graph_inputs | |||||
graph_input | |||||
graph_outputs | |||||
graph_output | |||||
filters | ✔ | ||||
filter | ✔ | ✔ | |||
filter_inputs | (ignored) | ||||
filter_input | ✔ | ||||
filter_outputs | (ignored) | ||||
filter_output | ✔ | ||||
hw_frames_context | for graphs, graphprint.c includes the values in the parent section | ||||
inputfiles | ✔ | invisible subgraph | |||
inputfile | ✔ | ||||
inputstreams | ✔ | invisible subgraph | |||
inputstream | ✔ | ✔ | |||
outputfiles | ✔ | invisible subgraph | |||
outputfile | ✔ | ||||
outputstreams | ✔ | invisible subgraph | |||
outputstream | ✔ | ✔ | |||
streamlinks | (ignored) | ||||
streamlink | ✔ | ||||
decoders | ✔ | invisible subgraph | |||
decoder | ✔ | ✔ | ✔ | used for both, shape rendering and a link | |
encoders | ✔ | invisible subgraph | |||
encoder | ✔ | ✔ | ✔ | used for both, shape rendering and a link |
Some of the sections marked for generating a subgraph element are not even visible in the final diagram (visibility is controlled via CSS), but they are important for enforcing the layout of the diagram.
Invisible subgraph sections are:
- inputfiles keeps all inputfile subgraphs vertically stacked in a column
- inputstreams keeps all inputstream shapes vertically stacked and also makes sure that there's enough room at the top of the inputfile content for the information shown there
- decoders keeps all decoder shapes vertically stacked in a column left-side of all filtergraph subgraphs
(same patterns are used for the output side )
The image below includes those subgraphs that are normally invisible: