mirror of
https://gitee.com/openharmony/third_party_ffmpeg
synced 2024-11-23 19:30:05 +00:00
lavf/mux: add avformat_init_output
This allows a consumer to run the muxer's init function without actually writing the header, which is useful in chained muxers that support automatic bitstream filtering.
This commit is contained in:
parent
8a24e03684
commit
a246fef163
@ -15,6 +15,9 @@ libavutil: 2015-08-28
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2016-10-24 - xxxxxxx - lavf 57.54.100 - avformat.h
|
||||
Add avformat_init_output() and AVSTREAM_INIT_IN_ macros
|
||||
|
||||
2016-10-22 - xxxxxxx - lavu 55.33.100 - avassert.h
|
||||
Add av_assert0_fpu() / av_assert2_fpu()
|
||||
|
||||
|
@ -618,6 +618,8 @@ typedef struct AVOutputFormat {
|
||||
* AVStream parameters that need to be set before packets are sent.
|
||||
* This method must not write output.
|
||||
*
|
||||
* Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure
|
||||
*
|
||||
* Any allocations made here must be freed in deinit().
|
||||
*/
|
||||
int (*init)(struct AVFormatContext *);
|
||||
@ -2374,6 +2376,10 @@ void avformat_close_input(AVFormatContext **s);
|
||||
* @addtogroup lavf_encoding
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define AVSTREAM_INIT_IN_WRITE_HEADER 0 ///< stream parameters initialized in avformat_write_header
|
||||
#define AVSTREAM_INIT_IN_INIT_OUTPUT 1 ///< stream parameters initialized in avformat_init_output
|
||||
|
||||
/**
|
||||
* Allocate the stream private data and write the stream header to
|
||||
* an output media file.
|
||||
@ -2385,13 +2391,37 @@ void avformat_close_input(AVFormatContext **s);
|
||||
* On return this parameter will be destroyed and replaced with a dict containing
|
||||
* options that were not found. May be NULL.
|
||||
*
|
||||
* @return 0 on success, negative AVERROR on failure.
|
||||
* @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec had not already been fully initialized in avformat_init,
|
||||
* AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec had already been fully initialized in avformat_init,
|
||||
* negative AVERROR on failure.
|
||||
*
|
||||
* @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
|
||||
* @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_init_output.
|
||||
*/
|
||||
av_warn_unused_result
|
||||
int avformat_write_header(AVFormatContext *s, AVDictionary **options);
|
||||
|
||||
/**
|
||||
* Allocate the stream private data and initialize the codec, but do not write the header.
|
||||
* May optionally be used before avformat_write_header to initialize stream parameters
|
||||
* before actually writing the header.
|
||||
* If using this function, do not pass the same options to avformat_write_header.
|
||||
*
|
||||
* @param s Media file handle, must be allocated with avformat_alloc_context().
|
||||
* Its oformat field must be set to the desired output format;
|
||||
* Its pb field must be set to an already opened AVIOContext.
|
||||
* @param options An AVDictionary filled with AVFormatContext and muxer-private options.
|
||||
* On return this parameter will be destroyed and replaced with a dict containing
|
||||
* options that were not found. May be NULL.
|
||||
*
|
||||
* @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec requires avformat_write_header to fully initialize,
|
||||
* AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec has been fully initialized,
|
||||
* negative AVERROR on failure.
|
||||
*
|
||||
* @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_write_header.
|
||||
*/
|
||||
av_warn_unused_result
|
||||
int avformat_init_output(AVFormatContext *s, AVDictionary **options);
|
||||
|
||||
/**
|
||||
* Write a packet to an output media file.
|
||||
*
|
||||
|
@ -130,6 +130,16 @@ struct AVFormatInternal {
|
||||
* Timestamp of the end of the shortest stream.
|
||||
*/
|
||||
int64_t shortest_end;
|
||||
|
||||
/**
|
||||
* Whether or not avformat_init_output has already been called
|
||||
*/
|
||||
int initialized;
|
||||
|
||||
/**
|
||||
* Whether or not avformat_init_output fully initialized streams
|
||||
*/
|
||||
int streams_initialized;
|
||||
};
|
||||
|
||||
struct AVStreamInternal {
|
||||
|
@ -423,10 +423,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
*options = tmp;
|
||||
}
|
||||
|
||||
if (s->oformat->init && (ret = s->oformat->init(s)) < 0) {
|
||||
if (s->oformat->deinit)
|
||||
s->oformat->deinit(s);
|
||||
goto fail;
|
||||
if (s->oformat->init) {
|
||||
if ((ret = s->oformat->init(s)) < 0) {
|
||||
if (s->oformat->deinit)
|
||||
s->oformat->deinit(s);
|
||||
return ret;
|
||||
}
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -493,31 +496,64 @@ static int write_header_internal(AVFormatContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
||||
int avformat_init_output(AVFormatContext *s, AVDictionary **options)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if ((ret = init_muxer(s, options)) < 0)
|
||||
return ret;
|
||||
|
||||
s->internal->initialized = 1;
|
||||
s->internal->streams_initialized = ret;
|
||||
|
||||
if (s->oformat->init && ret) {
|
||||
if ((ret = init_pts(s)) < 0)
|
||||
return ret;
|
||||
|
||||
if (s->avoid_negative_ts < 0) {
|
||||
av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
|
||||
if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
|
||||
s->avoid_negative_ts = 0;
|
||||
} else
|
||||
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
|
||||
}
|
||||
|
||||
return AVSTREAM_INIT_IN_INIT_OUTPUT;
|
||||
}
|
||||
|
||||
return AVSTREAM_INIT_IN_WRITE_HEADER;
|
||||
}
|
||||
|
||||
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
||||
{
|
||||
int ret = 0;
|
||||
int already_initialized = s->internal->initialized;
|
||||
int streams_already_initialized = s->internal->streams_initialized;
|
||||
|
||||
if (!already_initialized)
|
||||
if ((ret = avformat_init_output(s, options)) < 0)
|
||||
return ret;
|
||||
|
||||
if (!(s->oformat->check_bitstream && s->flags & AVFMT_FLAG_AUTO_BSF)) {
|
||||
ret = write_header_internal(s);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ret = init_pts(s)) < 0)
|
||||
goto fail;
|
||||
if (!s->internal->streams_initialized) {
|
||||
if ((ret = init_pts(s)) < 0)
|
||||
goto fail;
|
||||
|
||||
if (s->avoid_negative_ts < 0) {
|
||||
av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
|
||||
if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
|
||||
s->avoid_negative_ts = 0;
|
||||
} else
|
||||
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
|
||||
if (s->avoid_negative_ts < 0) {
|
||||
av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
|
||||
if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
|
||||
s->avoid_negative_ts = 0;
|
||||
} else
|
||||
s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return streams_already_initialized;
|
||||
|
||||
fail:
|
||||
if (s->oformat->deinit)
|
||||
@ -1292,6 +1328,10 @@ fail:
|
||||
if (s->oformat->deinit)
|
||||
s->oformat->deinit(s);
|
||||
|
||||
s->internal->header_written =
|
||||
s->internal->initialized =
|
||||
s->internal->streams_initialized = 0;
|
||||
|
||||
if (s->pb)
|
||||
avio_flush(s->pb);
|
||||
if (ret == 0)
|
||||
|
@ -32,7 +32,7 @@
|
||||
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
|
||||
// Also please add any ticket numbers that you believe might be affected here
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 57
|
||||
#define LIBAVFORMAT_VERSION_MINOR 53
|
||||
#define LIBAVFORMAT_VERSION_MINOR 54
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user