Browse code

- Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for 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

Juanjo authored on 2002/04/09 13:52:49
Showing 4 changed files
... ...
@@ -741,10 +741,19 @@ static int av_encode(AVFormatContext **output_files,
741 741
                     codec->sample_rate == icodec->sample_rate) {
742 742
                     ost->audio_resample = 0;
743 743
                 } else {
744
-                    ost->audio_resample = 1;
745
-                    ost->resample = audio_resample_init(codec->channels, icodec->channels,
744
+                    if (codec->channels != icodec->channels &&
745
+                        icodec->codec_id == CODEC_ID_AC3) {
746
+                        /* Special case for 5:1 AC3 input */
747
+                        /* and mono or stereo output      */
748
+                        ost->audio_resample = 0;
749
+                        /* Request specific number of channels */
750
+                        icodec->channels = codec->channels;
751
+                    } else {
752
+                        ost->audio_resample = 1; 
753
+                        ost->resample = audio_resample_init(codec->channels, icodec->channels,
746 754
                                                         codec->sample_rate, 
747 755
                                                         icodec->sample_rate);
756
+                    }
748 757
                 }
749 758
                 ist->decoding_needed = 1;
750 759
                 ost->encoding_needed = 1;
... ...
@@ -1626,6 +1635,7 @@ void opt_input_file(const char *filename)
1626 1626
         AVCodecContext *enc = &ic->streams[i]->codec;
1627 1627
         switch(enc->codec_type) {
1628 1628
         case CODEC_TYPE_AUDIO:
1629
+            //fprintf(stderr, "\nInput Audio channels: %d", enc->channels);
1629 1630
             audio_channels = enc->channels;
1630 1631
             audio_sample_rate = enc->sample_rate;
1631 1632
             break;
... ...
@@ -1789,7 +1799,12 @@ void opt_output_file(const char *filename)
1789 1789
             
1790 1790
             audio_enc->bit_rate = audio_bit_rate;
1791 1791
             audio_enc->sample_rate = audio_sample_rate;
1792
-            audio_enc->channels = audio_channels;
1792
+            /* For audio codecs other than AC3 we limit */
1793
+            /* the number of coded channels to stereo   */
1794
+            if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
1795
+                audio_enc->channels = 2;
1796
+            } else
1797
+                audio_enc->channels = audio_channels;
1793 1798
             oc->streams[nb_streams] = st;
1794 1799
             nb_streams++;
1795 1800
         }
... ...
@@ -18,6 +18,7 @@
18 18
  */
19 19
 #include "avformat.h"
20 20
 #include "avi.h"
21
+#include "tick.h"
21 22
 
22 23
 #define PACKET_SIZE 3200
23 24
 #define PACKET_HEADER_SIZE 12
... ...
@@ -26,6 +27,7 @@
26 26
 typedef struct {
27 27
     int num;
28 28
     int seq;
29
+    Ticker pts_ticker;
29 30
     /* use for reading */
30 31
     AVPacket pkt;
31 32
     int frag_offset;
... ...
@@ -283,6 +285,7 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu
283 283
 
284 284
     /* stream headers */
285 285
     for(n=0;n<s->nb_streams;n++) {
286
+        ASFStream *stream = &asf->streams[n];
286 287
         enc = &s->streams[n]->codec;
287 288
         asf->streams[n].num = n + 1;
288 289
         asf->streams[n].seq = 0;
... ...
@@ -292,12 +295,20 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu
292 292
             wav_extra_size = 0;
293 293
             extra_size = 18 + wav_extra_size;
294 294
             extra_size2 = 0;
295
+            /* Init the ticker */
296
+            ticker_init(&stream->pts_ticker,
297
+                        enc->sample_rate,
298
+                        1000 * enc->frame_size);
295 299
             break;
296 300
         default:
297 301
         case CODEC_TYPE_VIDEO:
298 302
             wav_extra_size = 0;
299 303
             extra_size = 0x33;
300 304
             extra_size2 = 0;
305
+            /* Init the ticker */
306
+            ticker_init(&stream->pts_ticker,
307
+                        enc->frame_rate,
308
+                        1000 * FRAME_RATE_BASE);
301 309
             break;
302 310
         }
303 311
 
... ...
@@ -543,26 +554,27 @@ static int asf_write_packet(AVFormatContext *s, int stream_index,
543 543
                             UINT8 *buf, int size, int force_pts)
544 544
 {
545 545
     ASFContext *asf = s->priv_data;
546
+    ASFStream *stream;
546 547
     int timestamp;
547 548
     INT64 duration;
548 549
     AVCodecContext *codec;
549 550
 
550 551
     codec = &s->streams[stream_index]->codec;
552
+    stream = &asf->streams[stream_index];
553
+    
551 554
     if (codec->codec_type == CODEC_TYPE_AUDIO) {
552
-        timestamp = (int)((float)codec->frame_number * codec->frame_size * 1000.0 / 
553
-                          codec->sample_rate);
555
+        timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
554 556
         duration = (codec->frame_number * codec->frame_size * INT64_C(10000000)) / 
555 557
             codec->sample_rate;
556 558
     } else {
557
-        timestamp = (int)((float)codec->frame_number * 1000.0 * FRAME_RATE_BASE / 
558
-                          codec->frame_rate);
559
+        timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
559 560
         duration = codec->frame_number * 
560 561
             ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate);
561 562
     }
562 563
     if (duration > asf->duration)
563 564
         asf->duration = duration;
564 565
     
565
-    put_frame(s, &asf->streams[stream_index], (int)timestamp, buf, size);
566
+    put_frame(s, stream, timestamp, buf, size);
566 567
     return 0;
567 568
 }
