mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
- 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
This commit is contained in:
parent
9f862d1133
commit
e0d2714adc
21
ffmpeg.c
21
ffmpeg.c
@ -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++;
|
||||
}
|
||||
|
22
libav/asf.c
22
libav/asf.c
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user