|
|
|
@ -2733,6 +2733,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6 |
|
|
|
|
/************************************************************/ |
|
|
|
|
/* output media file */ |
|
|
|
|
|
|
|
|
|
#if FF_API_FORMAT_PARAMETERS |
|
|
|
|
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
{ |
|
|
|
|
int ret; |
|
|
|
@ -2755,6 +2756,7 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static int validate_codec_tag(AVFormatContext *s, AVStream *st) |
|
|
|
|
{ |
|
|
|
@ -2789,15 +2791,29 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if FF_API_FORMAT_PARAMETERS |
|
|
|
|
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; |
|
|
|
|
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
|
|
|
|
|
if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) { |
|
|
|
|
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++) { |
|
|
|
@ -2807,7 +2823,8 @@ int av_write_header(AVFormatContext *s) |
|
|
|
|
case AVMEDIA_TYPE_AUDIO: |
|
|
|
|
if(st->codec->sample_rate<=0){ |
|
|
|
|
av_log(s, AV_LOG_ERROR, "sample rate not set\n"); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
ret = AVERROR(EINVAL); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if(!st->codec->block_align) |
|
|
|
|
st->codec->block_align = st->codec->channels * |
|
|
|
@ -2816,15 +2833,18 @@ int av_write_header(AVFormatContext *s) |
|
|
|
|
case AVMEDIA_TYPE_VIDEO: |
|
|
|
|
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"); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
ret = AVERROR(EINVAL); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){ |
|
|
|
|
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)){ |
|
|
|
|
av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n"); |
|
|
|
|
return AVERROR(EINVAL); |
|
|
|
|
ret = AVERROR(EINVAL); |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -2841,7 +2861,8 @@ int av_write_header(AVFormatContext *s) |
|
|
|
|
av_log(s, AV_LOG_ERROR, |
|
|
|
|
"Tag %s/0x%08x incompatible with output codec id '%d'\n", |
|
|
|
|
tagbuf, st->codec->codec_tag, st->codec->codec_id); |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
}else |
|
|
|
|
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) { |
|
|
|
|
s->priv_data = av_mallocz(s->oformat->priv_data_size); |
|
|
|
|
if (!s->priv_data) |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
if (!s->priv_data) { |
|
|
|
|
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 */ |
|
|
|
@ -2866,7 +2895,7 @@ int av_write_header(AVFormatContext *s) |
|
|
|
|
if(s->oformat->write_header){ |
|
|
|
|
ret = s->oformat->write_header(s); |
|
|
|
|
if (ret < 0) |
|
|
|
|
return ret; |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* init PTS generation */ |
|
|
|
@ -2885,12 +2914,22 @@ int av_write_header(AVFormatContext *s) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
if (den != AV_NOPTS_VALUE) { |
|
|
|
|
if (den <= 0) |
|
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
|
if (den <= 0) { |
|
|
|
|
ret = AVERROR_INVALIDDATA; |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
av_frac_init(&st->pts, 0, 0, den); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (options) { |
|
|
|
|
av_dict_free(options); |
|
|
|
|
*options = tmp; |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|
fail: |
|
|
|
|
av_dict_free(&tmp); |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//FIXME merge with compute_pkt_fields
|
|
|
|
|