1
0
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:
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) { if (enc->codec_type == CODEC_TYPE_AUDIO) {
/* WAVEFORMATEX header */ /* WAVEFORMATEX header */
put_wav_header(pb, enc); if (put_wav_header(pb, enc) < 0)
return -1;
} else { } else {
put_le32(pb, enc->width); put_le32(pb, enc->width);
put_le32(pb, enc->height); put_le32(pb, enc->height);
@ -376,7 +377,10 @@ static int asf_write_header(AVFormatContext *s)
asf->packet_size = PACKET_SIZE; asf->packet_size = PACKET_SIZE;
asf->nb_packets = 0; 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); put_flush_packet(&s->pb);
@ -637,7 +641,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
AVStream *st; AVStream *st;
ASFStream *asf_st; ASFStream *asf_st;
int size, i; int size, i, bps;
INT64 gsize; INT64 gsize;
asf = av_mallocz(sizeof(ASFContext)); asf = av_mallocz(sizeof(ASFContext));
@ -710,12 +714,12 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)
if (type == CODEC_TYPE_AUDIO) { if (type == CODEC_TYPE_AUDIO) {
id = get_le16(pb); id = get_le16(pb);
st->codec.codec_tag = id; st->codec.codec_tag = id;
st->codec.codec_id = codec_get_id(codec_wav_tags, id);
st->codec.channels = get_le16(pb); st->codec.channels = get_le16(pb);
st->codec.sample_rate = get_le32(pb); st->codec.sample_rate = get_le32(pb);
st->codec.bit_rate = get_le32(pb) * 8; st->codec.bit_rate = get_le32(pb) * 8;
get_le16(pb); /* block align */ get_le16(pb); /* block align */
get_le16(pb); /* bits per sample */ bps = get_le16(pb); /* bits per sample */
st->codec.codec_id = wav_codec_get_id(id, bps);
size = get_le16(pb); size = get_le16(pb);
url_fskip(pb, size); url_fskip(pb, size);
} else { } else {

View File

@ -10,7 +10,8 @@ offset_t start_tag(ByteIOContext *pb, char *tag);
void end_tag(ByteIOContext *pb, offset_t start); void end_tag(ByteIOContext *pb, offset_t start);
void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc); 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 { typedef struct CodecTag {
int id; int id;

View File

@ -51,7 +51,7 @@ int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
UINT32 tag, tag1; UINT32 tag, tag1;
int codec_type, stream_index, size, frame_period, bit_rate; int codec_type, stream_index, size, frame_period, bit_rate;
int i; int i, bps;
AVStream *st; AVStream *st;
avi = malloc(sizeof(AVIContext)); avi = malloc(sizeof(AVIContext));
@ -169,14 +169,16 @@ int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
tag1 = get_le16(pb); tag1 = get_le16(pb);
st->codec.codec_type = CODEC_TYPE_AUDIO; st->codec.codec_type = CODEC_TYPE_AUDIO;
st->codec.codec_tag = tag1; st->codec.codec_tag = tag1;
st->codec.codec_id = codec_get_id(codec_wav_tags, tag1);
#ifdef DEBUG #ifdef DEBUG
printf("audio: 0x%x\n", tag1); printf("audio: 0x%x\n", tag1);
#endif #endif
st->codec.channels = get_le16(pb); st->codec.channels = get_le16(pb);
st->codec.sample_rate = get_le32(pb); st->codec.sample_rate = get_le32(pb);
st->codec.bit_rate = get_le32(pb) * 8; 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; break;
default: default:
url_fskip(pb, size); url_fskip(pb, size);

View File

@ -67,17 +67,6 @@ CodecTag codec_bmp_tags[] = {
{ 0, 0 }, { 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) unsigned int codec_get_tag(CodecTag *tags, int id)
{ {
while (tags->id != 0) { while (tags->id != 0) {
@ -120,22 +109,6 @@ void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc)
put_le32(pb, 0); 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) static int avi_write_header(AVFormatContext *s)
{ {
AVIContext *avi; AVIContext *avi;
@ -247,7 +220,10 @@ static int avi_write_header(AVFormatContext *s)
put_bmp_header(pb, stream); put_bmp_header(pb, stream);
break; break;
case CODEC_TYPE_AUDIO: case CODEC_TYPE_AUDIO:
put_wav_header(pb, stream); if (put_wav_header(pb, stream) < 0) {
free(avi);
return -1;
}
break; break;
} }
end_tag(pb, strf); end_tag(pb, strf);

View File

@ -19,6 +19,55 @@
#include "avformat.h" #include "avformat.h"
#include "avi.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 { typedef struct {
offset_t data; offset_t data;
} WAVContext; } WAVContext;
@ -41,7 +90,10 @@ static int wav_write_header(AVFormatContext *s)
/* format header */ /* format header */
fmt = start_tag(pb, "fmt "); 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); end_tag(pb, fmt);
/* data header */ /* data header */
@ -155,12 +207,9 @@ static int wav_read_header(AVFormatContext *s,
st->codec.codec_type = CODEC_TYPE_AUDIO; st->codec.codec_type = CODEC_TYPE_AUDIO;
st->codec.codec_tag = id; 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.channels = channels;
st->codec.sample_rate = rate; 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; return 0;
} }