diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-07-19 23:31:04 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-07-19 23:31:04 +0200 |
commit | e4c00aca966e0b22777f3d2d6fe9c993151cc5f8 (patch) | |
tree | 4116ad4fe097fbc05a87e40ed73e9b1b6a4e6fdc /libavformat | |
parent | a8d8e868c6154f63a9229f913434aaa21833e488 (diff) | |
parent | eeb55f5f2f48dba3cb4530e9c65999471affe26e (diff) | |
download | ffmpeg-e4c00aca966e0b22777f3d2d6fe9c993151cc5f8.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master: (38 commits)
alac: cosmetics: general pretty-printing and comment clean up
alac: calculate buffer size outside the loop in allocate_buffers()
alac: change some data types to plain int
alac: cosmetics: rename some variables and function names
alac: multi-channel decoding support
alac: split element parsing into a separate function
alac: support a read sample size of up to 32
alac: output in planar sample format
alac: add 32-bit decoding support
alac: simplify channel interleaving
alac: use AVPacket fields directly in alac_decode_frame()
alac: fix check for valid max_samples_per_frame
alac: use get_sbits() to read LPC coefficients instead of casting
alac: move the current samples per frame to the ALACContext
alac: avoid using a double-negative when checking if the frame is compressed
alac: factor out output_size check in predictor_decompress_fir_adapt()
alac: factor out loading of next decoded sample in LPC prediction
alac: use index into buffer_out instead of incrementing the pointer
alac: simplify lpc coefficient adaptation
alac: reduce the number of local variables needed in lpc prediction
...
Conflicts:
libavcodec/alac.c
libavformat/cafdec.c
libavformat/mov.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/aiffdec.c | 3 | ||||
-rw-r--r-- | libavformat/cafdec.c | 61 | ||||
-rw-r--r-- | libavformat/isom.c | 16 | ||||
-rw-r--r-- | libavformat/isom.h | 2 | ||||
-rw-r--r-- | libavformat/mov.c | 41 | ||||
-rw-r--r-- | libavformat/mov_chan.c | 46 | ||||
-rw-r--r-- | libavformat/mov_chan.h | 19 |
7 files changed, 109 insertions, 79 deletions
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 3382e8a4c1..f89ed93dd5 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -275,9 +275,8 @@ static int aiff_read_header(AVFormatContext *s) avio_read(pb, st->codec->extradata, size); break; case MKTAG('C','H','A','N'): - if (size < 12) + if(ff_mov_read_chan(s, st, size) < 0) return AVERROR_INVALIDDATA; - ff_mov_read_chan(s, size, st->codec); break; default: /* Jump */ if (size & 1) /* Always even aligned */ diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 6fad878566..0dacf2c4f1 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -29,6 +29,7 @@ #include "internal.h" #include "riff.h" #include "isom.h" +#include "mov_chan.h" #include "libavutil/intreadwrite.h" #include "libavutil/intfloat.h" #include "libavutil/dict.h" @@ -122,27 +123,39 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) #define ALAC_PREAMBLE 12 #define ALAC_HEADER 36 #define ALAC_NEW_KUKI 24 - if (size == ALAC_NEW_KUKI) { - st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - memcpy(st->codec->extradata, "\0\0\0\24alac", 8); - avio_read(pb, st->codec->extradata + ALAC_HEADER - ALAC_NEW_KUKI, ALAC_NEW_KUKI); - st->codec->extradata_size = ALAC_HEADER; - } else { + uint8_t preamble[12]; + if (size < ALAC_NEW_KUKI || size > ALAC_PREAMBLE + ALAC_HEADER) { + av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); + avio_skip(pb, size); + return AVERROR_INVALIDDATA; + } + avio_read(pb, preamble, ALAC_PREAMBLE); + + st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE); + if (!st->codec->extradata) + return AVERROR(ENOMEM); + + /* For the old style cookie, we skip 12 bytes, then read 36 bytes. + * The new style cookie only contains the last 24 bytes of what was + * 36 bytes in the old style cookie, so we fabricate the first 12 bytes + * in that case to maintain compatibility. */ + if (!memcmp(&preamble[4], "frmaalac", 8)) { if (size < ALAC_PREAMBLE + ALAC_HEADER) { av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); - avio_skip(pb, size); + av_freep(&st->codec->extradata); return AVERROR_INVALIDDATA; } - avio_skip(pb, ALAC_PREAMBLE); - st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); avio_read(pb, st->codec->extradata, ALAC_HEADER); - st->codec->extradata_size = ALAC_HEADER; avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER); + } else { + AV_WB32(st->codec->extradata, 36); + memcpy(&st->codec->extradata[4], "alac", 4); + AV_WB32(&st->codec->extradata[8], 0); + memcpy(&st->codec->extradata[12], preamble, 12); + avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12); + avio_skip(pb, size - ALAC_NEW_KUKI); } + st->codec->extradata_size = ALAC_HEADER; } else { st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) @@ -160,8 +173,8 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) AVIOContext *pb = s->pb; AVStream *st = s->streams[0]; CaffContext *caf = s->priv_data; - int64_t pos = 0, ccount; - int num_packets, i; + int64_t pos = 0, ccount, num_packets; + int i; ccount = avio_tell(pb); @@ -180,10 +193,11 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); } - if (avio_tell(pb) - ccount != size) { + if (avio_tell(pb) - ccount > size) { av_log(s, AV_LOG_ERROR, "error reading packet table\n"); - return -1; + return AVERROR_INVALIDDATA; } + avio_skip(pb, ccount + size - avio_tell(pb)); caf->num_bytes = pos; return 0; @@ -253,6 +267,11 @@ static int read_header(AVFormatContext *s) found_data = 1; break; + case MKBETAG('c','h','a','n'): + if ((ret = ff_mov_read_chan(s, st, size)) < 0) + return ret; + break; + /* magic cookie chunk */ case MKBETAG('k','u','k','i'): if (read_kuki_chunk(s, size)) @@ -269,12 +288,6 @@ static int read_header(AVFormatContext *s) read_info_chunk(s, size); break; - case MKBETAG('c','h','a','n'): - if (size < 12) - return AVERROR_INVALIDDATA; - ff_mov_read_chan(s, size, st->codec); - break; - default: #define _(x) ((x) >= ' ' ? (x) : ' ') av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n", diff --git a/libavformat/isom.c b/libavformat/isom.c index bcd5894f0a..c110b7f6fa 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -499,25 +499,30 @@ static const MovChannelLayout mov_channel_layout[] = { { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11 { 0, 0}, }; - -void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec) +#if 0 +int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size) { + AVCodecContext *codec= st->codec; uint32_t layout_tag; AVIOContext *pb = s->pb; const MovChannelLayout *layouts = mov_channel_layout; + + if (size < 12) + return AVERROR_INVALIDDATA; + layout_tag = avio_rb32(pb); size -= 4; if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions // Channel descriptions not implemented av_log_ask_for_sample(s, "Unimplemented container channel layout.\n"); avio_skip(pb, size); - return; + return 0; } if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap codec->channel_layout = avio_rb32(pb); size -= 4; avio_skip(pb, size); - return; + return 0; } while (layouts->channel_layout) { if (layout_tag == layouts->layout_tag) { @@ -529,7 +534,10 @@ void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec) if (!codec->channel_layout) av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n"); avio_skip(pb, size); + + return 0; } +#endif void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) { diff --git a/libavformat/isom.h b/libavformat/isom.h index f198f70da2..f1cbe8c621 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -197,7 +197,7 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom); enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags); int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries); -void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec); +int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size); void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout); #endif /* AVFORMAT_ISOM_H */ diff --git a/libavformat/mov.c b/libavformat/mov.c index 0acebc21f1..b4295f8948 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -597,10 +597,6 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; - uint8_t av_unused version; - uint32_t av_unused flags; - uint32_t layout_tag, bitmap, num_descr, label_mask; - int i; if (c->fc->nb_streams < 1) return 0; @@ -609,40 +605,7 @@ static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (atom.size < 16) return 0; - version = avio_r8(pb); - flags = avio_rb24(pb); - - layout_tag = avio_rb32(pb); - bitmap = avio_rb32(pb); - num_descr = avio_rb32(pb); - - if (atom.size < 16ULL + num_descr * 20ULL) - return 0; - - av_dlog(c->fc, "chan: size=%" PRId64 " version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n", - atom.size, version, flags, layout_tag, bitmap, num_descr); - - label_mask = 0; - for (i = 0; i < num_descr; i++) { - uint32_t label; - label = avio_rb32(pb); // mChannelLabel - avio_rb32(pb); // mChannelFlags - avio_rl32(pb); // mCoordinates[0] - avio_rl32(pb); // mCoordinates[1] - avio_rl32(pb); // mCoordinates[2] - if (layout_tag == 0) { - uint32_t mask_incr = ff_mov_get_channel_label(label); - if (mask_incr == 0) { - label_mask = 0; - break; - } - label_mask |= mask_incr; - } - } - if (layout_tag == 0) - st->codec->channel_layout = label_mask; - else - st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); + ff_mov_read_chan(c->fc, st, atom.size - 4); return 0; } @@ -2556,7 +2519,7 @@ static int mov_read_chan2(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (atom.size < 16) return 0; avio_skip(pb, 4); - ff_mov_read_chan(c->fc, atom.size - 4, c->fc->streams[0]->codec); + ff_mov_read_chan(c->fc,c->fc->streams[0], atom.size - 4); return 0; } diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index edd5f6c4da..c0b57119d1 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -477,7 +477,7 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) return layout_map[i].layout; } -uint32_t ff_mov_get_channel_label(uint32_t label) +static uint32_t mov_get_channel_label(uint32_t label) { if (label == 0) return 0; @@ -542,3 +542,47 @@ uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, return tag; } + +int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size) +{ + AVIOContext *pb = s->pb; + uint32_t layout_tag, bitmap, num_descr, label_mask; + int i; + + if (size < 12) + return AVERROR_INVALIDDATA; + + layout_tag = avio_rb32(pb); + bitmap = avio_rb32(pb); + num_descr = avio_rb32(pb); + + av_dlog(s, "chan: layout=%u bitmap=%u num_descr=%u\n", + layout_tag, bitmap, num_descr); + + if (size < 12ULL + num_descr * 20ULL) + return 0; + + label_mask = 0; + for (i = 0; i < num_descr; i++) { + uint32_t label; + label = avio_rb32(pb); // mChannelLabel + avio_rb32(pb); // mChannelFlags + avio_rl32(pb); // mCoordinates[0] + avio_rl32(pb); // mCoordinates[1] + avio_rl32(pb); // mCoordinates[2] + if (layout_tag == 0) { + uint32_t mask_incr = mov_get_channel_label(label); + if (mask_incr == 0) { + label_mask = 0; + break; + } + label_mask |= mask_incr; + } + } + if (layout_tag == 0) + st->codec->channel_layout = label_mask; + else + st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); + + return 0; +} diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h index bd6adf6ad4..0897cd92dd 100644 --- a/libavformat/mov_chan.h +++ b/libavformat/mov_chan.h @@ -29,6 +29,7 @@ #include <stdint.h> #include "libavcodec/avcodec.h" +#include "avformat.h" /** * Get the channel layout for the specified channel layout tag. @@ -40,14 +41,6 @@ uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap); /** - * Get the channel layout for the specified channel label. - * - * @param[in] label channel label - * @return channel layout mask fragment - */ -uint32_t ff_mov_get_channel_label(uint32_t label); - -/** * Get the channel layout tag for the specified codec id and channel layout. * If the layout tag was not found, use a channel bitmap if possible. * @@ -60,4 +53,14 @@ uint32_t ff_mov_get_channel_layout_tag(enum CodecID codec_id, uint64_t channel_layout, uint32_t *bitmap); +/** + * Read 'chan' tag from the input stream. + * + * @param s AVFormatContext + * @param st The stream to set codec values for + * @param size Remaining size in the 'chan' tag + * @return 0 if ok, or negative AVERROR code on failure + */ +int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size); + #endif /* AVFORMAT_MOV_CHAN_H */ |