lavf: add avformat_write_header() as a replacement for av_write_header().
It supports more convenient setting of AVOptions.
This commit is contained in:
@@ -1322,7 +1322,12 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index,
|
|||||||
/**
|
/**
|
||||||
* media file output
|
* media file output
|
||||||
*/
|
*/
|
||||||
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
|
#if FF_API_FORMAT_PARAMETERS
|
||||||
|
/**
|
||||||
|
* @deprecated pass the options to avformat_write_header directly.
|
||||||
|
*/
|
||||||
|
attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split a URL string into components.
|
* Split a URL string into components.
|
||||||
@@ -1350,6 +1355,24 @@ void av_url_split(char *proto, int proto_size,
|
|||||||
char *path, int path_size,
|
char *path, int path_size,
|
||||||
const char *url);
|
const char *url);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate the stream private data and write the stream header to
|
||||||
|
* an output media file.
|
||||||
|
*
|
||||||
|
* @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 openened 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 0 on success, negative AVERROR on failure.
|
||||||
|
*
|
||||||
|
* @see av_opt_find, av_dict_set, avio_open, av_oformat_next.
|
||||||
|
*/
|
||||||
|
int avformat_write_header(AVFormatContext *s, AVDictionary **options);
|
||||||
|
|
||||||
|
#if FF_API_FORMAT_PARAMETERS
|
||||||
/**
|
/**
|
||||||
* Allocate the stream private data and write the stream header to an
|
* Allocate the stream private data and write the stream header to an
|
||||||
* output media file.
|
* output media file.
|
||||||
@@ -1358,8 +1381,11 @@ void av_url_split(char *proto, int proto_size,
|
|||||||
*
|
*
|
||||||
* @param s media file handle
|
* @param s media file handle
|
||||||
* @return 0 if OK, AVERROR_xxx on error
|
* @return 0 if OK, AVERROR_xxx on error
|
||||||
|
*
|
||||||
|
* @deprecated use avformat_write_header.
|
||||||
*/
|
*/
|
||||||
int av_write_header(AVFormatContext *s);
|
attribute_deprecated int av_write_header(AVFormatContext *s);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a packet to an output media file.
|
* Write a packet to an output media file.
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st,
|
|||||||
ffio_fdopen(&rtpctx->pb, handle);
|
ffio_fdopen(&rtpctx->pb, handle);
|
||||||
} else
|
} else
|
||||||
ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
|
ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size);
|
||||||
ret = av_write_header(rtpctx);
|
ret = avformat_write_header(rtpctx, NULL);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (handle) {
|
if (handle) {
|
||||||
|
|||||||
@@ -2733,6 +2733,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6
|
|||||||
/************************************************************/
|
/************************************************************/
|
||||||
/* output media file */
|
/* output media file */
|
||||||
|
|
||||||
|
#if FF_API_FORMAT_PARAMETERS
|
||||||
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
|
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2755,6 +2756,7 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int validate_codec_tag(AVFormatContext *s, AVStream *st)
|
static int validate_codec_tag(AVFormatContext *s, AVStream *st)
|
||||||
{
|
{
|
||||||
@@ -2789,15 +2791,29 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if FF_API_FORMAT_PARAMETERS
|
||||||
int av_write_header(AVFormatContext *s)
|
int av_write_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
int ret, i;
|
return avformat_write_header(s, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
||||||
|
{
|
||||||
|
int ret = 0, i;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
|
AVDictionary *tmp = NULL;
|
||||||
|
|
||||||
|
if (options)
|
||||||
|
av_dict_copy(&tmp, *options, 0);
|
||||||
|
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
// some sanity checks
|
// some sanity checks
|
||||||
if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
|
if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) {
|
||||||
av_log(s, AV_LOG_ERROR, "no streams\n");
|
av_log(s, AV_LOG_ERROR, "no streams\n");
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0;i<s->nb_streams;i++) {
|
for(i=0;i<s->nb_streams;i++) {
|
||||||
@@ -2807,7 +2823,8 @@ int av_write_header(AVFormatContext *s)
|
|||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
if(st->codec->sample_rate<=0){
|
if(st->codec->sample_rate<=0){
|
||||||
av_log(s, AV_LOG_ERROR, "sample rate not set\n");
|
av_log(s, AV_LOG_ERROR, "sample rate not set\n");
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if(!st->codec->block_align)
|
if(!st->codec->block_align)
|
||||||
st->codec->block_align = st->codec->channels *
|
st->codec->block_align = st->codec->channels *
|
||||||
@@ -2816,15 +2833,18 @@ int av_write_header(AVFormatContext *s)
|
|||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
|
if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
|
||||||
av_log(s, AV_LOG_ERROR, "time base not set\n");
|
av_log(s, AV_LOG_ERROR, "time base not set\n");
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){
|
if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){
|
||||||
av_log(s, AV_LOG_ERROR, "dimensions not set\n");
|
av_log(s, AV_LOG_ERROR, "dimensions not set\n");
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
|
if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){
|
||||||
av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
|
av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
|
||||||
return AVERROR(EINVAL);
|
ret = AVERROR(EINVAL);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2841,7 +2861,8 @@ int av_write_header(AVFormatContext *s)
|
|||||||
av_log(s, AV_LOG_ERROR,
|
av_log(s, AV_LOG_ERROR,
|
||||||
"Tag %s/0x%08x incompatible with output codec id '%d'\n",
|
"Tag %s/0x%08x incompatible with output codec id '%d'\n",
|
||||||
tagbuf, st->codec->codec_tag, st->codec->codec_id);
|
tagbuf, st->codec->codec_tag, st->codec->codec_id);
|
||||||
return AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
|
st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
|
||||||
@@ -2854,8 +2875,16 @@ int av_write_header(AVFormatContext *s)
|
|||||||
|
|
||||||
if (!s->priv_data && s->oformat->priv_data_size > 0) {
|
if (!s->priv_data && s->oformat->priv_data_size > 0) {
|
||||||
s->priv_data = av_mallocz(s->oformat->priv_data_size);
|
s->priv_data = av_mallocz(s->oformat->priv_data_size);
|
||||||
if (!s->priv_data)
|
if (!s->priv_data) {
|
||||||
return AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (s->oformat->priv_class) {
|
||||||
|
*(const AVClass**)s->priv_data= s->oformat->priv_class;
|
||||||
|
av_opt_set_defaults(s->priv_data);
|
||||||
|
if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set muxer identification string */
|
/* set muxer identification string */
|
||||||
@@ -2866,7 +2895,7 @@ int av_write_header(AVFormatContext *s)
|
|||||||
if(s->oformat->write_header){
|
if(s->oformat->write_header){
|
||||||
ret = s->oformat->write_header(s);
|
ret = s->oformat->write_header(s);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init PTS generation */
|
/* init PTS generation */
|
||||||
@@ -2885,12 +2914,22 @@ int av_write_header(AVFormatContext *s)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (den != AV_NOPTS_VALUE) {
|
if (den != AV_NOPTS_VALUE) {
|
||||||
if (den <= 0)
|
if (den <= 0) {
|
||||||
return AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
av_frac_init(&st->pts, 0, 0, den);
|
av_frac_init(&st->pts, 0, 0, den);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
av_dict_free(options);
|
||||||
|
*options = tmp;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
av_dict_free(&tmp);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME merge with compute_pkt_fields
|
//FIXME merge with compute_pkt_fields
|
||||||
|
|||||||
Reference in New Issue
Block a user