From d9521cb1197c8b5bd1611ec0edfdf58b7a56e30e Mon Sep 17 00:00:00 2001
From: "Ronald S. Bultje" <rsbultje@gmail.com>
Date: Wed, 31 Mar 2010 21:02:34 +0000
Subject: [PATCH] Fix FFM-based streaming from ffmpeg to ffserver. The basic
 problem is that we'd memset() the codec context to zero, thereby setting
 audio input to U8 and video to YUV420P. For most video encoders, that
 actually works, but for most audio codecs, it doesn't. This patch changes
 defaults to those set by avcodec_context_get_defaults() and have ffmpeg
 figure out the optimal encoding format itself if not set explicitely (as it
 does for the non-ffserver-cases also).

Originally committed as revision 22751 to svn://svn.ffmpeg.org/ffmpeg/trunk
---
 ffmpeg.c   | 19 ++++++++++++++-----
 ffserver.c | 12 ++----------
 2 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index c6058c7afa6..8e603d51939 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -515,6 +515,7 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename)
     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));
@@ -524,13 +525,21 @@ static int read_ffserver_streams(AVFormatContext *s, const char *filename)
             print_error(filename, AVERROR(ENOMEM));
             av_exit(1);
         }
-        memcpy(st->codec, ic->streams[i]->codec, sizeof(AVCodecContext));
+        avcodec_copy_context(st->codec, ic->streams[i]->codec);
         s->streams[i] = st;
 
-        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_stream_copy)
-            st->stream_copy = 1;
-        else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_stream_copy)
-            st->stream_copy = 1;
+        codec = avcodec_find_encoder(st->codec->codec_id);
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            if (audio_stream_copy) {
+                st->stream_copy = 1;
+            } else
+                choose_sample_fmt(st, codec);
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            if (video_stream_copy) {
+                st->stream_copy = 1;
+            } else
+                choose_pixel_fmt(st, codec);
+        }
 
         if(!st->codec->thread_count)
             st->codec->thread_count = 1;
diff --git a/ffserver.c b/ffserver.c
index fad1548c6e3..f68ca11fbb0 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -4039,7 +4039,6 @@ static int parse_ffconfig(const char *filename)
                         filename, line_num);
             } else {
                 FFStream *s;
-                const AVClass *class;
                 stream = av_mallocz(sizeof(FFStream));
                 get_arg(stream->filename, sizeof(stream->filename), &p);
                 q = strrchr(stream->filename, '>');
@@ -4055,15 +4054,8 @@ static int parse_ffconfig(const char *filename)
                 }
 
                 stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
-                /* fetch avclass so AVOption works
-                 * FIXME try to use avcodec_get_context_defaults2
-                 * without changing defaults too much */
-                avcodec_get_context_defaults(&video_enc);
-                class = video_enc.av_class;
-                memset(&audio_enc, 0, sizeof(AVCodecContext));
-                memset(&video_enc, 0, sizeof(AVCodecContext));
-                audio_enc.av_class = class;
-                video_enc.av_class = class;
+                avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO);
+                avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO);
                 audio_id = CODEC_ID_NONE;
                 video_id = CODEC_ID_NONE;
                 if (stream->fmt) {
-- 
GitLab