提交 e0d2714a 编写于 作者: J 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
上级 9f862d11
...@@ -741,10 +741,19 @@ static int av_encode(AVFormatContext **output_files, ...@@ -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; if (codec->channels != icodec->channels &&
ost->resample = audio_resample_init(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) ...@@ -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) ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 / timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
codec->sample_rate);
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 / timestamp = (int)ticker_tick(&stream->pts_ticker, codec->frame_number);
codec->frame_rate);
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, ...@@ -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) if (s->flags & AC3_LFE)
s->channels++; s->channels++;
if (s->channels < avctx->channels) { if (avctx->channels == 0)
fprintf(stderr, "Source channels are less than specified: output to %d channels..\n", s->channels); /* No specific number of channel requested */
avctx->channels = s->channels; avctx->channels = s->channels;
} else if (s->channels < avctx->channels) {
avctx->bit_rate = bit_rate; 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, ...@@ -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 else
flags = s->flags; flags |= AC3_ADJUST_LEVEL;
#endif
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, ...@@ -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) ...@@ -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) ...@@ -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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册