On 11.11.2014 18:03, Michael Niedermayer wrote:
On Tue, Nov 11, 2014 at 04:41:17PM +0100, Lukasz Marek wrote:
On 11.11.2014 08:31, Lukasz Marek wrote:
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
ffmpeg_opt.c | 48 ++++++++++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 16 deletions(-)
Thanks for the hint with opt_target()
It is indeed simpler and cleaner.
Updated patch attached.
Following patch dropped:
[PATCH 4/9] ffmpeg_opt: allow to force codec in new_output_stream
ffmpeg_opt.c | 50 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 15 deletions(-)
99c8226c4dc0258ebe2a4e223fae49c87c8f8d33
0001-ffmpeg_opt-use-codec-private-context-in-ffserver-str.patch
From 042e92b4f4b0d25e3d133c5dac92e483c425becf Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Tue, 11 Nov 2014 05:19:27 +0100
Subject: [PATCH] ffmpeg_opt: use codec private context in ffserver streams
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
ffmpeg_opt.c | 50 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 15 deletions(-)
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 77ef0c4..ed84d73 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1617,6 +1617,35 @@ static int copy_chapters(InputFile *ifile, OutputFile
*ofile, int copy_metadata)
return 0;
}
+static int ffserver_streams_copy_context(AVCodecContext *dest, const
AVCodecContext *src)
+{
+ int ret;
+ if ((ret = avcodec_copy_context(dest, src)) < 0)
+ return ret;
+ if (src->priv_data) {
+ if (dest->priv_data && *(const AVClass**)src->priv_data != *(const
AVClass**)dest->priv_data) {
+ av_opt_free(dest->priv_data);
that assumes that theres a AVClass as first element of priv_data,
that does not have to be so.
AVCodec.priv_class has to be checked at least
+ av_freep(&dest->priv_data);
+ }
+ if (!dest->priv_data) {
+ if (!src->codec) {
+ av_log(NULL, AV_LOG_WARNING, "Cannot copy codec private options.
They won't get applied.\n");
+ return 0;
+ }
+ dest->priv_data = av_mallocz(src->codec->priv_data_size);
+ if (!dest->priv_data)
+ return AVERROR(ENOMEM);
+ *(const AVClass**)dest->priv_data = src->codec->priv_class;
priv_data_size could be 0
except these the code is ugly* but probably ok
New version seems to be cleaner, hopely ok.
I changed according to your solution to keep recommended configuration.
Not sure it is possible case, but setting encoder priv context in
decoder may be danger if someone really used it as decoder with
mismatched private data.
>From b4533ffaa62a94e5ca8d350bd76bd32ea44986f2 Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Tue, 11 Nov 2014 05:19:27 +0100
Subject: [PATCH 2/2] ffmpeg_opt: use codec private context in ffserver streams
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
ffmpeg_opt.c | 48 +++++++++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 77ef0c4..cdf8d58 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1617,6 +1617,31 @@ static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
return 0;
}
+static int ffserver_streams_copy_context(AVCodecContext *dest, const AVCodecContext *src,
+ const char *configuration)
+{
+ int ret;
+ if ((ret = avcodec_copy_context(dest, src)) < 0)
+ return ret;
+ dest->codec = avcodec_find_encoder(src->codec_id);
+ if (!dest->codec)
+ return AVERROR(EINVAL);
+ if (!dest->codec->priv_class || !dest->codec->priv_data_size)
+ return 0;
+ if (!dest->priv_data) {
+ dest->priv_data = av_mallocz(dest->codec->priv_data_size);
+ if (!dest->priv_data)
+ return AVERROR(ENOMEM);
+ *(const AVClass**)dest->priv_data = dest->codec->priv_class;
+ }
+ av_opt_set_defaults(dest->priv_data);
+ if (av_set_options_string(dest->priv_data, configuration, "=", ",") < 0) {
+ av_log(dest, AV_LOG_WARNING, "Cannot copy private codec options. Using defaults.\n");
+ av_opt_set_defaults(dest->priv_data);
+ }
+ return 0;
+}
+
static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
{
int i, err;
@@ -1631,35 +1656,28 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
AVStream *st;
OutputStream *ost;
AVCodec *codec;
- AVCodecContext *avctx;
codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
if (!codec) {
av_log(s, AV_LOG_ERROR, "no encoder found for codec id %i\n", ic->streams[i]->codec->codec_id);
return AVERROR(EINVAL);
}
+ if (codec->type == AVMEDIA_TYPE_AUDIO)
+ opt_audio_codec(o, "c:a", codec->name);
+ else if (codec->type == AVMEDIA_TYPE_VIDEO)
+ opt_video_codec(o, "c:v", codec->name);
ost = new_output_stream(o, s, codec->type, -1);
st = ost->st;
- avctx = st->codec;
- ost->enc = codec;
- // FIXME: a more elegant solution is needed
- memcpy(st, ic->streams[i], sizeof(AVStream));
- st->cur_dts = 0;
- st->info = av_malloc(sizeof(*st->info));
- memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
- st->codec= avctx;
- avcodec_copy_context(st->codec, ic->streams[i]->codec);
+ ffserver_streams_copy_context(st->codec, ic->streams[i]->codec,
+ ic->streams[i]->recommended_encoder_configuration);
if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
choose_sample_fmt(st, codec);
else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
choose_pixel_fmt(st, st->codec, codec, st->codec->pix_fmt);
- avcodec_copy_context(ost->enc_ctx, st->codec);
- if (ost->enc_ctx->priv_data) {
- av_opt_free(ost->enc_ctx->priv_data);
- av_freep(&ost->enc_ctx->priv_data);
- }
+ ffserver_streams_copy_context(ost->enc_ctx, st->codec,
+ ic->streams[i]->recommended_encoder_configuration);
}
avformat_close_input(&ic);
--
1.9.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel