Commit e4c00aca authored by Michael Niedermayer's avatar Michael Niedermayer

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents a8d8e868 eeb55f5f
This diff is collapsed.
......@@ -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 */
......
......@@ -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",
......
......@@ -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)
{
......
......@@ -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 */
......@@ -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;
}
......
......@@ -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;
}
......@@ -29,6 +29,7 @@
#include <stdint.h>
#include "libavcodec/avcodec.h"
#include "avformat.h"
/**
* Get the channel layout for the specified channel layout tag.
......@@ -39,14 +40,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 */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment