correct pcm audio format handling

Originally committed as revision 147 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Fabrice Bellard 2001-09-24 23:26:46 +00:00
parent 96baaa6aff
commit 46a3d0685d
5 changed files with 75 additions and 43 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}