This is a generic solution that will not reqiore modifications when new options are added. This also fixes problem with current implementation when qmin or qmax=-1. Only 8 bits was sent and read back as 255.
Fixes #1275 Fixes #1461 Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com> --- libavformat/ffmdec.c | 20 +++++++++++++++ libavformat/ffmenc.c | 70 +++++++++++++++------------------------------------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index bba3b36..a1b9e9b 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -380,6 +380,26 @@ static int ffm2_read_header(AVFormatContext *s) av_set_options_string(codec->priv_data, buffer, "=", ","); av_freep(&buffer); break; + case MKBETAG('S', '2', 'V', 'I'): + if (f_stvi++) { + ret = AVERROR(EINVAL); + goto fail; + } + buffer = av_malloc(size); + avio_get_str(pb, INT_MAX, buffer, size); + av_set_options_string(codec, buffer, "=", ","); + av_freep(&buffer); + break; + case MKBETAG('S', '2', 'A', 'U'): + if (f_stau++) { + ret = AVERROR(EINVAL); + goto fail; + } + buffer = av_malloc(size); + avio_get_str(pb, INT_MAX, buffer, size); + av_set_options_string(codec, buffer, "=", ","); + av_freep(&buffer); + break; } avio_seek(pb, next, SEEK_SET); } diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c index f307f8f..7c5debb 100644 --- a/libavformat/ffmenc.c +++ b/libavformat/ffmenc.c @@ -112,6 +112,22 @@ static int ffm_write_header_codec_private_ctx(AVIOContext *pb, void *priv_data, return 0; } +static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsigned tag) +{ + AVIOContext *tmp; + char *buf = NULL; + + if (avio_open_dyn_buf(&tmp) < 0) + return AVERROR(ENOMEM); + /* Second parameter could be AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO/VIDEO_PARAM, + but some required options don't have this flags. Skipping defaults should be enough. */ + av_opt_serialize(ctx, 0, 1, &buf, '=', ','); + avio_put_str(tmp, buf); + write_header_chunk(pb, tmp, tag); + av_free(buf); + return 0; +} + static int ffm_write_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; @@ -172,59 +188,13 @@ static int ffm_write_header(AVFormatContext *s) /* specific info */ switch(codec->codec_type) { case AVMEDIA_TYPE_VIDEO: - avio_wb32(pb, codec->time_base.num); - avio_wb32(pb, codec->time_base.den); - avio_wb16(pb, codec->width); - avio_wb16(pb, codec->height); - avio_wb16(pb, codec->gop_size); - avio_wb32(pb, codec->pix_fmt); - avio_w8(pb, codec->qmin); - avio_w8(pb, codec->qmax); - avio_w8(pb, codec->max_qdiff); - avio_wb16(pb, (int) (codec->qcompress * 10000.0)); - avio_wb16(pb, (int) (codec->qblur * 10000.0)); - avio_wb32(pb, codec->bit_rate_tolerance); - avio_put_str(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp"); - avio_wb32(pb, codec->rc_max_rate); - avio_wb32(pb, codec->rc_min_rate); - avio_wb32(pb, codec->rc_buffer_size); - avio_wb64(pb, av_double2int(codec->i_quant_factor)); - avio_wb64(pb, av_double2int(codec->b_quant_factor)); - avio_wb64(pb, av_double2int(codec->i_quant_offset)); - avio_wb64(pb, av_double2int(codec->b_quant_offset)); - avio_wb32(pb, codec->dct_algo); - avio_wb32(pb, codec->strict_std_compliance); - avio_wb32(pb, codec->max_b_frames); - avio_wb32(pb, codec->mpeg_quant); - avio_wb32(pb, codec->intra_dc_precision); - avio_wb32(pb, codec->me_method); - avio_wb32(pb, codec->mb_decision); - avio_wb32(pb, codec->nsse_weight); - avio_wb32(pb, codec->frame_skip_cmp); - avio_wb64(pb, av_double2int(codec->rc_buffer_aggressivity)); - avio_wb32(pb, codec->codec_tag); - avio_w8(pb, codec->thread_count); - avio_wb32(pb, codec->coder_type); - avio_wb32(pb, codec->me_cmp); - avio_wb32(pb, codec->me_subpel_quality); - avio_wb32(pb, codec->me_range); - avio_wb32(pb, codec->keyint_min); - avio_wb32(pb, codec->scenechange_threshold); - avio_wb32(pb, codec->b_frame_strategy); - avio_wb64(pb, av_double2int(codec->qcompress)); - avio_wb64(pb, av_double2int(codec->qblur)); - avio_wb32(pb, codec->max_qdiff); - avio_wb32(pb, codec->refs); - write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'V', 'I')); - if ((ret = ffm_write_header_codec_private_ctx(s->pb, codec->priv_data, AV_OPT_FLAG_VIDEO_PARAM)) < 0) + if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'V', 'I'))) < 0 || + (ret = ffm_write_header_codec_private_ctx(s->pb, codec->priv_data, AV_OPT_FLAG_VIDEO_PARAM)) < 0) return ret; break; case AVMEDIA_TYPE_AUDIO: - avio_wb32(pb, codec->sample_rate); - avio_wl16(pb, codec->channels); - avio_wl16(pb, codec->frame_size); - write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'A', 'U')); - if ((ret = ffm_write_header_codec_private_ctx(s->pb, codec->priv_data, AV_OPT_FLAG_AUDIO_PARAM)) < 0) + if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'A', 'U'))) < 0 || + (ret = ffm_write_header_codec_private_ctx(s->pb, codec->priv_data, AV_OPT_FLAG_AUDIO_PARAM)) < 0) return ret; break; default: -- 1.9.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel