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) { | codec->sample_rate == icodec->sample_rate) { | ||||
| ost->audio_resample = 0; | ost->audio_resample = 0; | ||||
| } else { | } 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, | codec->sample_rate, | ||||
| icodec->sample_rate); | icodec->sample_rate); | ||||
| } | |||||
| } | } | ||||
| ist->decoding_needed = 1; | ist->decoding_needed = 1; | ||||
| ost->encoding_needed = 1; | ost->encoding_needed = 1; | ||||
| @@ -1626,6 +1635,7 @@ void opt_input_file(const char *filename) | |||||
| AVCodecContext *enc = &ic->streams[i]->codec; | AVCodecContext *enc = &ic->streams[i]->codec; | ||||
| switch(enc->codec_type) { | switch(enc->codec_type) { | ||||
| case CODEC_TYPE_AUDIO: | case CODEC_TYPE_AUDIO: | ||||
| //fprintf(stderr, "\nInput Audio channels: %d", enc->channels); | |||||
| audio_channels = enc->channels; | audio_channels = enc->channels; | ||||
| audio_sample_rate = enc->sample_rate; | audio_sample_rate = enc->sample_rate; | ||||
| break; | break; | ||||
| @@ -1789,7 +1799,12 @@ void opt_output_file(const char *filename) | |||||
| audio_enc->bit_rate = audio_bit_rate; | audio_enc->bit_rate = audio_bit_rate; | ||||
| audio_enc->sample_rate = audio_sample_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; | oc->streams[nb_streams] = st; | ||||
| nb_streams++; | nb_streams++; | ||||
| } | } | ||||
| @@ -18,6 +18,7 @@ | |||||
| */ | */ | ||||
| #include "avformat.h" | #include "avformat.h" | ||||
| #include "avi.h" | #include "avi.h" | ||||
| #include "tick.h" | |||||
| #define PACKET_SIZE 3200 | #define PACKET_SIZE 3200 | ||||
| #define PACKET_HEADER_SIZE 12 | #define PACKET_HEADER_SIZE 12 | ||||
| @@ -26,6 +27,7 @@ | |||||
| typedef struct { | typedef struct { | ||||
| int num; | int num; | ||||
| int seq; | int seq; | ||||
| Ticker pts_ticker; | |||||
| /* use for reading */ | /* use for reading */ | ||||
| AVPacket pkt; | AVPacket pkt; | ||||
| int frag_offset; | int frag_offset; | ||||
| @@ -283,6 +285,7 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu | |||||
| /* stream headers */ | /* stream headers */ | ||||
| for(n=0;n<s->nb_streams;n++) { | for(n=0;n<s->nb_streams;n++) { | ||||
| ASFStream *stream = &asf->streams[n]; | |||||
| enc = &s->streams[n]->codec; | enc = &s->streams[n]->codec; | ||||
| asf->streams[n].num = n + 1; | asf->streams[n].num = n + 1; | ||||
| asf->streams[n].seq = 0; | 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; | wav_extra_size = 0; | ||||
| extra_size = 18 + wav_extra_size; | extra_size = 18 + wav_extra_size; | ||||
| extra_size2 = 0; | extra_size2 = 0; | ||||
| /* Init the ticker */ | |||||
| ticker_init(&stream->pts_ticker, | |||||
| enc->sample_rate, | |||||
| 1000 * enc->frame_size); | |||||
| break; | break; | ||||
| default: | default: | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| wav_extra_size = 0; | wav_extra_size = 0; | ||||
| extra_size = 0x33; | extra_size = 0x33; | ||||
| extra_size2 = 0; | extra_size2 = 0; | ||||
| /* Init the ticker */ | |||||
| ticker_init(&stream->pts_ticker, | |||||
| enc->frame_rate, | |||||
| 1000 * FRAME_RATE_BASE); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -543,26 +554,27 @@ static int asf_write_packet(AVFormatContext *s, int stream_index, | |||||
| UINT8 *buf, int size, int force_pts) | UINT8 *buf, int size, int force_pts) | ||||
| { | { | ||||
| ASFContext *asf = s->priv_data; | ASFContext *asf = s->priv_data; | ||||
| ASFStream *stream; | |||||
| int timestamp; | int timestamp; | ||||
| INT64 duration; | INT64 duration; | ||||
| AVCodecContext *codec; | AVCodecContext *codec; | ||||
| codec = &s->streams[stream_index]->codec; | codec = &s->streams[stream_index]->codec; | ||||
| stream = &asf->streams[stream_index]; | |||||
| if (codec->codec_type == CODEC_TYPE_AUDIO) { | 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)) / | duration = (codec->frame_number * codec->frame_size * INT64_C(10000000)) / | ||||
| codec->sample_rate; | codec->sample_rate; | ||||
| } else { | } 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 * | duration = codec->frame_number * | ||||
| ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate); | ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate); | ||||
| } | } | ||||
| if (duration > asf->duration) | if (duration > asf->duration) | ||||
| asf->duration = duration; | asf->duration = duration; | ||||
| put_frame(s, &asf->streams[stream_index], (int)timestamp, buf, size); | |||||
| put_frame(s, stream, timestamp, buf, size); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -108,13 +108,16 @@ static int ac3_decode_frame(AVCodecContext *avctx, | |||||
| /* update codec info */ | /* update codec info */ | ||||
| avctx->sample_rate = sample_rate; | avctx->sample_rate = sample_rate; | ||||
| s->channels = ac3_channels[s->flags & 7]; | 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) { | } else if (len < s->frame_size) { | ||||
| @@ -127,15 +130,13 @@ static int ac3_decode_frame(AVCodecContext *avctx, | |||||
| s->inbuf_ptr += len; | s->inbuf_ptr += len; | ||||
| buf_size -= len; | buf_size -= len; | ||||
| } else { | } else { | ||||
| #if 0 | |||||
| flags = s->flags; | |||||
| if (avctx->channels == 1) | if (avctx->channels == 1) | ||||
| flags = AC3_MONO; | flags = AC3_MONO; | ||||
| else | |||||
| else if (avctx->channels == 2) | |||||
| flags = AC3_STEREO; | flags = AC3_STEREO; | ||||
| #else | |||||
| flags = s->flags; | |||||
| #endif | |||||
| flags |= AC3_ADJUST_LEVEL; | |||||
| else | |||||
| flags |= AC3_ADJUST_LEVEL; | |||||
| level = 1; | level = 1; | ||||
| if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { | if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { | ||||
| fail: | fail: | ||||
| @@ -146,7 +147,7 @@ static int ac3_decode_frame(AVCodecContext *avctx, | |||||
| for (i = 0; i < 6; i++) { | for (i = 0; i < 6; i++) { | ||||
| if (ac3_block (&s->state)) | if (ac3_block (&s->state)) | ||||
| goto fail; | 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->inbuf_ptr = s->inbuf; | ||||
| s->frame_size = 0; | s->frame_size = 0; | ||||
| @@ -219,6 +219,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) | |||||
| const char *codec_name; | const char *codec_name; | ||||
| AVCodec *p; | AVCodec *p; | ||||
| char buf1[32]; | char buf1[32]; | ||||
| char *channels_str=NULL; | |||||
| int bitrate; | int bitrate; | ||||
| if (encode) | if (encode) | ||||
| @@ -269,12 +270,27 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) | |||||
| snprintf(buf, buf_size, | snprintf(buf, buf_size, | ||||
| "Audio: %s", | "Audio: %s", | ||||
| codec_name); | 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) { | if (enc->sample_rate) { | ||||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | snprintf(buf + strlen(buf), buf_size - strlen(buf), | ||||
| ", %d Hz, %s", | ", %d Hz, %s", | ||||
| enc->sample_rate, | enc->sample_rate, | ||||
| enc->channels == 2 ? "stereo" : "mono"); | |||||
| channels_str); | |||||
| } | } | ||||
| /* for PCM codecs, compute bitrate directly */ | /* for PCM codecs, compute bitrate directly */ | ||||
| switch(enc->codec_id) { | switch(enc->codec_id) { | ||||
| case CODEC_ID_PCM_S16LE: | case CODEC_ID_PCM_S16LE: | ||||