[FFmpeg-devel] [PATCH 9/9] lavf/ffm: use AVOption API to store/restore stream properties
Lukasz Marek
lukasz.m.luki2 at gmail.com
Tue Nov 11 08:31:31 CET 2014
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.luki2 at 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
More information about the ffmpeg-devel
mailing list