mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-17 20:17:55 +02:00
Make the IFF demuxer a little more standards-compliant, e.g. respect the size
fields of common media header chunks (these can have different sizes depending on the type of IFF file you read), better handle odd sizes (like RIFF, every field is padded to word) and handle headerchunks after the BODY chunk. Patch by Sebastian Vater <cdgs.basty googlemail com>. Originally committed as revision 22977 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
726dc06158
commit
46dcabf82b
@ -2,6 +2,7 @@
|
|||||||
* IFF (.iff) file demuxer
|
* IFF (.iff) file demuxer
|
||||||
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
|
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
|
||||||
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
|
* Copyright (c) 2010 Peter Ross <pross@xvid.org>
|
||||||
|
* Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
|
||||||
*
|
*
|
||||||
* This file is part of FFmpeg.
|
* This file is part of FFmpeg.
|
||||||
*
|
*
|
||||||
@ -72,6 +73,7 @@ typedef enum {
|
|||||||
} bitmap_compression_type;
|
} bitmap_compression_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint64_t body_pos;
|
||||||
uint32_t body_size;
|
uint32_t body_size;
|
||||||
uint32_t sent_bytes;
|
uint32_t sent_bytes;
|
||||||
uint32_t audio_frame_count;
|
uint32_t audio_frame_count;
|
||||||
@ -107,7 +109,6 @@ static int iff_read_header(AVFormatContext *s,
|
|||||||
ByteIOContext *pb = s->pb;
|
ByteIOContext *pb = s->pb;
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
uint32_t chunk_id, data_size;
|
uint32_t chunk_id, data_size;
|
||||||
int padding, done = 0;
|
|
||||||
int compression = -1;
|
int compression = -1;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
@ -120,27 +121,34 @@ static int iff_read_header(AVFormatContext *s,
|
|||||||
// codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
|
// codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
|
||||||
st->codec->codec_tag = get_le32(pb);
|
st->codec->codec_tag = get_le32(pb);
|
||||||
|
|
||||||
while(!done && !url_feof(pb)) {
|
while(!url_feof(pb)) {
|
||||||
|
uint64_t orig_pos;
|
||||||
chunk_id = get_le32(pb);
|
chunk_id = get_le32(pb);
|
||||||
data_size = get_be32(pb);
|
data_size = get_be32(pb);
|
||||||
padding = data_size & 1;
|
orig_pos = url_ftell(pb);
|
||||||
|
|
||||||
switch(chunk_id) {
|
switch(chunk_id) {
|
||||||
case ID_VHDR:
|
case ID_VHDR:
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||||
|
|
||||||
|
if (data_size < 14)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
url_fskip(pb, 12);
|
url_fskip(pb, 12);
|
||||||
st->codec->sample_rate = get_be16(pb);
|
st->codec->sample_rate = get_be16(pb);
|
||||||
|
if (data_size >= 16) {
|
||||||
url_fskip(pb, 1);
|
url_fskip(pb, 1);
|
||||||
compression = get_byte(pb);
|
compression = get_byte(pb);
|
||||||
url_fskip(pb, 4);
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_BODY:
|
case ID_BODY:
|
||||||
|
iff->body_pos = url_ftell(pb);
|
||||||
iff->body_size = data_size;
|
iff->body_size = data_size;
|
||||||
done = 1;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_CHAN:
|
case ID_CHAN:
|
||||||
|
if (data_size < 4)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
st->codec->channels = (get_be32(pb) < 6) ? 1 : 2;
|
st->codec->channels = (get_be32(pb) < 6) ? 1 : 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -155,16 +163,21 @@ static int iff_read_header(AVFormatContext *s,
|
|||||||
|
|
||||||
case ID_BMHD:
|
case ID_BMHD:
|
||||||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||||
|
if (data_size <= 8)
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
st->codec->width = get_be16(pb);
|
st->codec->width = get_be16(pb);
|
||||||
st->codec->height = get_be16(pb);
|
st->codec->height = get_be16(pb);
|
||||||
url_fskip(pb, 4); // x, y offset
|
url_fskip(pb, 4); // x, y offset
|
||||||
st->codec->bits_per_coded_sample = get_byte(pb);
|
st->codec->bits_per_coded_sample = get_byte(pb);
|
||||||
|
if (data_size >= 11) {
|
||||||
url_fskip(pb, 1); // masking
|
url_fskip(pb, 1); // masking
|
||||||
compression = get_byte(pb);
|
compression = get_byte(pb);
|
||||||
|
}
|
||||||
|
if (data_size >= 16) {
|
||||||
url_fskip(pb, 3); // paddding, transparent
|
url_fskip(pb, 3); // paddding, transparent
|
||||||
st->sample_aspect_ratio.num = get_byte(pb);
|
st->sample_aspect_ratio.num = get_byte(pb);
|
||||||
st->sample_aspect_ratio.den = get_byte(pb);
|
st->sample_aspect_ratio.den = get_byte(pb);
|
||||||
url_fskip(pb, 4); // source page width, height
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_ANNO:
|
case ID_ANNO:
|
||||||
@ -175,13 +188,13 @@ static int iff_read_header(AVFormatContext *s,
|
|||||||
buf[data_size] = 0;
|
buf[data_size] = 0;
|
||||||
av_metadata_set2(&s->metadata, "comment", buf, AV_METADATA_DONT_STRDUP_VAL);
|
av_metadata_set2(&s->metadata, "comment", buf, AV_METADATA_DONT_STRDUP_VAL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
|
||||||
url_fseek(pb, data_size + padding, SEEK_CUR);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url_fskip(pb, data_size - (url_ftell(pb) - orig_pos) + (data_size & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url_fseek(pb, iff->body_pos, SEEK_SET);
|
||||||
|
|
||||||
switch(st->codec->codec_type) {
|
switch(st->codec->codec_type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
av_set_pts_info(st, 32, 1, st->codec->sample_rate);
|
av_set_pts_info(st, 32, 1, st->codec->sample_rate);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user