On 06.11.2014 01:32, Michael Niedermayer wrote:
On Thu, Nov 06, 2014 at 12:59:45AM +0100, Lukasz Marek wrote:
new_output_stream creates a codec context with arbitraty picked codec.
Later data is updated, but priv_data are left alone.
There is a bit chance there is a mismatch between codecs.
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
ffmpeg_opt.c | 16 ++++++++++++++++
libavformat/ffmdec.c | 6 ++++--
2 files changed, 20 insertions(+), 2 deletions(-)
with this fate-lavf-ffm crashes
==10836== Invalid write of size 8
==10836== at 0x935442: decode_init (mpegaudiodec_template.c:419)
==10836== by 0xA69226: avcodec_open2 (utils.c:1614)
==10836== by 0x64CC5F: avformat_find_stream_info (utils.c:3053)
==10836== by 0x41C2D7: open_input_file (ffmpeg_opt.c:886)
==10836== by 0x42427A: open_files (ffmpeg_opt.c:2699)
==10836== by 0x4243F8: ffmpeg_parse_options (ffmpeg_opt.c:2736)
==10836== by 0x43762E: main (ffmpeg.c:3861)
==10836== Address 0x10f072b0 is not stack'd, malloc'd or (recently) free'd
==10836==
==10836== Invalid write of size 8
==10836== at 0xDC67D0: avpriv_float_dsp_init (float_dsp.c:120)
==10836== by 0x93546B: decode_init (mpegaudiodec_template.c:421)
==10836== by 0xA69226: avcodec_open2 (utils.c:1614)
==10836== by 0x64CC5F: avformat_find_stream_info (utils.c:3053)
==10836== by 0x41C2D7: open_input_file (ffmpeg_opt.c:886)
==10836== by 0x42427A: open_files (ffmpeg_opt.c:2699)
==10836== by 0x4243F8: ffmpeg_parse_options (ffmpeg_opt.c:2736)
==10836== by 0x43762E: main (ffmpeg.c:3861)
==10836== Address 0x10f072e8 is not stack'd, malloc'd or (recently) free'd
and pages more
I tried to debug it, but there is too much code to read to handle one
very specific case and I'm not sure there is other, better solution.
Probably, I haven't check, clear solution would be to clear priv_data in
read_ffserver_streams right after copy_context, and set it to NULL, but
I will need private data soon to support it in ffserver.
Solution is ugly, but I think I will not propose anything better.
>From abb6a1fb9c1da226b6bfe179ded076365b969cad Mon Sep 17 00:00:00 2001
From: Lukasz Marek <lukasz.m.lu...@gmail.com>
Date: Thu, 6 Nov 2014 00:55:10 +0100
Subject: [PATCH] ffmpeg_opt: set correct priv_data for feed stream
new_output_stream creates a codec context with arbitraty picked codec.
Later data is updated, but priv_data are left alone.
There is a bit chance there is a mismatch between codecs.
Signed-off-by: Lukasz Marek <lukasz.m.lu...@gmail.com>
---
ffmpeg_opt.c | 20 +++++++++++++++++++-
libavformat/ffm.h | 3 +++
libavformat/ffmdec.c | 28 ++++++++++++++++++++++++----
3 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
index 1757dcc..d020c13 100644
--- a/ffmpeg_opt.c
+++ b/ffmpeg_opt.c
@@ -1614,9 +1614,11 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
{
int i, err;
AVFormatContext *ic = avformat_alloc_context();
+ AVDictionary *opts = NULL;
ic->interrupt_callback = int_cb;
- err = avformat_open_input(&ic, filename, NULL, NULL);
+ av_dict_set_int(&opts, "need_stream", 1500100900, 0);
+ err = avformat_open_input(&ic, filename, NULL, &opts);
if (err < 0)
return err;
/* copy stream format */
@@ -1643,12 +1645,28 @@ static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const ch
memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
st->codec= avctx;
avcodec_copy_context(st->codec, ic->streams[i]->codec);
+ if (st->codec->priv_data) {
+ av_opt_free(st->codec->priv_data);
+ av_free(st->codec->priv_data);
+ }
+ st->codec->priv_data = ic->streams[i]->codec->priv_data;
+ ic->streams[i]->codec->priv_data = NULL;
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_free(ost->enc_ctx->priv_data);
+ }
+ ost->enc_ctx->priv_data = av_mallocz(codec->priv_data_size);
+ if (ost->enc_ctx->priv_data) {
+ *(const AVClass**)ost->enc_ctx->priv_data = codec->priv_class;
+ av_opt_copy(ost->enc_ctx->priv_data, st->codec->priv_data);
+ } else
+ err = AVERROR(ENOMEM);
}
avformat_close_input(&ic);
diff --git a/libavformat/ffm.h b/libavformat/ffm.h
index b392b8d..0ab92f1 100644
--- a/libavformat/ffm.h
+++ b/libavformat/ffm.h
@@ -43,6 +43,9 @@ enum {
typedef struct FFMContext {
/* only reading mode */
+ AVClass *avclass;
+ int need_streams;
+
int64_t write_index, file_size;
int read_state;
uint8_t header[FRAME_HEADER_SIZE+4];
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 448762b..e34431c 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -23,6 +23,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
#include "ffm.h"
@@ -237,6 +238,7 @@ static int ffm2_read_header(AVFormatContext *s)
AVIOContext *pb = s->pb;
AVCodecContext *codec;
int ret;
+ enum AVCodecID codec_id;
ffm->packet_size = avio_rb32(pb);
if (ffm->packet_size != FFM_PACKET_SIZE) {
@@ -271,7 +273,8 @@ static int ffm2_read_header(AVFormatContext *s)
avio_rb32(pb); /* total bitrate */
break;
case MKBETAG('C', 'O', 'M', 'M'):
- st = avformat_new_stream(s, NULL);
+ codec_id = avio_rb32(pb);
+ st = avformat_new_stream(s, ffm->need_streams == 1500100900 ? avcodec_find_encoder(codec_id) : NULL);
if (!st) {
ret = AVERROR(ENOMEM);
goto fail;
@@ -281,7 +284,7 @@ static int ffm2_read_header(AVFormatContext *s)
codec = st->codec;
/* generic info */
- codec->codec_id = avio_rb32(pb);
+ codec->codec_id = codec_id;
codec->codec_type = avio_r8(pb);
codec->bit_rate = avio_rb32(pb);
codec->flags = avio_rb32(pb);
@@ -378,6 +381,7 @@ static int ffm_read_header(AVFormatContext *s)
AVCodecContext *codec;
int i, nb_streams;
uint32_t tag;
+ enum AVCodecID codec_id;
/* header */
tag = avio_rl32(pb);
@@ -404,7 +408,8 @@ static int ffm_read_header(AVFormatContext *s)
for(i=0;i<nb_streams;i++) {
char rc_eq_buf[128];
- st = avformat_new_stream(s, NULL);
+ codec_id = avio_rb32(pb);
+ st = avformat_new_stream(s, ffm->need_streams == 1500100900 ? avcodec_find_encoder(codec_id) : NULL);
if (!st)
goto fail;
@@ -412,7 +417,7 @@ static int ffm_read_header(AVFormatContext *s)
codec = st->codec;
/* generic info */
- codec->codec_id = avio_rb32(pb);
+ codec->codec_id = codec_id;
codec->codec_type = avio_r8(pb); /* codec_type */
codec->bit_rate = avio_rb32(pb);
codec->flags = avio_rb32(pb);
@@ -631,8 +636,23 @@ static int ffm_probe(AVProbeData *p)
return 0;
}
+#define OFFSET(x) offsetof(FFMContext, x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "need_stream", "FFServer hack option, not to used by user", OFFSET(need_streams), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, ENC },
+ { NULL },
+};
+
+static const AVClass ffm_demuxer_class = {
+ .class_name = "FFM demuxer",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = options,
+};
+
AVInputFormat ff_ffm_demuxer = {
.name = "ffm",
+ .priv_class = &ffm_demuxer_class,
.long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
.priv_data_size = sizeof(FFMContext),
.read_probe = ffm_probe,
--
1.9.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel