- Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
authorJuanjo <pulento@users.sourceforge.net>
Tue, 9 Apr 2002 04:52:49 +0000 (04:52 +0000)
committerJuanjo <pulento@users.sourceforge.net>
Tue, 9 Apr 2002 04:52:49 +0000 (04:52 +0000)
AC3 set avcodec_context->channels to the desired number channels, if the
setting is 0 AC3 decoder will set it to the channels found in the
stream.
- Changed ffmpeg to cope with the new "way" of AC3 decoding.
- ASF muxer now uses Tickers for PTS calculations.

Originally committed as revision 393 to svn://svn.ffmpeg.org/ffmpeg/trunk

ffmpeg.c
libav/asf.c
libavcodec/ac3dec.c
libavcodec/utils.c

index da084de..2c18cd8 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -741,10 +741,19 @@ static int av_encode(AVFormatContext **output_files,
                     codec->sample_rate == icodec->sample_rate) {
                     ost->audio_resample = 0;
                 } else {
-                    ost->audio_resample = 1;
-                    ost->resample = audio_resample_init(codec->channels, icodec->channels,
+                    if (codec->channels != icodec->channels &&
+                        icodec->codec_id == CODEC_ID_AC3) {
+                        /* Special case for 5:1 AC3 input */
+                        /* and mono or stereo output      */
+                        ost->audio_resample = 0;
+                        /* Request specific number of channels */
+                        icodec->channels = codec->channels;
+                    } else {
+                        ost->audio_resample = 1; 
+                        ost->resample = audio_resample_init(codec->channels, icodec->channels,
                                                         codec->sample_rate, 
                                                         icodec->sample_rate);
+                    }
                 }
                 ist->decoding_needed = 1;
                 ost->encoding_needed = 1;
@@ -1626,6 +1635,7 @@ void opt_input_file(const char *filename)
         AVCodecContext *enc = &ic->streams[i]->codec;
         switch(enc->codec_type) {
         case CODEC_TYPE_AUDIO:
+            //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
             audio_channels = enc->channels;
             audio_sample_rate = enc->sample_rate;
             break;
@@ -1789,7 +1799,12 @@ void opt_output_file(const char *filename)
             
             audio_enc->bit_rate = audio_bit_rate;
             audio_enc->sample_rate = audio_sample_rate;
-            audio_enc->channels = audio_channels;
+            /* For audio codecs other than AC3 we limit */
+            /* the number of coded channels to stereo   */
+            if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
+                audio_enc->channels = 2;
+            } else
+                audio_enc->channels = audio_channels;
             oc->streams[nb_streams] = st;
             nb_streams++;
         }
index 90fa685..adc2437 100644 (file)
@@ -18,6 +18,7 @@
  */
 #include "avformat.h"
 #include "avi.h"
+#include "tick.h"
 
 #define PACKET_SIZE 3200
 #define PACKET_HEADER_SIZE 12
@@ -26,6 +27,7 @@
 typedef struct {
     int num;
     int seq;
+    Ticker pts_ticker;
     /* use for reading */
     AVPacket pkt;
     int frag_offset;
@@ -283,6 +285,7 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu
 
     /* stream headers */
     for(n=0;n<s->nb_streams;n++) {
+        ASFStream *stream = &asf->streams[n];
         enc = &s->streams[n]->codec;
         asf->streams[n].num = n + 1;
         asf->streams[n].seq = 0;
@@ -292,12 +295,20 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu
             wav_extra_size = 0;
             extra_size = 18 + wav_extra_size;
             extra_size2 = 0;
+            /* Init the ticker */
+            ticker_init(&stream->pts_ticker,
+                        enc->sample_rate,
+                        1000 * enc->frame_size);
             break;
         default:
         case CODEC_TYPE_VIDEO:
             wav_extra_size = 0;
             extra_size = 0x33;
             extra_size2 = 0;
+            /* Init the ticker */
+            ticker_init(&stream->pts_ticker,
+                        enc->frame_rate,
+                        1000 * FRAME_RATE_BASE);
             break;
         }
 
@@ -543,26 +554,27 @@ static int asf_write_packet(AVFormatContext *s, int stream_index,
                             UINT8 *buf, int size, int force_pts)
 {
     ASFContext *asf = s->priv_data;
+    ASFStream *stream;
     int timestamp;
     INT64 duration;
     AVCodecContext *codec;
 
     codec = &s->streams[stream_index]->codec;
+    stream = &asf->streams[stream_index];
+    
     if (codec->codec_type == CODEC_TYPE_AUDIO) {
-        timestamp = (int)((float)codec->frame_number * codec->frame_size * 1000.0 / 
-                          codec->sample_rate);
+        timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
         duration = (codec->frame_number * codec->frame_size * INT64_C(10000000)) / 
             codec->sample_rate;
     } else {
-        timestamp = (int)((float)codec->frame_number * 1000.0 * FRAME_RATE_BASE / 
-                          codec->frame_rate);
+        timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
         duration = codec->frame_number * 
             ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate);
     }
     if (duration > asf->duration)
         asf->duration = duration;
     
-    put_frame(s, &asf->streams[stream_index], (int)timestamp, buf, size);
+    put_frame(s, stream, timestamp, buf, size);
     return 0;
 }
     