568 569
     
... ...
@@ -108,13 +108,16 @@ static int ac3_decode_frame(AVCodecContext *avctx,
108 108
                     /* update codec info */
109 109
                     avctx->sample_rate = sample_rate;
110 110
                     s->channels = ac3_channels[s->flags & 7];
111
-		    if (s->flags & AC3_LFE)
112
-			s->channels++;
113
-		    if (s->channels < avctx->channels) {
114
-			fprintf(stderr, "Source channels are less than specified: output to %d channels..\n", s->channels);
115
-			avctx->channels = s->channels;
116
-		    }
117
-                    avctx->bit_rate = bit_rate;
111
+                    if (s->flags & AC3_LFE)
112
+			            s->channels++;
113
+			        if (avctx->channels == 0)
114
+			            /* No specific number of channel requested */
115
+			            avctx->channels = s->channels;
116
+			        else if (s->channels < avctx->channels) {
117
+			            fprintf(stderr, "libav: AC3 Source channels are less than specified: output to %d channels..\n", s->channels);
118
+			            avctx->channels = s->channels;
119
+		            }
120
+		            avctx->bit_rate = bit_rate;
118 121
                 }
119 122
             }
120 123
         } else if (len < s->frame_size) {
... ...
@@ -127,15 +130,13 @@ static int ac3_decode_frame(AVCodecContext *avctx,
127 127
             s->inbuf_ptr += len;
128 128
             buf_size -= len;
129 129
         } else {
130
-#if 0
130
+            flags = s->flags;
131 131
             if (avctx->channels == 1)
132 132
                 flags = AC3_MONO;
133
-            else
133
+            else if (avctx->channels == 2)
134 134
                 flags = AC3_STEREO;
135
-#else
136
-	    flags = s->flags;
137
-#endif
138
-            flags |= AC3_ADJUST_LEVEL;
135
+            else
136
+                flags |= AC3_ADJUST_LEVEL;
139 137
             level = 1;
140 138
             if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) {
141 139
             fail:
... ...
@@ -146,7 +147,7 @@ static int ac3_decode_frame(AVCodecContext *avctx,
146 146
             for (i = 0; i < 6; i++) {
147 147
                 if (ac3_block (&s->state))
148 148
                     goto fail;
149
-		float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
149
+                float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
150 150
             }
151 151
             s->inbuf_ptr = s->inbuf;
152 152
             s->frame_size = 0;
... ...
@@ -219,6 +219,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
219 219
     const char *codec_name;
220 220
     AVCodec *p;
221 221
     char buf1[32];
222
+    char *channels_str=NULL;
222 223
     int bitrate;
223 224
 
224 225
     if (encode)
... ...
@@ -269,12 +270,27 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
269 269
         snprintf(buf, buf_size,
270 270
                  "Audio: %s",
271 271
                  codec_name);
272
+        switch (enc->channels) {
273
+            case 1:
274
+                channels_str = "mono";
275
+                break;
276
+            case 2:
277
+                channels_str = "stereo";
278
+                break;
279
+            case 6:
280
+                channels_str = "5:1";
281
+                break;
282
+            default:
283
+                sprintf(channels_str, "%d channels", enc->channels);
284
+                break;
285
+        }
272 286
         if (enc->sample_rate) {
273 287
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
274 288
                      ", %d Hz, %s",
275 289
                      enc->sample_rate,
276
-                     enc->channels == 2 ? "stereo" : "mono");
290
+                     channels_str);
277 291
         }
292
+        
278 293
         /* for PCM codecs, compute bitrate directly */
279 294
         switch(enc->codec_id) {
280 295
         case CODEC_ID_PCM_S16LE: