- 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) {
|
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)
|
|||||||
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++;
|
||||||
}
|
}
|
||||||
|
22
libav/asf.c
22
libav/asf.c
@ -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 /
|
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,
|
|||||||
/* 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,
|
|||||||
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,
|
|||||||
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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user