Quoting Martin Storsjö (2016-05-09 13:34:26)
> This allows callers with avio write callbacks to get the bytestream
> positions that correspond to keyframes, suitable for live streaming.
>
> In the simplest form, a caller could expect that a header is written
> to the bytestream during the avformat_write_header, and the data
> output to the avio context during e.g. av_write_frame corresponds
> exactly to the current packet passed in.
>
> When combined with av_interleaved_write_frame, and with muxers that
> do buffering (most muxers that do some sort of fragmenting or
> clustering), the mapping from input data to bytestream positions
> is nontrivial.
>
> This allows callers to get directly information about what part
> of the bytestream is what, without having to resort to assumptions
> about the muxer behaviour.
>
> One keyframe/fragment/block can still be split into multiple (if
> they are larger than the aviocontext buffer), which would call
> the callback with e.g. AVIO_DATA_SYNC_POINT, followed by AVIO_DATA_OPAQUE
> for the second time it is called with the following data.
>
> TODO: Do we need a muxer flag to indicate muxers that actually mark
> keyframes in this way? All muxers that don't implement anything
> special will at least mark header/trailer.
Maybe call it "extended markers"? That said, I'm not sure it would be very
useful. It's probably still all very muxer specific.
>
> TODO: What should the new callback be called? Other suggestions
> were write_data_with_type or write_packet2. IMO it shouldn't be called
> write_packet2, since it's not supposed to be a complete replacement
> used by all callers; it's only supposed to be used by callers that
> actually are interested in the data. (If using this callback, the
> avio context is flushed potentially more often, which isn't ideal
> for all users, e.g. when writing to a file.)
The current name is fine with me.
>
> Better suggestions on the data type names are welcome.
> ---
> doc/APIchanges | 4 ++++
> libavformat/avio.h | 61
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> libavformat/aviobuf.c | 52 +++++++++++++++++++++++++++++++++++++++++--
> libavformat/mux.c | 6 +++++
> libavformat/version.h | 4 ++--
> 5 files changed, 123 insertions(+), 4 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index b83c5ae..c15bc05 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,10 @@ libavutil: 2015-08-28
>
> API changes, most recent first:
>
> +2016-xx-xx - xxxxxxx - lavf 57.6.0 - avio.h
> + Add AVIODataType, write_data_type, ignore_parse_point and
> + avio_write_marker.
> +
> 2016-xx-xx - xxxxxxx - lavu 55.10.0 - opt.h
> Add av_opt_copy().
>
> diff --git a/libavformat/avio.h b/libavformat/avio.h
> index d60a597..a7c8533 100644
> --- a/libavformat/avio.h
> +++ b/libavformat/avio.h
> @@ -54,6 +54,37 @@ typedef struct AVIOInterruptCB {
> } AVIOInterruptCB;
>
> /**
> + * Different data types that can be returned via the AVIO
> + * write_data_type callback.
> + */
> +enum AVIODataType {
This naming looks a bit too generic to me. Perhaps something like
AVIODataMarkerType would be better?
> + /**
> + * Header data; this needs to be present for the stream to be decodeable.
> + */
> + AVIO_DATA_HEADER,
> + /**
> + * A point in the output bytestream where a decoder can start decoding
> + * (i.e. a keyframe). A decoder given the data flagged with
> + * AVIO_DATA_HEADER, followed by any AVIO_DATA_SYNC_POINT, should
> + * give decodeable results.
> + */
> + AVIO_DATA_SYNC_POINT,
> + /**
> + * A point in the output bytestream where a demuxer can start parsing
> + * (for non self synchronizing bytestream formats).
> + */
> + AVIO_DATA_PARSE_POINT,
It is not exactly clear what the difference between those two is. And the actual
muxer patch don't make it very obvious either.
> + /**
> + * This is any, unlabelled data.
> + */
> + AVIO_DATA_OPAQUE,
> + /**
> + * Trailer data. (TODO: Description?)
> + */
> + AVIO_DATA_TRAILER
> +};
> +
> +/**
> * Bytestream IO Context.
> * New fields can be added to the end with minor version bumps.
> * Removal, reordering and changes to existing fields require a major
> @@ -115,6 +146,24 @@ typedef struct AVIOContext {
> * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not
> seekable.
> */
> int seekable;
> +
> + /**
> + * A callback that is used instead of write_packet.
> + */
> + int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,
> + enum AVIODataType type, int64_t time);
> + /**
> + * If set, don't call write_data_type separately for
> AVIO_DATA_PARSE_POINT,
> + * but ignore them and treat them as AVIO_DATA_OPAQUE (to avoid
> needlessly
> + * small chunks of data returned from the callback).
> + */
> + int ignore_parse_point;
> +
> + /**
> + * Internal, not meant to be used from outside of AVIOContext.
> + */
> + enum AVIODataType current_type;
> + int64_t last_time;
I guess we should switch the internal callers to allocate AVIOContext
dynamically and move this stuff to an AVIOInternal. Not saying you have to do it
now, just a not for the future.
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel