Commit e0d2714a authored by Juanjo's avatar Juanjo

- 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
parent 9f862d11
......@@ -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:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment