[FFmpeg-devel] Fix FFM-based audio streaming from FFmpeg to FFserver

Michael Niedermayer michaelni
Mon Mar 15 23:59:21 CET 2010


On Mon, Mar 15, 2010 at 06:42:06PM -0400, Ronald S. Bultje wrote:
> Hi,
> 
> see attached. Currently (SVN HEAD), video works but audio is badly
> distorted. A quick look reveals that this is b/c we set the sample_fmt
> to 0 (=U8) in the FFM-descriptor that FFmpeg reads from FFserver to
> see what formats to stream in. While removing the memset(ctx, 0); from
> ffserver.c, I found that pix_fmt/sample_fmt were now no longer filled
> in with random values, but are always unset, leading to problems later
> on in ac_encode(). The rest of the patch therefore fixes the
> pix_fmt/sample_fmt setting when reading a config from FFserver, and
> also fixes a bug when copying codeccontexts. I'm suspecting that the
> reason that video encoding worked is purely coincidental, e.g. yuv420p
> being pix_fmt=0 and most encoders accepting that.
> 
> Some of this stuff could probably be cleaned up (e.g. splitting the
> pix_fmt/sample_fmt setting into a new function), let me know if you
> want that.
> 
> With this patch, streaming works again (both video + audio).
> 
> Also, this bug reveals a deeper bug in that setting pix_fmt /
> sample_fmt to random values doesn't error out, we just generate random
> garbage. Maybe avcodec_open() should check the filled-in values?
> 
> Ronald

>  ffmpeg.c   |   47 +++++++++++++++++++++++++++++++++++++++++++----
>  ffserver.c |   12 ++----------
>  2 files changed, 45 insertions(+), 14 deletions(-)
> 5cc02a5af63af232a65e4b463729310e8e088659  fix-ffserver-ffm-streaming.patch
> Index: ffmpeg.c
> ===================================================================
> --- ffmpeg.c	(revision 22550)
> +++ ffmpeg.c	(working copy)
> @@ -488,6 +488,7 @@
>      s->nb_streams = ic->nb_streams;
>      for(i=0;i<ic->nb_streams;i++) {
>          AVStream *st;
> +        AVCodec *codec;
>  
>          // FIXME: a more elegant solution is needed
>          st = av_mallocz(sizeof(AVStream));
> @@ -498,12 +499,50 @@
>              av_exit(1);
>          }
>          memcpy(st->codec, ic->streams[i]->codec, sizeof(AVCodecContext));
> +        if (st->codec->rc_eq) {
> +            st->codec->rc_eq = av_strdup(st->codec->rc_eq);
> +            if (!st->codec->rc_eq)
> +                return AVERROR(ENOMEM);
> +        }
> +        if (st->codec->extradata_size) {
> +            st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
> +            if (!st->codec->extradata)
> +                return AVERROR(ENOMEM);
> +            memcpy(st->codec->extradata, ic->streams[i]->codec->extradata,
> +                   st->codec->extradata_size);
> +        }
>          s->streams[i] = st;
>  
> -        if (st->codec->codec_type == CODEC_TYPE_AUDIO && audio_stream_copy)
> -            st->stream_copy = 1;
> -        else if (st->codec->codec_type == CODEC_TYPE_VIDEO && video_stream_copy)
> -            st->stream_copy = 1;
> +        codec = avcodec_find_encoder(st->codec->codec_id);
> +        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
> +            if (audio_stream_copy) {
> +                st->stream_copy = 1;
> +            } else {
> +                if(codec && codec->sample_fmts){
> +                    const enum SampleFormat *p= codec->sample_fmts;
> +                    for(; *p!=-1; p++){
> +                        if(*p == st->codec->sample_fmt)
> +                            break;
> +                    }
> +                    if(*p == -1)
> +                        st->codec->sample_fmt = codec->sample_fmts[0];
> +                }
> +            }
> +        } else if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
> +            if (video_stream_copy) {
> +                st->stream_copy = 1;
> +            } else {
> +                if(codec && codec->pix_fmts){
> +                    const enum PixelFormat *p= codec->pix_fmts;
> +                    for(; *p!=-1; p++){
> +                        if(*p == st->codec->pix_fmt)
> +                            break;
> +                    }
> +                    if(*p == -1)
> +                        st->codec->pix_fmt = codec->pix_fmts[0];
> +                }
> +             }
> +        }

code duplication i suspect
also the AVCodecContext cloning likely should be in a function of its own

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100315/efe21c2a/attachment.pgp>



More information about the ffmpeg-devel mailing list