return x;
}
- static int bastardized_rice_decompress(ALACContext *alac,
- int32_t *output_buffer,
- int output_size,
- int readsamplesize, /* arg_10 */
- int rice_initialhistory, /* arg424->b */
- int rice_kmodifier, /* arg424->d */
- int rice_historymult, /* arg424->c */
- int rice_kmodifier_mask /* arg424->e */
- )
-static void rice_decompress(ALACContext *alac, int32_t *output_buffer,
++static int rice_decompress(ALACContext *alac, int32_t *output_buffer,
+ int nb_samples, int bps, int rice_history_mult)
{
- int output_count;
- unsigned int history = rice_initialhistory;
+ int i;
+ unsigned int history = alac->rice_initial_history;
int sign_modifier = 0;
- for (output_count = 0; output_count < output_size; output_count++) {
- int32_t x;
- int32_t x_modified;
- int32_t final_val;
-
- /* standard rice encoding */
- int k; /* size of extra bits */
+ for (i = 0; i < nb_samples; i++) {
+ int k;
+ unsigned int x;
- /* read k, that is bits as is */
+ if(get_bits_left(&alac->gb) <= 0)
+ return -1;
+
+ /* calculate rice param and decode next value */
k = av_log2((history >> 9) + 3);
- x= decode_scalar(&alac->gb, k, rice_kmodifier, readsamplesize);
-
- x_modified = sign_modifier + x;
- final_val = (x_modified + 1) / 2;
- if (x_modified & 1) final_val *= -1;
-
- output_buffer[output_count] = final_val;
-
+ k = FFMIN(k, alac->rice_limit);
+ x = decode_scalar(&alac->gb, k, bps);
+ x += sign_modifier;
sign_modifier = 0;
+ output_buffer[i] = (x >> 1) ^ -(x & 1);
- /* now update the history */
- history += x_modified * rice_historymult
- - ((history * rice_historymult) >> 9);
-
- if (x_modified > 0xffff)
+ /* update the history */
+ if (x > 0xffff)
history = 0xffff;
+ else
+ history += x * rice_history_mult -
+ ((history * rice_history_mult) >> 9);
/* special case: there may be compressed blocks of 0 */
- if ((history < 128) && (output_count+1 < output_size)) {
- int k;
- unsigned int block_size;
+ if ((history < 128) && (i + 1 < nb_samples)) {
+ int block_size;
- sign_modifier = 1;
-
- k = 7 - av_log2(history) + ((history + 16) >> 6 /* / 64 */);
-
- block_size= decode_scalar(&alac->gb, k, rice_kmodifier, 16);
+ /* calculate rice param and decode block size */
+ k = 7 - av_log2(history) + ((history + 16) >> 6);
+ k = FFMIN(k, alac->rice_limit);
+ block_size = decode_scalar(&alac->gb, k, 16);
if (block_size > 0) {
- if(block_size >= output_size - output_count){
- av_log(alac->avctx, AV_LOG_ERROR, "invalid zero block size of %d %d %d\n", block_size, output_size, output_count);
- block_size= output_size - output_count - 1;
+ if (block_size >= nb_samples - i) {
+ av_log(alac->avctx, AV_LOG_ERROR,
+ "invalid zero block size of %d %d %d\n", block_size,
+ nb_samples, i);
+ block_size = nb_samples - i - 1;
}
- memset(&output_buffer[output_count+1], 0, block_size * 4);
- output_count += block_size;
+ memset(&output_buffer[i + 1], 0,
+ block_size * sizeof(*output_buffer));
+ i += block_size;
}
-
- if (block_size > 0xffff)
- sign_modifier = 0;
-
+ if (block_size <= 0xffff)
+ sign_modifier = 1;
history = 0;
}
}
}
if (alac->extra_bits) {
- for (i = 0; i < outputsamples; i++) {
+ for (i = 0; i < alac->nb_samples; i++) {
+ if(get_bits_left(&alac->gb) <= 0)
+ return -1;
for (ch = 0; ch < channels; ch++)
alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits);
}
}
for (ch = 0; ch < channels; ch++) {
- int ret = bastardized_rice_decompress(alac,
- alac->predicterror_buffer[ch],
- outputsamples,
- readsamplesize,
- alac->setinfo_rice_initialhistory,
- alac->setinfo_rice_kmodifier,
- ricemodifier[ch] * alac->setinfo_rice_historymult / 4,
- (1 << alac->setinfo_rice_kmodifier) - 1);
- rice_decompress(alac, alac->predict_error_buffer[ch],
++ int ret=rice_decompress(alac, alac->predict_error_buffer[ch],
+ alac->nb_samples, bps,
+ rice_history_mult[ch] * alac->rice_history_mult / 4);
+ if(ret<0)
+ return ret;
/* adaptive FIR filter */
if (prediction_type[ch] == 15) {
}
} else {
/* not compressed, easy case */
- for (i = 0; i < outputsamples; i++) {
+ for (i = 0; i < alac->nb_samples; i++) {
+ if(get_bits_left(&alac->gb) <= 0)
+ return -1;
for (ch = 0; ch < channels; ch++) {
- alac->outputsamples_buffer[ch][i] = get_sbits_long(&alac->gb,
- alac->setinfo_sample_size);
+ alac->output_samples_buffer[ch][i] =
+ get_sbits_long(&alac->gb, alac->sample_size);
}
}
- alac->extra_bits = 0;
- interlacing_shift = 0;
- interlacing_leftweight = 0;
+ alac->extra_bits = 0;
+ decorr_shift = 0;
+ decorr_left_weight = 0;
}
- if (get_bits(&alac->gb, 3) != 7)
- av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n");
- if (channels == 2 && interlacing_leftweight) {
- decorrelate_stereo(alac->outputsamples_buffer, outputsamples,
- interlacing_shift, interlacing_leftweight);
+ if (channels == 2 && decorr_left_weight) {
+ decorrelate_stereo(alac->output_samples_buffer, alac->nb_samples,
+ decorr_shift, decorr_left_weight);
}
if (alac->extra_bits) {
st->codec->extradata_size = size;
avio_read(pb, st->codec->extradata, size);
break;
- if (size < 12)
+ case MKTAG('C','H','A','N'):
- ff_mov_read_chan(s, size, st->codec);
++ if(ff_mov_read_chan(s, st, size) < 0)
+ return AVERROR_INVALIDDATA;
+ break;
default: /* Jump */
if (size & 1) /* Always even aligned */
size++;
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)\n",
- tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF));
+ av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n",
+ tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size);
#undef _
case MKBETAG('f','r','e','e'):
if (size < 0)
}
return 0;
}
-
- void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec)
+
+typedef struct MovChannelLayout {
+ int64_t channel_layout;
+ uint32_t layout_tag;
+} MovChannelLayout;
+
+static const MovChannelLayout mov_channel_layout[] = {
+ { AV_CH_LAYOUT_MONO, (100<<16) | 1}, // kCAFChannelLayoutTag_Mono
+ { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, // kCAFChannelLayoutTag_Stereo
+ { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, // kCAFChannelLayoutTag_StereoHeadphones
+ { AV_CH_LAYOUT_2_1, (131<<16) | 3}, // kCAFChannelLayoutTag_ITU_2_1
+ { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+ { AV_CH_LAYOUT_2_2, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+ { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, // kCAFChannelLayoutTag_Quadraphonic
+ { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, // kCAFChannelLayoutTag_MPEG_3_0_A
+ { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, // kCAFChannelLayoutTag_MPEG_4_0_A
+ { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+ { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+ { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+ { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+ { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_C
+ { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_A
+ { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8}, // kCAFChannelLayoutTag_SMPTE_DTV
+ { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, // kCAFChannelLayoutTag_DVD_4
+ { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, // kCAFChannelLayoutTag_DVD_5
+ { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+ { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+ { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10
+ { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11
+ { 0, 0},
+};
- return;
++#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 0;
+ }
+ while (layouts->channel_layout) {
+ if (layout_tag == layouts->layout_tag) {
+ codec->channel_layout = layouts->channel_layout;
+ break;
+ }
+ layouts++;
+ }
+ 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)
+{
+ const MovChannelLayout *layouts;
+ uint32_t layout_tag = 0;
+
+ for (layouts = mov_channel_layout; layouts->channel_layout; layouts++)
+ if (channel_layout == layouts->channel_layout) {
+ layout_tag = layouts->layout_tag;
+ break;
+ }
+
+ if (layout_tag) {
+ avio_wb32(pb, layout_tag); // mChannelLayoutTag
+ avio_wb32(pb, 0); // mChannelBitmap
+ } else {
+ avio_wb32(pb, 0x10000); // kCAFChannelLayoutTag_UseChannelBitmap
+ avio_wb32(pb, channel_layout);
+ }
+ avio_wb32(pb, 0); // mNumberChannelDescriptions
+}
+
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 */
return 0;
}
- ff_mov_read_chan(c->fc, atom.size - 4, c->fc->streams[0]->codec);
+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,c->fc->streams[0], atom.size - 4);
+ return 0;
+}
+
+static int mov_read_tref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ uint32_t i, size;
+ MOVStreamContext *sc;
+
+ if (c->fc->nb_streams < 1)
+ return AVERROR_INVALIDDATA;
+ sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+
+ size = avio_rb32(pb);
+ if (size < 12)
+ return 0;
+
+ sc->trefs_count = (size - 4) / 8;
+ sc->trefs = av_malloc(sc->trefs_count * sizeof(*sc->trefs));
+ if (!sc->trefs)
+ return AVERROR(ENOMEM);
+
+ sc->tref_type = avio_rl32(pb);
+ for (i = 0; i < sc->trefs_count; i++)
+ sc->trefs[i] = avio_rb32(pb);
+ return 0;
+}
+
static const MOVParseTableEntry mov_default_parse_table[] = {
-{ MKTAG('a','v','s','s'), mov_read_extradata },
+{ MKTAG('A','P','R','G'), mov_read_aprg },
+{ MKTAG('a','v','s','s'), mov_read_avss },
{ MKTAG('c','h','p','l'), mov_read_chpl },
{ MKTAG('c','o','6','4'), mov_read_stco },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */