On 12.11.2014 03:19, Michael Niedermayer wrote:
On Wed, Nov 12, 2014 at 12:02:07AM +0100, Lukasz Marek wrote:
On 11.11.2014 08:31, Lukasz Marek wrote:
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(-)
Updated version attached.
not related to this patch specifically but please test
fate-opt under valgrind
it seems one of the patches adds a memleak
==16696== 4 bytes in 1 blocks are definitely lost in loss record 1 of 6
==16696== at 0x4C2A6C5: memalign (vg_replace_malloc.c:727)
==16696== by 0x4C2A760: posix_memalign (vg_replace_malloc.c:876)
==16696== by 0x40FC2D: av_malloc (mem.c:95)
==16696== by 0x402022: set_string_binary (opt.c:142)
==16696== by 0x40617F: av_opt_set_defaults2 (opt.c:1235)
==16696== by 0x405ED1: av_opt_set_defaults (opt.c:1175)
==16696== by 0x40809C: main (opt.c:1986)
This is leak in the test itself :P
Fix was trivial so I pushed it directly.
I uploaded updated patch, that removes necessity of the patch I dropped
"[PATCH] lavc/options: set all codec options to defaults"
Note: it extends opt serialize with new flag, so before a sumbit I will
move that chunk to commit that introduce it.
I pushed to github current patches too.
>From 5a9755466f56569e222c8ff6955b5b8e56c268a2 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Tue, 11 Nov 2014 08:20:02 +0100
Subject: [PATCH] lavf/ffm: use AVOption API to store/restore stream properties
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 | 29 ++++++++++++++++
libavformat/ffmenc.c | 96 +++++++++++++++++++++++++---------------------------
libavutil/opt.c | 6 +++-
libavutil/opt.h | 1 +
4 files changed, 81 insertions(+), 51 deletions(-)
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 1c848b9..f66f8aa 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -240,6 +240,7 @@ static int ffm2_read_header(AVFormatContext *s)
int ret;
int f_main = 0, f_cprv, f_stvi, f_stau;
AVCodec *enc;
+ char *buffer;
ffm->packet_size = avio_rb32(pb);
if (ffm->packet_size != FFM_PACKET_SIZE) {
@@ -375,6 +376,34 @@ static int ffm2_read_header(AVFormatContext *s)
avio_get_str(pb, size, st->recommended_encoder_configuration, size + 1);
}
break;
+ case MKBETAG('S', '2', 'V', 'I'):
+ if (f_stvi++) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ buffer = av_malloc(size);
+ if (!buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ 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);
+ if (!buffer) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ 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 e0885e7..b717813 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -120,6 +120,48 @@ static int ffm_write_header_codec_private_ctx(AVIOContext *pb, AVCodecContext *c
return 0;
}
+static int ffm_write_header_codec_ctx(AVIOContext *pb, AVCodecContext *ctx, unsigned tag, int type)
+{
+ AVIOContext *tmp;
+ char *buf = NULL;
+ uint8_t *p = NULL;
+ int ret, need_coma = 0;
+
+#define SKIP_DEFAULTS AV_OPT_SERIALIZE_SKIP_DEFAULTS
+#define OPT_FLAGS_EXACT AV_OPT_SERIALIZE_OPT_FLAGS_EXACT
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+ if (avio_open_dyn_buf(&tmp) < 0)
+ return AVERROR(ENOMEM);
+ if ((ret = av_opt_serialize(ctx, ENC | type, SKIP_DEFAULTS, &buf, '=', ',')) < 0)
+ goto fail;
+ if (buf && strlen(buf)) {
+ avio_write(tmp, buf, strlen(buf));
+ av_free(buf);
+ need_coma = 1;
+ }
+ if ((ret = av_opt_serialize(ctx, 0, SKIP_DEFAULTS | OPT_FLAGS_EXACT, &buf, '=', ',')) < 0)
+ goto fail;
+ if (buf && strlen(buf)) {
+ if (need_coma)
+ avio_w8(tmp, ',');
+ avio_write(tmp, buf, strlen(buf));
+ av_free(buf);
+ }
+ avio_w8(tmp, 0);
+ write_header_chunk(pb, tmp, tag);
+ return 0;
+ fail:
+ av_free(buf);
+ avio_close_dyn_buf(tmp, &p);
+ av_free(p);
+ return ret;
+
+#undef SKIP_DEFAULTS
+#undef OPT_FLAGS_EXACT
+#undef ENC
+}
+
static int ffm_write_header(AVFormatContext *s)
{
FFMContext *ffm = s->priv_data;
@@ -180,59 +222,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, AV_OPT_FLAG_VIDEO_PARAM)) < 0)
+ if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'V', 'I'), AV_OPT_FLAG_VIDEO_PARAM)) < 0 ||
+ (ret = ffm_write_header_codec_private_ctx(s->pb, codec, 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, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
+ if ((ret = ffm_write_header_codec_ctx(s->pb, codec, MKBETAG('S', '2', 'A', 'U'), AV_OPT_FLAG_AUDIO_PARAM)) < 0 ||
+ (ret = ffm_write_header_codec_private_ctx(s->pb, codec, AV_OPT_FLAG_AUDIO_PARAM)) < 0)
return ret;
break;
default:
diff --git a/libavutil/opt.c b/libavutil/opt.c
index f70ecae..0546a37 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -1851,7 +1851,11 @@ int av_opt_serialize(void *obj, int opt_flags, int flags, char **buffer,
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
while (o = av_opt_next(obj, o)) {
- if (o->flags & opt_flags != opt_flags || o->type == AV_OPT_TYPE_CONST)
+ if (o->type == AV_OPT_TYPE_CONST)
+ continue;
+ if ((flags & AV_OPT_SERIALIZE_OPT_FLAGS_EXACT) && o->flags != opt_flags)
+ continue;
+ else if (((o->flags & opt_flags) != opt_flags))
continue;
if (flags & AV_OPT_SERIALIZE_SKIP_DEFAULTS && av_opt_is_set_to_default(obj, o) > 0)
continue;
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 482410d..7338e78 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -871,6 +871,7 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla
#define AV_OPT_SERIALIZE_SKIP_DEFAULTS 0x00000001 ///< Serialize options that are not set to default values only.
+#define AV_OPT_SERIALIZE_OPT_FLAGS_EXACT 0x00000002 ///< Serialize options that exactly match opt_flags only.
/**
* Serialize object's options.
--
1.9.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel