mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
correct pcm audio format handling
Originally committed as revision 147 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
96baaa6aff
commit
46a3d0685d
16
libav/asf.c
16
libav/asf.c
@ -301,7 +301,8 @@ static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chu
|
||||
|
||||
if (enc->codec_type == CODEC_TYPE_AUDIO) {
|
||||
/* WAVEFORMATEX header */
|
||||
put_wav_header(pb, enc);
|
||||
if (put_wav_header(pb, enc) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
put_le32(pb, enc->width);
|
||||
put_le32(pb, enc->height);
|
||||
@ -376,7 +377,10 @@ static int asf_write_header(AVFormatContext *s)
|
||||
asf->packet_size = PACKET_SIZE;
|
||||
asf->nb_packets = 0;
|
||||
|
||||
asf_write_header1(s, 0, 24);
|
||||
if (asf_write_header1(s, 0, 24) < 0) {
|
||||
free(asf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
put_flush_packet(&s->pb);
|
||||
|
||||
@ -637,7 +641,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
ByteIOContext *pb = &s->pb;
|
||||
AVStream *st;
|
||||
ASFStream *asf_st;
|
||||
int size, i;
|
||||
int size, i, bps;
|
||||
INT64 gsize;
|
||||
|
||||
asf = av_mallocz(sizeof(ASFContext));
|
||||
@ -710,13 +714,13 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
if (type == CODEC_TYPE_AUDIO) {
|
||||
id = get_le16(pb);
|
||||
st->codec.codec_tag = id;
|
||||
st->codec.codec_id = codec_get_id(codec_wav_tags, id);
|
||||
st->codec.channels = get_le16(pb);
|
||||
st->codec.sample_rate = get_le32(pb);
|
||||
st->codec.bit_rate = get_le32(pb) * 8;
|
||||
get_le16(pb); /* block align */
|
||||
get_le16(pb); /* bits per sample */
|
||||
size = get_le16(pb);
|
||||
bps = get_le16(pb); /* bits per sample */
|
||||
st->codec.codec_id = wav_codec_get_id(id, bps);
|
||||
size = get_le16(pb);
|
||||
url_fskip(pb, size);
|
||||
} else {
|
||||
get_le32(pb);
|
||||
|
@ -10,7 +10,8 @@ offset_t start_tag(ByteIOContext *pb, char *tag);
|
||||
void end_tag(ByteIOContext *pb, offset_t start);
|
||||
|
||||
void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc);
|
||||
void put_wav_header(ByteIOContext *pb, AVCodecContext *enc);
|
||||
int put_wav_header(ByteIOContext *pb, AVCodecContext *enc);
|
||||
int wav_codec_get_id(unsigned int tag, int bps);
|
||||
|
||||
typedef struct CodecTag {
|
||||
int id;
|
||||
|
@ -51,7 +51,7 @@ int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
ByteIOContext *pb = &s->pb;
|
||||
UINT32 tag, tag1;
|
||||
int codec_type, stream_index, size, frame_period, bit_rate;
|
||||
int i;
|
||||
int i, bps;
|
||||
AVStream *st;
|
||||
|
||||
avi = malloc(sizeof(AVIContext));
|
||||
@ -169,14 +169,16 @@ int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
tag1 = get_le16(pb);
|
||||
st->codec.codec_type = CODEC_TYPE_AUDIO;
|
||||
st->codec.codec_tag = tag1;
|
||||
st->codec.codec_id = codec_get_id(codec_wav_tags, tag1);
|
||||
#ifdef DEBUG
|
||||
printf("audio: 0x%x\n", tag1);
|
||||
#endif
|
||||
st->codec.channels = get_le16(pb);
|
||||
st->codec.sample_rate = get_le32(pb);
|
||||
st->codec.bit_rate = get_le32(pb) * 8;
|
||||
url_fskip(pb, size - 3 * 4);
|
||||
get_le16(pb); /* block align */
|
||||
bps = get_le16(pb);
|
||||
st->codec.codec_id = wav_codec_get_id(tag1, bps);
|
||||
url_fskip(pb, size - 4 * 4);
|
||||
break;
|
||||
default:
|
||||
url_fskip(pb, size);
|
||||
|
@ -67,17 +67,6 @@ CodecTag codec_bmp_tags[] = {
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
CodecTag codec_wav_tags[] = {
|
||||
{ CODEC_ID_MP2, 0x55 },
|
||||
{ CODEC_ID_MP2, 0x50 },
|
||||
{ CODEC_ID_AC3, 0x2000 },
|
||||
{ CODEC_ID_PCM_S16LE, 0x01 },
|
||||
{ CODEC_ID_PCM_ALAW, 0x06 },
|
||||
{ CODEC_ID_PCM_MULAW, 0x07 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
|
||||
unsigned int codec_get_tag(CodecTag *tags, int id)
|
||||
{
|
||||
while (tags->id != 0) {
|
||||
@ -120,22 +109,6 @@ void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc)
|
||||
put_le32(pb, 0);
|
||||
}
|
||||
|
||||
/* WAVEFORMATEX header */
|
||||
void put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
|
||||
{
|
||||
int tag;
|
||||
|
||||
tag = codec_get_tag(codec_wav_tags, enc->codec_id);
|
||||
|
||||
put_le16(pb, tag);
|
||||
put_le16(pb, enc->channels);
|
||||
put_le32(pb, enc->sample_rate);
|
||||
put_le32(pb, enc->bit_rate / 8);
|
||||
put_le16(pb, 1); /* block align */
|
||||
put_le16(pb, 16); /* bits per sample */
|
||||
put_le16(pb, 0); /* wav_extra_size */
|
||||
}
|
||||
|
||||
static int avi_write_header(AVFormatContext *s)
|
||||
{
|
||||
AVIContext *avi;
|
||||
@ -247,7 +220,10 @@ static int avi_write_header(AVFormatContext *s)
|
||||
put_bmp_header(pb, stream);
|
||||
break;
|
||||
case CODEC_TYPE_AUDIO:
|
||||
put_wav_header(pb, stream);
|
||||
if (put_wav_header(pb, stream) < 0) {
|
||||
free(avi);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
end_tag(pb, strf);
|
||||
|
59
libav/wav.c
59
libav/wav.c
@ -19,6 +19,55 @@
|
||||
#include "avformat.h"
|
||||
#include "avi.h"
|
||||
|
||||
CodecTag codec_wav_tags[] = {
|
||||
{ CODEC_ID_MP2, 0x55 },
|
||||
{ CODEC_ID_MP2, 0x50 },
|
||||
{ CODEC_ID_AC3, 0x2000 },
|
||||
{ CODEC_ID_PCM_S16LE, 0x01 },
|
||||
{ CODEC_ID_PCM_U8, 0x01 }, /* must come after s16le in this list */
|
||||
{ CODEC_ID_PCM_ALAW, 0x06 },
|
||||
{ CODEC_ID_PCM_MULAW, 0x07 },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
/* WAVEFORMATEX header */
|
||||
int put_wav_header(ByteIOContext *pb, AVCodecContext *enc)
|
||||
{
|
||||
int tag, bps;
|
||||
|
||||
tag = codec_get_tag(codec_wav_tags, enc->codec_id);
|
||||
if (tag == 0)
|
||||
return -1;
|
||||
put_le16(pb, tag);
|
||||
put_le16(pb, enc->channels);
|
||||
put_le32(pb, enc->sample_rate);
|
||||
put_le32(pb, enc->bit_rate / 8);
|
||||
put_le16(pb, 1); /* block align */
|
||||
if (enc->codec_id == CODEC_ID_PCM_U8 ||
|
||||
enc->codec_id == CODEC_ID_PCM_ALAW ||
|
||||
enc->codec_id == CODEC_ID_PCM_MULAW) {
|
||||
bps = 8;
|
||||
} else {
|
||||
bps = 16;
|
||||
}
|
||||
put_le16(pb, bps); /* bits per sample */
|
||||
|
||||
put_le16(pb, 0); /* wav_extra_size */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wav_codec_get_id(unsigned int tag, int bps)
|
||||
{
|
||||
int id;
|
||||
id = codec_get_id(codec_wav_tags, tag);
|
||||
if (id <= 0)
|
||||
return id;
|
||||
/* handle specific u8 codec */
|
||||
if (id == CODEC_ID_PCM_S16LE && bps == 8)
|
||||
id = CODEC_ID_PCM_U8;
|
||||
return id;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
offset_t data;
|
||||
} WAVContext;
|
||||
@ -41,7 +90,10 @@ static int wav_write_header(AVFormatContext *s)
|
||||
|
||||
/* format header */
|
||||
fmt = start_tag(pb, "fmt ");
|
||||
put_wav_header(pb, &s->streams[0]->codec);
|
||||
if (put_wav_header(pb, &s->streams[0]->codec) < 0) {
|
||||
free(wav);
|
||||
return -1;
|
||||
}
|
||||
end_tag(pb, fmt);
|
||||
|
||||
/* data header */
|
||||
@ -155,12 +207,9 @@ static int wav_read_header(AVFormatContext *s,
|
||||
|
||||
st->codec.codec_type = CODEC_TYPE_AUDIO;
|
||||
st->codec.codec_tag = id;
|
||||
st->codec.codec_id = codec_get_id(codec_wav_tags, id);
|
||||
st->codec.codec_id = wav_codec_get_id(id, bps);
|
||||
st->codec.channels = channels;
|
||||
st->codec.sample_rate = rate;
|
||||
if (st->codec.codec_id == CODEC_ID_PCM_S16LE && bps == 8) {
|
||||
st->codec.codec_id = CODEC_ID_PCM_U8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user