index c0d801d..eade4fb 100644 (file)
@@ -108,13 +108,16 @@ static int ac3_decode_frame(AVCodecContext *avctx,
                     /* update codec info */
                     avctx->sample_rate = sample_rate;
                     s->channels = ac3_channels[s->flags & 7];
-                   if (s->flags & AC3_LFE)
-                       s->channels++;
-                   if (s->channels < avctx->channels) {
-                       fprintf(stderr, "Source channels are less than specified: output to %d channels..\n", s->channels);
-                       avctx->channels = s->channels;
-                   }
-                    avctx->bit_rate = bit_rate;
+                    if (s->flags & AC3_LFE)
+                                   s->channels++;
+                               if (avctx->channels == 0)
+                                   /* No specific number of channel requested */
+                                   avctx->channels = s->channels;
+                               else if (s->channels < avctx->channels) {
+                                   fprintf(stderr, "libav: AC3 Source channels are less than specified: output to %d channels..\n", s->channels);
+                                   avctx->channels = s->channels;
+                           }
+                           avctx->bit_rate = bit_rate;
                 }
             }
         } else if (len < s->frame_size) {
@@ -127,15 +130,13 @@ static int ac3_decode_frame(AVCodecContext *avctx,
             s->inbuf_ptr += len;
             buf_size -= len;
         } else {
-#if 0
+            flags = s->flags;
             if (avctx->channels == 1)
                 flags = AC3_MONO;
-            else
+            else if (avctx->channels == 2)
                 flags = AC3_STEREO;
-#else
-           flags = s->flags;
-#endif
-            flags |= AC3_ADJUST_LEVEL;
+            else
+                flags |= AC3_ADJUST_LEVEL;
             level = 1;
             if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) {
             fail:
@@ -146,7 +147,7 @@ static int ac3_decode_frame(AVCodecContext *avctx,
             for (i = 0; i < 6; i++) {
                 if (ac3_block (&s->state))
                     goto fail;
-               float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
+                float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
             }
             s->inbuf_ptr = s->inbuf;
             s->frame_size = 0;
index 815d215..e749268 100644 (file)
@@ -219,6 +219,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
     const char *codec_name;
     AVCodec *p;
     char buf1[32];
+    char *channels_str=NULL;
     int bitrate;
 
     if (encode)
@@ -269,12 +270,27 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
         snprintf(buf, buf_size,
                  "Audio: %s",
                  codec_name);
+        switch (enc->channels) {
+            case 1:
+                channels_str = "mono";
+                break;
+            case 2:
+                channels_str = "stereo";
+                break;
+            case 6:
+                channels_str = "5:1";
+                break;
+            default:
+                sprintf(channels_str, "%d channels", enc->channels);
+                break;
+        }
         if (enc->sample_rate) {
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
                      ", %d Hz, %s",
                      enc->sample_rate,
-                     enc->channels == 2 ? "stereo" : "mono");
+                     channels_str);
         }
+        
         /* for PCM codecs, compute bitrate directly */
         switch(enc->codec_id) {
         case CODEC_ID_PCM_S16LE: