Originally committed as revision 1664 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
@@ -806,7 +806,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
asf->packet_size = asf->hdr.max_pktsize; | asf->packet_size = asf->hdr.max_pktsize; | ||||
asf->nb_packets = asf->hdr.packets_count; | asf->nb_packets = asf->hdr.packets_count; | ||||
} else if (!memcmp(&g, &stream_header, sizeof(GUID))) { | } else if (!memcmp(&g, &stream_header, sizeof(GUID))) { | ||||
int type, total_size; | |||||
int type, total_size, type_specific_size; | |||||
unsigned int tag1; | unsigned int tag1; | ||||
int64_t pos1, pos2; | int64_t pos1, pos2; | ||||
@@ -832,7 +832,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
} | } | ||||
get_guid(pb, &g); | get_guid(pb, &g); | ||||
total_size = get_le64(pb); | total_size = get_le64(pb); | ||||
get_le32(pb); | |||||
type_specific_size = get_le32(pb); | |||||
get_le32(pb); | get_le32(pb); | ||||
st->id = get_le16(pb) & 0x7f; /* stream id */ | st->id = get_le16(pb) & 0x7f; /* stream id */ | ||||
// mapping of asf ID to AV stream ID; | // mapping of asf ID to AV stream ID; | ||||
@@ -842,7 +842,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
st->codec.codec_type = type; | st->codec.codec_type = type; | ||||
st->codec.frame_rate = 15 * s->pts_den / s->pts_num; // 15 fps default | st->codec.frame_rate = 15 * s->pts_den / s->pts_num; // 15 fps default | ||||
if (type == CODEC_TYPE_AUDIO) { | if (type == CODEC_TYPE_AUDIO) { | ||||
get_wav_header(pb, &st->codec, 1); | |||||
get_wav_header(pb, &st->codec, type_specific_size); | |||||
/* We have to init the frame size at some point .... */ | /* We have to init the frame size at some point .... */ | ||||
pos2 = url_ftell(pb); | pos2 = url_ftell(pb); | ||||
if (gsize > (pos2 + 8 - pos1 + 24)) { | if (gsize > (pos2 + 8 - pos1 + 24)) { | ||||
@@ -18,8 +18,7 @@ typedef struct CodecTag { | |||||
void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf); | void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf); | ||||
int 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); | int wav_codec_get_id(unsigned int tag, int bps); | ||||
void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, | |||||
int has_extra_data); | |||||
void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size); | |||||
extern const CodecTag codec_bmp_tags[]; | extern const CodecTag codec_bmp_tags[]; | ||||
extern const CodecTag codec_wav_tags[]; | extern const CodecTag codec_wav_tags[]; | ||||
@@ -187,7 +187,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
// url_fskip(pb, size - 5 * 4); | // url_fskip(pb, size - 5 * 4); | ||||
break; | break; | ||||
case CODEC_TYPE_AUDIO: | case CODEC_TYPE_AUDIO: | ||||
get_wav_header(pb, &st->codec, (size >= 18)); | |||||
get_wav_header(pb, &st->codec, size); | |||||
if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ | if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ | ||||
url_fskip(pb, 1); | url_fskip(pb, 1); | ||||
break; | break; | ||||
@@ -103,26 +103,44 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) | |||||
return hdrsize; | return hdrsize; | ||||
} | } | ||||
void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, | |||||
int has_extra_data) | |||||
/* We could be given one of the three possible structures here: | |||||
* WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure | |||||
* is an expansion of the previous one with the fields added | |||||
* at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and | |||||
* WAVEFORMATEX adds 'WORD cbSize' and basically makes itself | |||||
* an openended structure. | |||||
*/ | |||||
void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size) | |||||
{ | { | ||||
int id; | int id; | ||||
id = get_le16(pb); | id = get_le16(pb); | ||||
codec->codec_id = wav_codec_get_id(id, codec->frame_bits); | |||||
codec->codec_type = CODEC_TYPE_AUDIO; | codec->codec_type = CODEC_TYPE_AUDIO; | ||||
codec->codec_tag = id; | codec->codec_tag = id; | ||||
codec->channels = get_le16(pb); | codec->channels = get_le16(pb); | ||||
codec->sample_rate = get_le32(pb); | codec->sample_rate = get_le32(pb); | ||||
codec->bit_rate = get_le32(pb) * 8; | codec->bit_rate = get_le32(pb) * 8; | ||||
codec->block_align = get_le16(pb); | codec->block_align = get_le16(pb); | ||||
codec->bits_per_sample = get_le16(pb); /* bits per sample */ | |||||
codec->codec_id = wav_codec_get_id(id, codec->frame_bits); | |||||
if (has_extra_data) { | |||||
if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ | |||||
codec->bits_per_sample = 8; | |||||
return; | |||||
} | |||||
codec->bits_per_sample = get_le16(pb); | |||||
if (size > 16) { /* We're obviously dealing with WAVEFORMATEX */ | |||||
codec->extradata_size = get_le16(pb); | codec->extradata_size = get_le16(pb); | ||||
if (codec->extradata_size > 0) { | if (codec->extradata_size > 0) { | ||||
if (codec->extradata_size > size - 18) | |||||
codec->extradata_size = size - 18; | |||||
codec->extradata = av_mallocz(codec->extradata_size); | codec->extradata = av_mallocz(codec->extradata_size); | ||||
get_buffer(pb, codec->extradata, codec->extradata_size); | get_buffer(pb, codec->extradata, codec->extradata_size); | ||||
} | |||||
} else | |||||
codec->extradata_size = 0; | |||||
/* It is possible for the chunk to contain garbage at the end */ | |||||
if (size - codec->extradata_size - 18 > 0) | |||||
url_fskip(pb, size - codec->extradata_size - 18); | |||||
} | } | ||||
} | } | ||||
@@ -259,7 +277,7 @@ static int wav_read_header(AVFormatContext *s, | |||||
if (!st) | if (!st) | ||||
return AVERROR_NOMEM; | return AVERROR_NOMEM; | ||||
get_wav_header(pb, &st->codec, (size >= 18)); | |||||
get_wav_header(pb, &st->codec, size); | |||||
size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); | size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); | ||||
if (size < 0) | if (size < 0) | ||||