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/trunktags/v0.5
| @@ -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++; | |||
| } | |||
| @@ -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; | |||
| } | |||
| @@ -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; | |||
| @@ -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: | |||