diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-04-25 02:47:47 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-04-25 03:49:47 +0200 |
commit | 2ebd47841f16d1d521d7dd9b5ae0b8015443b690 (patch) | |
tree | 5e32bef0eda02346d15fa212326806ab58e9103b /libavformat/iff.c | |
parent | 9d7244c4c60d9f85f58b3770065a394c71fdce3f (diff) | |
parent | 989fb05fe344d9666db858e0577c44969625184e (diff) | |
download | ffmpeg-2ebd47841f16d1d521d7dd9b5ae0b8015443b690.tar.gz |
Merge branch 'master' into oldabi
* master: (172 commits)
Check mmap() return against correct value Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
vorbisdec: Employ proper printf format specifiers for uint_fast32_t.
Support fourcc MMJP.
Support fourcc XVIX.
Support fourcc M263.
Support fourcc auv2.
Fix indentation.
Support PARSER_FLAG_COMPLETE_FRAMES for h261 and h263 parsers.
ffplay: avoid SIGFPE exception in SDL_DisplayYUVOverlay
avi: try to synchronize the points in time of the starts of streams after seeking. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Add flag to force demuxers to sort more strictly by dts. This enables non interleaved AVI mode for example. Players that are picky on strict interleaving can set this. Patches to only switch to non intereaved AVI mode when the index is not strictly correctly interleaved are welcome. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
applehttp: Don't export variant_bitrate if it isn't known
crypto: Use av_freep instead of av_free
CrystalHD: Add AVOption to configure hardware downscaling.
Check for malloc failures in fraps decoder.
Use av_fast_malloc instead of av_realloc in fraps decoder.
general.texi: document libcelt decoder.
Fix some passing argument from incompatible pointer type warnings. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
configure: Add missing libm library dependencies to .pc files.
oggdec: reindent after 8f3eebd6
...
Conflicts:
libavcodec/version.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/iff.c')
-rw-r--r-- | libavformat/iff.c | 78 |
1 files changed, 71 insertions, 7 deletions
diff --git a/libavformat/iff.c b/libavformat/iff.c index 24942122ad..da4e858501 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -29,6 +29,7 @@ * http://wiki.multimedia.cx/index.php?title=IFF */ +#include "libavcodec/bytestream.h" #include "libavutil/intreadwrite.h" #include "avformat.h" @@ -40,6 +41,7 @@ #define ID_PBM MKTAG('P','B','M',' ') #define ID_ILBM MKTAG('I','L','B','M') #define ID_BMHD MKTAG('B','M','H','D') +#define ID_CAMG MKTAG('C','A','M','G') #define ID_CMAP MKTAG('C','M','A','P') #define ID_FORM MKTAG('F','O','R','M') @@ -60,6 +62,16 @@ #define PACKET_SIZE 1024 +/** + * This number of bytes if added at the beginning of each AVPacket + * which contain additional information about video properties + * which has to be shared between demuxer and decoder. + * This number may change between frames, e.g. the demuxer might + * set it to smallest possible size of 2 to indicate that there's + * no extradata changing in this frame. + */ +#define IFF_EXTRA_VIDEO_SIZE 9 + typedef enum { COMP_NONE, COMP_FIB, @@ -76,6 +88,12 @@ typedef struct { uint32_t body_size; uint32_t sent_bytes; uint32_t audio_frame_count; + unsigned compression; ///< delta compression method used + unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM) + unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise) + unsigned flags; ///< 1 for EHB, 0 is no extra half darkening + unsigned transparency; ///< transparency color index in palette + unsigned masking; ///< masking method used } IffDemuxContext; @@ -126,8 +144,12 @@ static int iff_read_header(AVFormatContext *s, IffDemuxContext *iff = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; + uint8_t *buf; uint32_t chunk_id, data_size; int compression = -1; + uint32_t screenmode = 0; + unsigned transparency = 0; + unsigned masking = 0; // no mask st = av_new_stream(s, 0); if (!st) @@ -171,12 +193,18 @@ static int iff_read_header(AVFormatContext *s, st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2; break; + case ID_CAMG: + if (data_size < 4) + return AVERROR_INVALIDDATA; + screenmode = avio_rb32(pb); + break; + case ID_CMAP: - st->codec->extradata_size = data_size; - st->codec->extradata = av_malloc(data_size); + st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; + st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) return AVERROR(ENOMEM); - if (avio_read(pb, st->codec->extradata, data_size) < 0) + if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0) return AVERROR(EIO); break; @@ -188,12 +216,15 @@ static int iff_read_header(AVFormatContext *s, st->codec->height = avio_rb16(pb); avio_skip(pb, 4); // x, y offset st->codec->bits_per_coded_sample = avio_r8(pb); - if (data_size >= 11) { - avio_skip(pb, 1); // masking + if (data_size >= 10) + masking = avio_r8(pb); + if (data_size >= 11) compression = avio_r8(pb); + if (data_size >= 14) { + avio_skip(pb, 1); // padding + transparency = avio_rb16(pb); } if (data_size >= 16) { - avio_skip(pb, 3); // paddding, transparent st->sample_aspect_ratio.num = avio_r8(pb); st->sample_aspect_ratio.den = avio_r8(pb); } @@ -253,6 +284,31 @@ static int iff_read_header(AVFormatContext *s, break; case AVMEDIA_TYPE_VIDEO: + iff->compression = compression; + iff->bpp = st->codec->bits_per_coded_sample; + if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) { + iff->ham = iff->bpp > 6 ? 6 : 4; + st->codec->bits_per_coded_sample = 24; + } + iff->flags = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8; + iff->masking = masking; + iff->transparency = transparency; + + if (!st->codec->extradata) { + st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE; + st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); + if (!st->codec->extradata) + return AVERROR(ENOMEM); + } + buf = st->codec->extradata; + bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); + bytestream_put_byte(&buf, iff->compression); + bytestream_put_byte(&buf, iff->bpp); + bytestream_put_byte(&buf, iff->ham); + bytestream_put_byte(&buf, iff->flags); + bytestream_put_be16(&buf, iff->transparency); + bytestream_put_byte(&buf, iff->masking); + switch (compression) { case BITMAP_RAW: st->codec->codec_id = CODEC_ID_IFF_ILBM; @@ -293,7 +349,15 @@ static int iff_read_packet(AVFormatContext *s, } interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE); } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = av_get_packet(pb, pkt, iff->body_size); + uint8_t *buf; + + if (av_new_packet(pkt, iff->body_size + 2) < 0) { + return AVERROR(ENOMEM); + } + + buf = pkt->data; + bytestream_put_be16(&buf, 2); + ret = avio_read(pb, buf, iff->body_size); } else { ret = av_get_packet(pb, pkt, PACKET_SIZE); } |