Update avcodec to 20080825

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27542 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul
2008-09-15 14:00:59 +00:00
parent a191927369
commit 092fe53c23
17 changed files with 6581 additions and 528 deletions
@@ -0,0 +1,175 @@
/*
* Autodesk RLE Decoder
* Copyright (C) 2005 the ffmpeg project
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file aasc.c
* Autodesk RLE Video Decoder by Konstantin Shishkov
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "avcodec.h"
#include "dsputil.h"
typedef struct AascContext {
AVCodecContext *avctx;
AVFrame frame;
} AascContext;
#define FETCH_NEXT_STREAM_BYTE() \
if (stream_ptr >= buf_size) \
{ \
av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (fetch)\n"); \
break; \
} \
stream_byte = buf[stream_ptr++];
static av_cold int aasc_decode_init(AVCodecContext *avctx)
{
AascContext *s = avctx->priv_data;
s->avctx = avctx;
avctx->pix_fmt = PIX_FMT_BGR24;
s->frame.data[0] = NULL;
return 0;
}
static int aasc_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
AascContext *s = avctx->priv_data;
int stream_ptr = 4;
unsigned char rle_code;
unsigned char stream_byte;
int pixel_ptr = 0;
int row_dec, row_ptr;
int frame_size;
int i;
s->frame.reference = 1;
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &s->frame)) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
row_dec = s->frame.linesize[0];
row_ptr = (s->avctx->height - 1) * row_dec;
frame_size = row_dec * s->avctx->height;
while (row_ptr >= 0) {
FETCH_NEXT_STREAM_BYTE();
rle_code = stream_byte;
if (rle_code == 0) {
/* fetch the next byte to see how to handle escape code */
FETCH_NEXT_STREAM_BYTE();
if (stream_byte == 0) {
/* line is done, goto the next one */
row_ptr -= row_dec;
pixel_ptr = 0;
} else if (stream_byte == 1) {
/* decode is done */
break;
} else if (stream_byte == 2) {
/* reposition frame decode coordinates */
FETCH_NEXT_STREAM_BYTE();
pixel_ptr += stream_byte;
FETCH_NEXT_STREAM_BYTE();
row_ptr -= stream_byte * row_dec;
} else {
/* copy pixels from encoded stream */
if ((pixel_ptr + stream_byte > avctx->width * 3) ||
(row_ptr < 0)) {
av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (copy1)\n");
break;
}
rle_code = stream_byte;
if (stream_ptr + rle_code > buf_size) {
av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (copy2)\n");
break;
}
for (i = 0; i < rle_code; i++) {
FETCH_NEXT_STREAM_BYTE();
s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
pixel_ptr++;
}
if (rle_code & 1)
stream_ptr++;
}
} else {
/* decode a run of data */
if ((pixel_ptr + rle_code > avctx->width * 3) ||
(row_ptr < 0)) {
av_log(s->avctx, AV_LOG_ERROR, " AASC: frame ptr just went out of bounds (run1)\n");
break;
}
FETCH_NEXT_STREAM_BYTE();
while(rle_code--) {
s->frame.data[0][row_ptr + pixel_ptr] = stream_byte;
pixel_ptr++;
}
}
}
/* one last sanity check on the way out */
if (stream_ptr < buf_size)
av_log(s->avctx, AV_LOG_ERROR, " AASC: ended frame decode with bytes left over (%d < %d)\n",
stream_ptr, buf_size);
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
/* report that the buffer was completely consumed */
return buf_size;
}
static av_cold int aasc_decode_end(AVCodecContext *avctx)
{
AascContext *s = avctx->priv_data;
/* release the last frame */
if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame);
return 0;
}
AVCodec aasc_decoder = {
"aasc",
CODEC_TYPE_VIDEO,
CODEC_ID_AASC,
sizeof(AascContext),
aasc_decode_init,
NULL,
aasc_decode_end,
aasc_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Autodesk RLE"),
};
@@ -0,0 +1,162 @@
/*
* various filters for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "avcodec.h"
#include "acelp_filters.h"
const int16_t ff_acelp_interp_filter[61] =
{ /* (0.15) */
29443, 28346, 25207, 20449, 14701, 8693,
3143, -1352, -4402, -5865, -5850, -4673,
-2783, -672, 1211, 2536, 3130, 2991,
2259, 1170, 0, -1001, -1652, -1868,
-1666, -1147, -464, 218, 756, 1060,
1099, 904, 550, 135, -245, -514,
-634, -602, -451, -231, 0, 191,
308, 340, 296, 198, 78, -36,
-120, -163, -165, -132, -79, -19,
34, 73, 91, 89, 70, 38,
0,
};
void ff_acelp_interpolate(
int16_t* out,
const int16_t* in,
const int16_t* filter_coeffs,
int precision,
int frac_pos,
int filter_length,
int length)
{
int n, i;
assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision);
for(n=0; n<length; n++)
{
int idx = 0;
int v = 0x4000;
for(i=0; i<filter_length;)
{
/* The reference G.729 and AMR fixed point code performs clipping after
each of the two following accumulations.
Since clipping affects only the synthetic OVERFLOW test without
causing an int type overflow, it was moved outside the loop. */
/* R(x):=ac_v[-k+x]
v += R(n-i)*ff_acelp_interp_filter(t+6i)
v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
v += in[n + i] * filter_coeffs[idx + frac_pos];
idx += precision;
i++;
v += in[n - i] * filter_coeffs[idx - frac_pos];
}
out[n] = av_clip_int16(v >> 15);
}
}
void ff_acelp_convolve_circ(
int16_t* fc_out,
const int16_t* fc_in,
const int16_t* filter,
int len)
{
int i, k;
memset(fc_out, 0, len * sizeof(int16_t));
/* Since there are few pulses over an entire subframe (i.e. almost
all fc_in[i] are zero) it is faster to loop over fc_in first. */
for(i=0; i<len; i++)
{
if(fc_in[i])
{
for(k=0; k<i; k++)
fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
for(k=i; k<len; k++)
fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
}
}
}
int ff_acelp_lp_synthesis_filter(
int16_t *out,
const int16_t* filter_coeffs,
const int16_t* in,
int buffer_length,
int filter_length,
int stop_on_overflow,
int rounder)
{
int i,n;
// These two lines are to avoid a -1 subtraction in the main loop
filter_length++;
filter_coeffs--;
for(n=0; n<buffer_length; n++)
{
int sum = rounder;
for(i=1; i<filter_length; i++)
sum -= filter_coeffs[i] * out[n-i];
sum = (sum >> 12) + in[n];
if(sum + 0x8000 > 0xFFFFU)
{
if(stop_on_overflow)
return 1;
sum = (sum >> 31) ^ 32767;
}
out[n] = sum;
}
return 0;
}
void ff_acelp_high_pass_filter(
int16_t* out,
int hpf_f[2],
const int16_t* in,
int length)
{
int i;
int tmp;
for(i=0; i<length; i++)
{
tmp = (hpf_f[0]* 15836LL)>>13; /* (14.13) = (13.13) * (1.13) */
tmp += (hpf_f[1]* -7667LL)>>13; /* (13.13) = (13.13) * (0.13) */
tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); /* (14.13) = (0.13) * (14.0) */
out[i] = av_clip_int16((tmp + 0x800) >> 12); /* (15.0) = 2 * (13.13) = (14.13) */
hpf_f[1] = hpf_f[0];
hpf_f[0] = tmp;
}
}
@@ -0,0 +1,197 @@
/*
* Various fixed-point math operations
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include <limits.h>
#include <assert.h>
#include "avcodec.h"
#include "acelp_math.h"
#ifdef G729_BITEXACT
/**
* Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64)
*/
static const int16_t base_cos[64] =
{
32767, 32729, 32610, 32413, 32138, 31786, 31357, 30853,
30274, 29622, 28899, 28106, 27246, 26320, 25330, 24279,
23170, 22006, 20788, 19520, 18205, 16846, 15447, 14010,
12540, 11039, 9512, 7962, 6393, 4808, 3212, 1608,
0, -1608, -3212, -4808, -6393, -7962, -9512, -11039,
-12540, -14010, -15447, -16846, -18205, -19520, -20788, -22006,
-23170, -24279, -25330, -26320, -27246, -28106, -28899, -29622,
-30274, -30853, -31357, -31786, -32138, -32413, -32610, -32729
};
/**
* Slope used to compute cos(x)
*
* cos(ind*64+offset) = base_cos[ind]+offset*slope_cos[ind]
* values multiplied by 1<<19
*/
static const int16_t slope_cos[64] =
{
-632, -1893, -3150, -4399, -5638, -6863, -8072, -9261,
-10428, -11570, -12684, -13767, -14817, -15832, -16808, -17744,
-18637, -19486, -20287, -21039, -21741, -22390, -22986, -23526,
-24009, -24435, -24801, -25108, -25354, -25540, -25664, -25726,
-25726, -25664, -25540, -25354, -25108, -24801, -24435, -24009,
-23526, -22986, -22390, -21741, -21039, -20287, -19486, -18637,
-17744, -16808, -15832, -14817, -13767, -12684, -11570, -10428,
-9261, -8072, -6863, -5638, -4399, -3150, -1893, -632
};
/**
* Table used to compute exp2(x)
*
* tab_exp2[i] = (1<<14) * exp2(i/32) = 2^(i/32) i=0..32
*/
static const uint16_t tab_exp2[33] =
{
16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
31379, 32066, 32767
};
int16_t ff_cos(uint16_t arg)
{
uint8_t offset= arg;
uint8_t ind = arg >> 8;
assert(arg < 0x4000);
return FFMAX(base_cos[ind] + ((slope_cos[ind] * offset) >> 12), -0x8000);
}
int ff_exp2(uint16_t power)
{
uint16_t frac_x0;
uint16_t frac_dx;
int result;
assert(power <= 0x7fff);
frac_x0 = power >> 10;
frac_dx = (power & 0x03ff) << 5;
result = tab_exp2[frac_x0] << 15;
result += frac_dx * (tab_exp2[frac_x0+1] - tab_exp2[frac_x0]);
return result >> 10;
}
#else // G729_BITEXACT
/**
* Cosine table: base_cos[i] = (1<<15) * cos(i*PI/64)
*/
static const int16_t tab_cos[65] =
{
32767, 32738, 32617, 32421, 32145, 31793, 31364, 30860,
30280, 29629, 28905, 28113, 27252, 26326, 25336, 24285,
23176, 22011, 20793, 19525, 18210, 16851, 15451, 14014,
12543, 11043, 9515, 7965, 6395, 4810, 3214, 1609,
1, -1607, -3211, -4808, -6393, -7962, -9513, -11040,
-12541, -14012, -15449, -16848, -18207, -19523, -20791, -22009,
-23174, -24283, -25334, -26324, -27250, -28111, -28904, -29627,
-30279, -30858, -31363, -31792, -32144, -32419, -32616, -32736, -32768,
};
static const uint16_t exp2a[]=
{
0, 1435, 2901, 4400, 5931, 7496, 9096, 10730,
12400, 14106, 15850, 17632, 19454, 21315, 23216, 25160,
27146, 29175, 31249, 33368, 35534, 37747, 40009, 42320,
44682, 47095, 49562, 52082, 54657, 57289, 59979, 62727,
};
static const uint16_t exp2b[]=
{
3, 712, 1424, 2134, 2845, 3557, 4270, 4982,
5696, 6409, 7124, 7839, 8554, 9270, 9986, 10704,
11421, 12138, 12857, 13576, 14295, 15014, 15734, 16455,
17176, 17898, 18620, 19343, 20066, 20790, 21514, 22238,
};
int16_t ff_cos(uint16_t arg)
{
uint8_t offset= arg;
uint8_t ind = arg >> 8;
assert(arg <= 0x3fff);
return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8);
}
int ff_exp2(uint16_t power)
{
unsigned int result= exp2a[power>>10] + 0x10000;
assert(arg <= 0x7fff);
result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17);
return result + ((result*(power&31)*89)>>22);
}
#endif // else G729_BITEXACT
/**
* Table used to compute log2(x)
*
* tab_log2[i] = (1<<15) * log2(1 + i/32), i=0..32
*/
static const uint16_t tab_log2[33] =
{
#ifdef G729_BITEXACT
0, 1455, 2866, 4236, 5568, 6863, 8124, 9352,
10549, 11716, 12855, 13967, 15054, 16117, 17156, 18172,
19167, 20142, 21097, 22033, 22951, 23852, 24735, 25603,
26455, 27291, 28113, 28922, 29716, 30497, 31266, 32023, 32767,
#else
4, 1459, 2870, 4240, 5572, 6867, 8127, 9355,
10552, 11719, 12858, 13971, 15057, 16120, 17158, 18175,
19170, 20145, 21100, 22036, 22954, 23854, 24738, 25605,
26457, 27294, 28116, 28924, 29719, 30500, 31269, 32025, 32769,
#endif
};
int ff_log2(uint32_t value)
{
uint8_t power_int;
uint8_t frac_x0;
uint16_t frac_dx;
// Stripping zeros from beginning
power_int = av_log2(value);
value <<= (31 - power_int);
// b31 is always non-zero now
frac_x0 = (value & 0x7c000000) >> 26; // b26-b31 and [32..63] -> [0..31]
frac_dx = (value & 0x03fff800) >> 11;
value = tab_log2[frac_x0];
value += (frac_dx * (tab_log2[frac_x0+1] - tab_log2[frac_x0])) >> 15;
return (power_int << 15) + value;
}
@@ -0,0 +1,119 @@
/*
* gain code, gain pitch and pitch delay decoding
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "acelp_pitch_delay.h"
#include "acelp_math.h"
int ff_acelp_decode_8bit_to_1st_delay3(int ac_index)
{
ac_index += 58;
if(ac_index > 254)
ac_index = 3 * ac_index - 510;
return ac_index;
}
int ff_acelp_decode_4bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min)
{
if(ac_index < 4)
return 3 * (ac_index + pitch_delay_min);
else if(ac_index < 12)
return 3 * pitch_delay_min + ac_index + 6;
else
return 3 * (ac_index + pitch_delay_min) - 18;
}
int ff_acelp_decode_5_6_bit_to_2nd_delay3(
int ac_index,
int pitch_delay_min)
{
return 3 * pitch_delay_min + ac_index - 2;
}
int ff_acelp_decode_9bit_to_1st_delay6(int ac_index)
{
if(ac_index < 463)
return ac_index + 105;
else
return 6 * (ac_index - 368);
}
int ff_acelp_decode_6bit_to_2nd_delay6(
int ac_index,
int pitch_delay_min)
{
return 6 * pitch_delay_min + ac_index - 3;
}
void ff_acelp_update_past_gain(
int16_t* quant_energy,
int gain_corr_factor,
int log2_ma_pred_order,
int erasure)
{
int i;
int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10)
for(i=(1 << log2_ma_pred_order) - 1; i>0; i--)
{
avg_gain += quant_energy[i-1];
quant_energy[i] = quant_energy[i-1];
}
if(erasure)
quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10)
else
quant_energy[0] = (6165 * ((ff_log2(gain_corr_factor) >> 2) - (13 << 13))) >> 13;
}
int16_t ff_acelp_decode_gain_code(
int gain_corr_factor,
const int16_t* fc_v,
int mr_energy,
const int16_t* quant_energy,
const int16_t* ma_prediction_coeff,
int subframe_size,
int ma_pred_order)
{
int i;
mr_energy <<= 10;
for(i=0; i<ma_pred_order; i++)
mr_energy += quant_energy[i] * ma_prediction_coeff[i];
#ifdef G729_BITEXACT
mr_energy += (((-6165LL * ff_log2(dot_product(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff);
mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23)
return bidir_sal(
((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
(mr_energy >> 15) - 25
);
#else
mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
sqrt(dot_product(fc_v, fc_v, subframe_size, 0));
return mr_energy >> 12;
#endif
}
@@ -0,0 +1,147 @@
/*
* adaptive and fixed codebook vector operations for ACELP-based codecs
*
* Copyright (c) 2008 Vladimir Voroshilov
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <inttypes.h>
#include "avcodec.h"
#include "acelp_vectors.h"
const uint8_t ff_fc_2pulses_9bits_track1[16] =
{
1, 3,
6, 8,
11, 13,
16, 18,
21, 23,
26, 28,
31, 33,
36, 38
};
const uint8_t ff_fc_2pulses_9bits_track1_gray[16] =
{
1, 3,
8, 6,
18, 16,
11, 13,
38, 36,
31, 33,
21, 23,
28, 26,
};
const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
{
0, 2,
5, 4,
12, 10,
7, 9,
25, 24,
20, 22,
14, 15,
19, 17,
36, 31,
21, 26,
1, 6,
16, 11,
27, 29,
32, 30,
39, 37,
34, 35,
};
const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
{
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
};
const uint8_t ff_fc_4pulses_8bits_track_4[32] =
{
3, 4,
8, 9,
13, 14,
18, 19,
23, 24,
28, 29,
33, 34,
38, 39,
43, 44,
48, 49,
53, 54,
58, 59,
63, 64,
68, 69,
73, 74,
78, 79,
};
#if 0
static uint8_t gray_decode[32] =
{
0, 1, 3, 2, 7, 6, 4, 5,
15, 14, 12, 13, 8, 9, 11, 10,
31, 30, 28, 29, 24, 25, 27, 26,
16, 17, 19, 18, 23, 22, 20, 21
};
#endif
void ff_acelp_fc_pulse_per_track(
int16_t* fc_v,
const uint8_t *tab1,
const uint8_t *tab2,
int pulse_indexes,
int pulse_signs,
int pulse_count,
int bits)
{
int mask = (1 << bits) - 1;
int i;
for(i=0; i<pulse_count; i++)
{
fc_v[i + tab1[pulse_indexes & mask]] +=
(pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
pulse_indexes >>= bits;
pulse_signs >>= 1;
}
fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192;
}
void ff_acelp_weighted_vector_sum(
int16_t* out,
const int16_t *in_a,
const int16_t *in_b,
int16_t weight_coeff_a,
int16_t weight_coeff_b,
int16_t rounder,
int shift,
int length)
{
int i;
// Clipping required here; breaks OVERFLOW test.
for(i=0; i<length; i++)
out[i] = av_clip_int16((
in_a[i] * weight_coeff_a +
in_b[i] * weight_coeff_b +
rounder) >> shift);
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,176 @@
/*
* ADX ADPCM codecs
* Copyright (c) 2001,2003 BERO
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "adx.h"
/**
* @file adx.c
* SEGA CRI adx codecs.
*
* Reference documents:
* http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
* adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
*/
static av_cold int adx_decode_init(AVCodecContext *avctx)
{
avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
/* 18 bytes <-> 32 samples */
static void adx_decode(short *out,const unsigned char *in,PREV *prev)
{
int scale = AV_RB16(in);
int i;
int s0,s1,s2,d;
// printf("%x ",scale);
in+=2;
s1 = prev->s1;
s2 = prev->s2;
for(i=0;i<16;i++) {
d = in[i];
// d>>=4; if (d&8) d-=16;
d = ((signed char)d >> 4);
s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
s2 = s1;
s1 = av_clip_int16(s0);
*out++=s1;
d = in[i];
//d&=15; if (d&8) d-=16;
d = ((signed char)(d<<4) >> 4);
s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
s2 = s1;
s1 = av_clip_int16(s0);
*out++=s1;
}
prev->s1 = s1;
prev->s2 = s2;
}
static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev)
{
short tmp[32*2];
int i;
adx_decode(tmp ,in ,prev);
adx_decode(tmp+32,in+18,prev+1);
for(i=0;i<32;i++) {
out[i*2] = tmp[i];
out[i*2+1] = tmp[i+32];
}
}
/* return data offset or 0 */
static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize)
{
int offset;
if (buf[0]!=0x80) return 0;
offset = (AV_RB32(buf)^0x80000000)+4;
if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0;
avctx->channels = buf[7];
avctx->sample_rate = AV_RB32(buf+8);
avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
return offset;
}
static int adx_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf0, int buf_size)
{
ADXContext *c = avctx->priv_data;
short *samples = data;
const uint8_t *buf = buf0;
int rest = buf_size;
if (!c->header_parsed) {
int hdrsize = adx_decode_header(avctx,buf,rest);
if (hdrsize==0) return -1;
c->header_parsed = 1;
buf += hdrsize;
rest -= hdrsize;
}
/* 18 bytes of data are expanded into 32*2 bytes of audio,
so guard against buffer overflows */
if(rest/18 > *data_size/64)
rest = (*data_size/64) * 18;
if (c->in_temp) {
int copysize = 18*avctx->channels - c->in_temp;
memcpy(c->dec_temp+c->in_temp,buf,copysize);
rest -= copysize;
buf += copysize;
if (avctx->channels==1) {
adx_decode(samples,c->dec_temp,c->prev);
samples += 32;
} else {
adx_decode_stereo(samples,c->dec_temp,c->prev);
samples += 32*2;
}
}
//
if (avctx->channels==1) {
while(rest>=18) {
adx_decode(samples,buf,c->prev);
rest-=18;
buf+=18;
samples+=32;
}
} else {
while(rest>=18*2) {
adx_decode_stereo(samples,buf,c->prev);
rest-=18*2;
buf+=18*2;
samples+=32*2;
}
}
//
c->in_temp = rest;
if (rest) {
memcpy(c->dec_temp,buf,rest);
buf+=rest;
}
*data_size = (uint8_t*)samples - (uint8_t*)data;
// printf("%d:%d ",buf-buf0,*data_size); fflush(stdout);
return buf-buf0;
}
AVCodec adpcm_adx_decoder = {
"adpcm_adx",
CODEC_TYPE_AUDIO,
CODEC_ID_ADPCM_ADX,
sizeof(ADXContext),
adx_decode_init,
NULL,
NULL,
adx_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX"),
};
@@ -0,0 +1,195 @@
/*
* ADX ADPCM codecs
* Copyright (c) 2001,2003 BERO
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "adx.h"
/**
* @file adx.c
* SEGA CRI adx codecs.
*
* Reference documents:
* http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
* adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
*/
/* 18 bytes <-> 32 samples */
static void adx_encode(unsigned char *adx,const short *wav,PREV *prev)
{
int scale;
int i;
int s0,s1,s2,d;
int max=0;
int min=0;
int data[32];
s1 = prev->s1;
s2 = prev->s2;
for(i=0;i<32;i++) {
s0 = wav[i];
d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL;
data[i]=d;
if (max<d) max=d;
if (min>d) min=d;
s2 = s1;
s1 = s0;
}
prev->s1 = s1;
prev->s2 = s2;
/* -8..+7 */
if (max==0 && min==0) {
memset(adx,0,18);
return;
}
if (max/7>-min/8) scale = max/7;
else scale = -min/8;
if (scale==0) scale=1;
AV_WB16(adx, scale);
for(i=0;i<16;i++) {
adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf);
}
}
static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize)
{
#if 0
struct {
uint32_t offset; /* 0x80000000 + sample start - 4 */
unsigned char unknown1[3]; /* 03 12 04 */
unsigned char channel; /* 1 or 2 */
uint32_t freq;
uint32_t size;
uint32_t unknown2; /* 01 f4 03 00 */
uint32_t unknown3; /* 00 00 00 00 */
uint32_t unknown4; /* 00 00 00 00 */
/* if loop
unknown3 00 15 00 01
unknown4 00 00 00 01
long loop_start_sample;
long loop_start_byte;
long loop_end_sample;
long loop_end_byte;
long
*/
} adxhdr; /* big endian */
/* offset-6 "(c)CRI" */
#endif
AV_WB32(buf+0x00,0x80000000|0x20);
AV_WB32(buf+0x04,0x03120400|avctx->channels);
AV_WB32(buf+0x08,avctx->sample_rate);
AV_WB32(buf+0x0c,0); /* FIXME: set after */
AV_WB32(buf+0x10,0x01040300);
AV_WB32(buf+0x14,0x00000000);
AV_WB32(buf+0x18,0x00000000);
memcpy(buf+0x1c,"\0\0(c)CRI",8);
return 0x20+4;
}
static av_cold int adx_encode_init(AVCodecContext *avctx)
{
if (avctx->channels > 2)
return -1; /* only stereo or mono =) */
avctx->frame_size = 32;
avctx->coded_frame= avcodec_alloc_frame();
avctx->coded_frame->key_frame= 1;
// avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
av_log(avctx, AV_LOG_DEBUG, "adx encode init\n");
return 0;
}
static av_cold int adx_encode_close(AVCodecContext *avctx)
{
av_freep(&avctx->coded_frame);
return 0;
}
static int adx_encode_frame(AVCodecContext *avctx,
uint8_t *frame, int buf_size, void *data)
{
ADXContext *c = avctx->priv_data;
const short *samples = data;
unsigned char *dst = frame;
int rest = avctx->frame_size;
/*
input data size =
ffmpeg.c: do_audio_out()
frame_bytes = enc->frame_size * 2 * enc->channels;
*/
// printf("sz=%d ",buf_size); fflush(stdout);
if (!c->header_parsed) {
int hdrsize = adx_encode_header(avctx,dst,buf_size);
dst+=hdrsize;
c->header_parsed = 1;
}
if (avctx->channels==1) {
while(rest>=32) {
adx_encode(dst,samples,c->prev);
dst+=18;
samples+=32;
rest-=32;
}
} else {
while(rest>=32*2) {
short tmpbuf[32*2];
int i;
for(i=0;i<32;i++) {
tmpbuf[i] = samples[i*2];
tmpbuf[i+32] = samples[i*2+1];
}
adx_encode(dst,tmpbuf,c->prev);
adx_encode(dst+18,tmpbuf+32,c->prev+1);
dst+=18*2;
samples+=32*2;
rest-=32*2;
}
}
return dst-frame;
}
AVCodec adpcm_adx_encoder = {
"adpcm_adx",
CODEC_TYPE_AUDIO,
CODEC_ID_ADPCM_ADX,
sizeof(ADXContext),
adx_encode_init,
adx_encode_frame,
adx_encode_close,
NULL,
.sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX"),
};
@@ -0,0 +1,629 @@
/*
* ALAC (Apple Lossless Audio Codec) decoder
* Copyright (c) 2005 David Hammerton
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file alac.c
* ALAC (Apple Lossless Audio Codec) decoder
* @author 2005 David Hammerton
*
* For more information on the ALAC format, visit:
* http://crazney.net/programs/itunes/alac.html
*
* Note: This decoder expects a 36- (0x24-)byte QuickTime atom to be
* passed through the extradata[_size] fields. This atom is tacked onto
* the end of an 'alac' stsd atom and has the following format:
* bytes 0-3 atom size (0x24), big-endian
* bytes 4-7 atom type ('alac', not the 'alac' tag from start of stsd)
* bytes 8-35 data bytes needed by decoder
*
* Extradata:
* 32bit size
* 32bit tag (=alac)
* 32bit zero?
* 32bit max sample per frame
* 8bit ?? (zero?)
* 8bit sample size
* 8bit history mult
* 8bit initial history
* 8bit kmodifier
* 8bit channels?
* 16bit ??
* 32bit max coded frame size
* 32bit bitrate?
* 32bit samplerate
*/
#include "avcodec.h"
#include "bitstream.h"
#include "bytestream.h"
#include "unary.h"
#define ALAC_EXTRADATA_SIZE 36
#define MAX_CHANNELS 2
typedef struct {
AVCodecContext *avctx;
GetBitContext gb;
/* init to 0; first frame decode should initialize from extradata and
* set this to 1 */
int context_initialized;
int numchannels;
int bytespersample;
/* buffers */
int32_t *predicterror_buffer[MAX_CHANNELS];
int32_t *outputsamples_buffer[MAX_CHANNELS];
/* stuff from setinfo */
uint32_t setinfo_max_samples_per_frame; /* 0x1000 = 4096 */ /* max samples per frame? */
uint8_t setinfo_sample_size; /* 0x10 */
uint8_t setinfo_rice_historymult; /* 0x28 */
uint8_t setinfo_rice_initialhistory; /* 0x0a */
uint8_t setinfo_rice_kmodifier; /* 0x0e */
/* end setinfo stuff */
} ALACContext;
static void allocate_buffers(ALACContext *alac)
{
int chan;
for (chan = 0; chan < MAX_CHANNELS; chan++) {
alac->predicterror_buffer[chan] =
av_malloc(alac->setinfo_max_samples_per_frame * 4);
alac->outputsamples_buffer[chan] =
av_malloc(alac->setinfo_max_samples_per_frame * 4);
}
}
static int alac_set_info(ALACContext *alac)
{
const unsigned char *ptr = alac->avctx->extradata;
ptr += 4; /* size */
ptr += 4; /* alac */
ptr += 4; /* 0 ? */
if(AV_RB32(ptr) >= UINT_MAX/4){
av_log(alac->avctx, AV_LOG_ERROR, "setinfo_max_samples_per_frame too large\n");
return -1;
}
/* buffer size / 2 ? */
alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr);
ptr++; /* ??? */
alac->setinfo_sample_size = *ptr++;
if (alac->setinfo_sample_size > 32) {
av_log(alac->avctx, AV_LOG_ERROR, "setinfo_sample_size too large\n");
return -1;
}
alac->setinfo_rice_historymult = *ptr++;
alac->setinfo_rice_initialhistory = *ptr++;
alac->setinfo_rice_kmodifier = *ptr++;
ptr++; /* channels? */
bytestream_get_be16(&ptr); /* ??? */
bytestream_get_be32(&ptr); /* max coded frame size */
bytestream_get_be32(&ptr); /* bitrate ? */
bytestream_get_be32(&ptr); /* samplerate */
allocate_buffers(alac);
return 0;
}
static inline int decode_scalar(GetBitContext *gb, int k, int limit, int readsamplesize){
/* read x - number of 1s before 0 represent the rice */
int x = get_unary_0_9(gb);
if (x > 8) { /* RICE THRESHOLD */
/* use alternative encoding */
x = get_bits(gb, readsamplesize);
} else {
if (k >= limit)
k = limit;
if (k != 1) {
int extrabits = show_bits(gb, k);
/* multiply x by 2^k - 1, as part of their strange algorithm */
x = (x << k) - x;
if (extrabits > 1) {
x += extrabits - 1;
skip_bits(gb, k);
} else
skip_bits(gb, k - 1);
}
}
return x;
}
static void 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 */
)
{
int output_count;
unsigned int history = rice_initialhistory;
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 */
/* read k, that is bits as is */
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;
sign_modifier = 0;
/* now update the history */
history += x_modified * rice_historymult
- ((history * rice_historymult) >> 9);
if (x_modified > 0xffff)
history = 0xffff;
/* special case: there may be compressed blocks of 0 */
if ((history < 128) && (output_count+1 < output_size)) {
int k;
unsigned 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);
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;
}
memset(&output_buffer[output_count+1], 0, block_size * 4);
output_count += block_size;
}
if (block_size > 0xffff)
sign_modifier = 0;
history = 0;
}
}
}
static inline int32_t extend_sign32(int32_t val, int bits)
{
return (val << (32 - bits)) >> (32 - bits);
}
static inline int sign_only(int v)
{
return v ? FFSIGN(v) : 0;
}
static void predictor_decompress_fir_adapt(int32_t *error_buffer,
int32_t *buffer_out,
int output_size,
int readsamplesize,
int16_t *predictor_coef_table,
int predictor_coef_num,
int predictor_quantitization)
{
int i;
/* first sample always copies */
*buffer_out = *error_buffer;
if (!predictor_coef_num) {
if (output_size <= 1)
return;
memcpy(buffer_out+1, error_buffer+1, (output_size-1) * 4);
return;
}
if (predictor_coef_num == 0x1f) { /* 11111 - max value of predictor_coef_num */
/* second-best case scenario for fir decompression,
* error describes a small difference from the previous sample only
*/
if (output_size <= 1)
return;
for (i = 0; i < output_size - 1; i++) {
int32_t prev_value;
int32_t error_value;
prev_value = buffer_out[i];
error_value = error_buffer[i+1];
buffer_out[i+1] =
extend_sign32((prev_value + error_value), readsamplesize);
}
return;
}
/* read warm-up samples */
if (predictor_coef_num > 0)
for (i = 0; i < predictor_coef_num; i++) {
int32_t val;
val = buffer_out[i] + error_buffer[i+1];
val = extend_sign32(val, readsamplesize);
buffer_out[i+1] = val;
}
#if 0
/* 4 and 8 are very common cases (the only ones i've seen). these
* should be unrolled and optimized
*/
if (predictor_coef_num == 4) {
/* FIXME: optimized general case */
return;
}
if (predictor_coef_table == 8) {
/* FIXME: optimized general case */
return;
}
#endif
/* general case */
if (predictor_coef_num > 0) {
for (i = predictor_coef_num + 1; i < output_size; i++) {
int j;
int sum = 0;
int outval;
int error_val = error_buffer[i];
for (j = 0; j < predictor_coef_num; j++) {
sum += (buffer_out[predictor_coef_num-j] - buffer_out[0]) *
predictor_coef_table[j];
}
outval = (1 << (predictor_quantitization-1)) + sum;
outval = outval >> predictor_quantitization;
outval = outval + buffer_out[0] + error_val;
outval = extend_sign32(outval, readsamplesize);
buffer_out[predictor_coef_num+1] = outval;
if (error_val > 0) {
int predictor_num = predictor_coef_num - 1;
while (predictor_num >= 0 && error_val > 0) {
int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num];
int sign = sign_only(val);
predictor_coef_table[predictor_num] -= sign;
val *= sign; /* absolute value */
error_val -= ((val >> predictor_quantitization) *
(predictor_coef_num - predictor_num));
predictor_num--;
}
} else if (error_val < 0) {
int predictor_num = predictor_coef_num - 1;
while (predictor_num >= 0 && error_val < 0) {
int val = buffer_out[0] - buffer_out[predictor_coef_num - predictor_num];
int sign = - sign_only(val);
predictor_coef_table[predictor_num] -= sign;
val *= sign; /* neg value */
error_val -= ((val >> predictor_quantitization) *
(predictor_coef_num - predictor_num));
predictor_num--;
}
}
buffer_out++;
}
}
}
static void reconstruct_stereo_16(int32_t *buffer[MAX_CHANNELS],
int16_t *buffer_out,
int numchannels, int numsamples,
uint8_t interlacing_shift,
uint8_t interlacing_leftweight)
{
int i;
if (numsamples <= 0)
return;
/* weighted interlacing */
if (interlacing_leftweight) {
for (i = 0; i < numsamples; i++) {
int32_t a, b;
a = buffer[0][i];
b = buffer[1][i];
a -= (b * interlacing_leftweight) >> interlacing_shift;
b += a;
buffer_out[i*numchannels] = b;
buffer_out[i*numchannels + 1] = a;
}
return;
}
/* otherwise basic interlacing took place */
for (i = 0; i < numsamples; i++) {
int16_t left, right;
left = buffer[0][i];
right = buffer[1][i];
buffer_out[i*numchannels] = left;
buffer_out[i*numchannels + 1] = right;
}
}
static int alac_decode_frame(AVCodecContext *avctx,
void *outbuffer, int *outputsize,
const uint8_t *inbuffer, int input_buffer_size)
{
ALACContext *alac = avctx->priv_data;
int channels;
unsigned int outputsamples;
int hassize;
unsigned int readsamplesize;
int wasted_bytes;
int isnotcompressed;
uint8_t interlacing_shift;
uint8_t interlacing_leftweight;
/* short-circuit null buffers */
if (!inbuffer || !input_buffer_size)
return input_buffer_size;
/* initialize from the extradata */
if (!alac->context_initialized) {
if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) {
av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n",
ALAC_EXTRADATA_SIZE);
return input_buffer_size;
}
if (alac_set_info(alac)) {
av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n");
return input_buffer_size;
}
alac->context_initialized = 1;
}
init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8);
channels = get_bits(&alac->gb, 3) + 1;
if (channels > MAX_CHANNELS) {
av_log(avctx, AV_LOG_ERROR, "channels > %d not supported\n",
MAX_CHANNELS);
return input_buffer_size;
}
/* 2^result = something to do with output waiting.
* perhaps matters if we read > 1 frame in a pass?
*/
skip_bits(&alac->gb, 4);
skip_bits(&alac->gb, 12); /* unknown, skip 12 bits */
/* the output sample size is stored soon */
hassize = get_bits1(&alac->gb);
wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */
/* whether the frame is compressed */
isnotcompressed = get_bits1(&alac->gb);
if (hassize) {
/* now read the number of samples as a 32bit integer */
outputsamples = get_bits_long(&alac->gb, 32);
if(outputsamples > alac->setinfo_max_samples_per_frame){
av_log(avctx, AV_LOG_ERROR, "outputsamples %d > %d\n", outputsamples, alac->setinfo_max_samples_per_frame);
return -1;
}
} else
outputsamples = alac->setinfo_max_samples_per_frame;
if(outputsamples > *outputsize / alac->bytespersample){
av_log(avctx, AV_LOG_ERROR, "sample buffer too small\n");
return -1;
}
*outputsize = outputsamples * alac->bytespersample;
readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + channels - 1;
if (readsamplesize > MIN_CACHE_BITS) {
av_log(avctx, AV_LOG_ERROR, "readsamplesize too big (%d)\n", readsamplesize);
return -1;
}
if (!isnotcompressed) {
/* so it is compressed */
int16_t predictor_coef_table[channels][32];
int predictor_coef_num[channels];
int prediction_type[channels];
int prediction_quantitization[channels];
int ricemodifier[channels];
int i, chan;
interlacing_shift = get_bits(&alac->gb, 8);
interlacing_leftweight = get_bits(&alac->gb, 8);
for (chan = 0; chan < channels; chan++) {
prediction_type[chan] = get_bits(&alac->gb, 4);
prediction_quantitization[chan] = get_bits(&alac->gb, 4);
ricemodifier[chan] = get_bits(&alac->gb, 3);
predictor_coef_num[chan] = get_bits(&alac->gb, 5);
/* read the predictor table */
for (i = 0; i < predictor_coef_num[chan]; i++)
predictor_coef_table[chan][i] = (int16_t)get_bits(&alac->gb, 16);
}
if (wasted_bytes)
av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n");
for (chan = 0; chan < channels; chan++) {
bastardized_rice_decompress(alac,
alac->predicterror_buffer[chan],
outputsamples,
readsamplesize,
alac->setinfo_rice_initialhistory,
alac->setinfo_rice_kmodifier,
ricemodifier[chan] * alac->setinfo_rice_historymult / 4,
(1 << alac->setinfo_rice_kmodifier) - 1);
if (prediction_type[chan] == 0) {
/* adaptive fir */
predictor_decompress_fir_adapt(alac->predicterror_buffer[chan],
alac->outputsamples_buffer[chan],
outputsamples,
readsamplesize,
predictor_coef_table[chan],
predictor_coef_num[chan],
prediction_quantitization[chan]);
} else {
av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type[chan]);
/* I think the only other prediction type (or perhaps this is
* just a boolean?) runs adaptive fir twice.. like:
* predictor_decompress_fir_adapt(predictor_error, tempout, ...)
* predictor_decompress_fir_adapt(predictor_error, outputsamples ...)
* little strange..
*/
}
}
} else {
/* not compressed, easy case */
int i, chan;
for (i = 0; i < outputsamples; i++)
for (chan = 0; chan < channels; chan++) {
int32_t audiobits;
audiobits = get_bits_long(&alac->gb, alac->setinfo_sample_size);
audiobits = extend_sign32(audiobits, alac->setinfo_sample_size);
alac->outputsamples_buffer[chan][i] = audiobits;
}
/* wasted_bytes = 0; */
interlacing_shift = 0;
interlacing_leftweight = 0;
}
if (get_bits(&alac->gb, 3) != 7)
av_log(avctx, AV_LOG_ERROR, "Error : Wrong End Of Frame\n");
switch(alac->setinfo_sample_size) {
case 16:
if (channels == 2) {
reconstruct_stereo_16(alac->outputsamples_buffer,
(int16_t*)outbuffer,
alac->numchannels,
outputsamples,
interlacing_shift,
interlacing_leftweight);
} else {
int i;
for (i = 0; i < outputsamples; i++) {
int16_t sample = alac->outputsamples_buffer[0][i];
((int16_t*)outbuffer)[i * alac->numchannels] = sample;
}
}
break;
case 20:
case 24:
// It is not clear if there exist any encoder that creates 24 bit ALAC
// files. iTunes convert 24 bit raw files to 16 bit before encoding.
case 32:
av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size);
break;
default:
break;
}
if (input_buffer_size * 8 - get_bits_count(&alac->gb) > 8)
av_log(avctx, AV_LOG_ERROR, "Error : %d bits left\n", input_buffer_size * 8 - get_bits_count(&alac->gb));
return input_buffer_size;
}
static av_cold int alac_decode_init(AVCodecContext * avctx)
{
ALACContext *alac = avctx->priv_data;
alac->avctx = avctx;
alac->context_initialized = 0;
alac->numchannels = alac->avctx->channels;
alac->bytespersample = (avctx->bits_per_sample / 8) * alac->numchannels;
avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
static av_cold int alac_decode_close(AVCodecContext *avctx)
{
ALACContext *alac = avctx->priv_data;
int chan;
for (chan = 0; chan < MAX_CHANNELS; chan++) {
av_free(alac->predicterror_buffer[chan]);
av_free(alac->outputsamples_buffer[chan]);
}
return 0;
}
AVCodec alac_decoder = {
"alac",
CODEC_TYPE_AUDIO,
CODEC_ID_ALAC,
sizeof(ALACContext),
alac_decode_init,
NULL,
alac_decode_close,
alac_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
};
@@ -0,0 +1,516 @@
/**
* ALAC audio encoder
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
#include "lpc.h"
#define DEFAULT_FRAME_SIZE 4096
#define DEFAULT_SAMPLE_SIZE 16
#define MAX_CHANNELS 8
#define ALAC_EXTRADATA_SIZE 36
#define ALAC_FRAME_HEADER_SIZE 55
#define ALAC_FRAME_FOOTER_SIZE 3
#define ALAC_ESCAPE_CODE 0x1FF
#define ALAC_MAX_LPC_ORDER 30
#define DEFAULT_MAX_PRED_ORDER 6
#define DEFAULT_MIN_PRED_ORDER 4
#define ALAC_MAX_LPC_PRECISION 9
#define ALAC_MAX_LPC_SHIFT 9
#define ALAC_CHMODE_LEFT_RIGHT 0
#define ALAC_CHMODE_LEFT_SIDE 1
#define ALAC_CHMODE_RIGHT_SIDE 2
#define ALAC_CHMODE_MID_SIDE 3
typedef struct RiceContext {
int history_mult;
int initial_history;
int k_modifier;
int rice_modifier;
} RiceContext;
typedef struct LPCContext {
int lpc_order;
int lpc_coeff[ALAC_MAX_LPC_ORDER+1];
int lpc_quant;
} LPCContext;
typedef struct AlacEncodeContext {
int compression_level;
int min_prediction_order;
int max_prediction_order;
int max_coded_frame_size;
int write_sample_size;
int32_t sample_buf[MAX_CHANNELS][DEFAULT_FRAME_SIZE];
int32_t predictor_buf[DEFAULT_FRAME_SIZE];
int interlacing_shift;
int interlacing_leftweight;
PutBitContext pbctx;
RiceContext rc;
LPCContext lpc[MAX_CHANNELS];
DSPContext dspctx;
AVCodecContext *avctx;
} AlacEncodeContext;
static void init_sample_buffers(AlacEncodeContext *s, int16_t *input_samples)
{
int ch, i;
for(ch=0;ch<s->avctx->channels;ch++) {
int16_t *sptr = input_samples + ch;
for(i=0;i<s->avctx->frame_size;i++) {
s->sample_buf[ch][i] = *sptr;
sptr += s->avctx->channels;
}
}
}
static void encode_scalar(AlacEncodeContext *s, int x, int k, int write_sample_size)
{
int divisor, q, r;
k = FFMIN(k, s->rc.k_modifier);
divisor = (1<<k) - 1;
q = x / divisor;
r = x % divisor;
if(q > 8) {
// write escape code and sample value directly
put_bits(&s->pbctx, 9, ALAC_ESCAPE_CODE);
put_bits(&s->pbctx, write_sample_size, x);
} else {
if(q)
put_bits(&s->pbctx, q, (1<<q) - 1);
put_bits(&s->pbctx, 1, 0);
if(k != 1) {
if(r > 0)
put_bits(&s->pbctx, k, r+1);
else
put_bits(&s->pbctx, k-1, 0);
}
}
}
static void write_frame_header(AlacEncodeContext *s, int is_verbatim)
{
put_bits(&s->pbctx, 3, s->avctx->channels-1); // No. of channels -1
put_bits(&s->pbctx, 16, 0); // Seems to be zero
put_bits(&s->pbctx, 1, 1); // Sample count is in the header
put_bits(&s->pbctx, 2, 0); // FIXME: Wasted bytes field
put_bits(&s->pbctx, 1, is_verbatim); // Audio block is verbatim
put_bits(&s->pbctx, 32, s->avctx->frame_size); // No. of samples in the frame
}
static void calc_predictor_params(AlacEncodeContext *s, int ch)
{
int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
int shift[MAX_LPC_ORDER];
int opt_order;
opt_order = ff_lpc_calc_coefs(&s->dspctx, s->sample_buf[ch], s->avctx->frame_size, s->min_prediction_order, s->max_prediction_order,
ALAC_MAX_LPC_PRECISION, coefs, shift, 1, ORDER_METHOD_EST, ALAC_MAX_LPC_SHIFT, 1);
s->lpc[ch].lpc_order = opt_order;
s->lpc[ch].lpc_quant = shift[opt_order-1];
memcpy(s->lpc[ch].lpc_coeff, coefs[opt_order-1], opt_order*sizeof(int));
}
static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
{
int i, best;
int32_t lt, rt;
uint64_t sum[4];
uint64_t score[4];
/* calculate sum of 2nd order residual for each channel */
sum[0] = sum[1] = sum[2] = sum[3] = 0;
for(i=2; i<n; i++) {
lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2];
rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
sum[2] += FFABS((lt + rt) >> 1);
sum[3] += FFABS(lt - rt);
sum[0] += FFABS(lt);
sum[1] += FFABS(rt);
}
/* calculate score for each mode */
score[0] = sum[0] + sum[1];
score[1] = sum[0] + sum[3];
score[2] = sum[1] + sum[3];
score[3] = sum[2] + sum[3];
/* return mode with lowest score */
best = 0;
for(i=1; i<4; i++) {
if(score[i] < score[best]) {
best = i;
}
}
return best;
}
static void alac_stereo_decorrelation(AlacEncodeContext *s)
{
int32_t *left = s->sample_buf[0], *right = s->sample_buf[1];
int i, mode, n = s->avctx->frame_size;
int32_t tmp;
mode = estimate_stereo_mode(left, right, n);
switch(mode)
{
case ALAC_CHMODE_LEFT_RIGHT:
s->interlacing_leftweight = 0;
s->interlacing_shift = 0;
break;
case ALAC_CHMODE_LEFT_SIDE:
for(i=0; i<n; i++) {
right[i] = left[i] - right[i];
}
s->interlacing_leftweight = 1;
s->interlacing_shift = 0;
break;
case ALAC_CHMODE_RIGHT_SIDE:
for(i=0; i<n; i++) {
tmp = right[i];
right[i] = left[i] - right[i];
left[i] = tmp + (right[i] >> 31);
}
s->interlacing_leftweight = 1;
s->interlacing_shift = 31;
break;
default:
for(i=0; i<n; i++) {
tmp = left[i];
left[i] = (tmp + right[i]) >> 1;
right[i] = tmp - right[i];
}
s->interlacing_leftweight = 1;
s->interlacing_shift = 1;
break;
}
}
static void alac_linear_predictor(AlacEncodeContext *s, int ch)
{
int i;
LPCContext lpc = s->lpc[ch];
if(lpc.lpc_order == 31) {
s->predictor_buf[0] = s->sample_buf[ch][0];
for(i=1; i<s->avctx->frame_size; i++)
s->predictor_buf[i] = s->sample_buf[ch][i] - s->sample_buf[ch][i-1];
return;
}
// generalised linear predictor
if(lpc.lpc_order > 0) {
int32_t *samples = s->sample_buf[ch];
int32_t *residual = s->predictor_buf;
// generate warm-up samples
residual[0] = samples[0];
for(i=1;i<=lpc.lpc_order;i++)
residual[i] = samples[i] - samples[i-1];
// perform lpc on remaining samples
for(i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) {
int sum = 1 << (lpc.lpc_quant - 1), res_val, j;
for (j = 0; j < lpc.lpc_order; j++) {
sum += (samples[lpc.lpc_order-j] - samples[0]) *
lpc.lpc_coeff[j];
}
sum >>= lpc.lpc_quant;
sum += samples[0];
residual[i] = samples[lpc.lpc_order+1] - sum;
res_val = residual[i];
if(res_val) {
int index = lpc.lpc_order - 1;
int neg = (res_val < 0);
while(index >= 0 && (neg ? (res_val < 0):(res_val > 0))) {
int val = samples[0] - samples[lpc.lpc_order - index];
int sign = (val ? FFSIGN(val) : 0);
if(neg)
sign*=-1;
lpc.lpc_coeff[index] -= sign;
val *= sign;
res_val -= ((val >> lpc.lpc_quant) *
(lpc.lpc_order - index));
index--;
}
}
samples++;
}
}
}
static void alac_entropy_coder(AlacEncodeContext *s)
{
unsigned int history = s->rc.initial_history;
int sign_modifier = 0, i, k;
int32_t *samples = s->predictor_buf;
for(i=0;i < s->avctx->frame_size;) {
int x;
k = av_log2((history >> 9) + 3);
x = -2*(*samples)-1;
x ^= (x>>31);
samples++;
i++;
encode_scalar(s, x - sign_modifier, k, s->write_sample_size);
history += x * s->rc.history_mult
- ((history * s->rc.history_mult) >> 9);
sign_modifier = 0;
if(x > 0xFFFF)
history = 0xFFFF;
if((history < 128) && (i < s->avctx->frame_size)) {
unsigned int block_size = 0;
k = 7 - av_log2(history) + ((history + 16) >> 6);
while((*samples == 0) && (i < s->avctx->frame_size)) {
samples++;
i++;
block_size++;
}
encode_scalar(s, block_size, k, 16);
sign_modifier = (block_size <= 0xFFFF);
history = 0;
}
}
}
static void write_compressed_frame(AlacEncodeContext *s)
{
int i, j;
/* only simple mid/side decorrelation supported as of now */
if(s->avctx->channels == 2)
alac_stereo_decorrelation(s);
put_bits(&s->pbctx, 8, s->interlacing_shift);
put_bits(&s->pbctx, 8, s->interlacing_leftweight);
for(i=0;i<s->avctx->channels;i++) {
calc_predictor_params(s, i);
put_bits(&s->pbctx, 4, 0); // prediction type : currently only type 0 has been RE'd
put_bits(&s->pbctx, 4, s->lpc[i].lpc_quant);
put_bits(&s->pbctx, 3, s->rc.rice_modifier);
put_bits(&s->pbctx, 5, s->lpc[i].lpc_order);
// predictor coeff. table
for(j=0;j<s->lpc[i].lpc_order;j++) {
put_sbits(&s->pbctx, 16, s->lpc[i].lpc_coeff[j]);
}
}
// apply lpc and entropy coding to audio samples
for(i=0;i<s->avctx->channels;i++) {
alac_linear_predictor(s, i);
alac_entropy_coder(s);
}
}
static av_cold int alac_encode_init(AVCodecContext *avctx)
{
AlacEncodeContext *s = avctx->priv_data;
uint8_t *alac_extradata = av_mallocz(ALAC_EXTRADATA_SIZE+1);
avctx->frame_size = DEFAULT_FRAME_SIZE;
avctx->bits_per_sample = DEFAULT_SAMPLE_SIZE;
if(avctx->sample_fmt != SAMPLE_FMT_S16) {
av_log(avctx, AV_LOG_ERROR, "only pcm_s16 input samples are supported\n");
return -1;
}
// Set default compression level
if(avctx->compression_level == FF_COMPRESSION_DEFAULT)
s->compression_level = 1;
else
s->compression_level = av_clip(avctx->compression_level, 0, 1);
// Initialize default Rice parameters
s->rc.history_mult = 40;
s->rc.initial_history = 10;
s->rc.k_modifier = 14;
s->rc.rice_modifier = 4;
s->max_coded_frame_size = (ALAC_FRAME_HEADER_SIZE + ALAC_FRAME_FOOTER_SIZE +
avctx->frame_size*avctx->channels*avctx->bits_per_sample)>>3;
s->write_sample_size = avctx->bits_per_sample + avctx->channels - 1; // FIXME: consider wasted_bytes
AV_WB32(alac_extradata, ALAC_EXTRADATA_SIZE);
AV_WB32(alac_extradata+4, MKBETAG('a','l','a','c'));
AV_WB32(alac_extradata+12, avctx->frame_size);
AV_WB8 (alac_extradata+17, avctx->bits_per_sample);
AV_WB8 (alac_extradata+21, avctx->channels);
AV_WB32(alac_extradata+24, s->max_coded_frame_size);
AV_WB32(alac_extradata+28, avctx->sample_rate*avctx->channels*avctx->bits_per_sample); // average bitrate
AV_WB32(alac_extradata+32, avctx->sample_rate);
// Set relevant extradata fields
if(s->compression_level > 0) {
AV_WB8(alac_extradata+18, s->rc.history_mult);
AV_WB8(alac_extradata+19, s->rc.initial_history);
AV_WB8(alac_extradata+20, s->rc.k_modifier);
}
s->min_prediction_order = DEFAULT_MIN_PRED_ORDER;
if(avctx->min_prediction_order >= 0) {
if(avctx->min_prediction_order < MIN_LPC_ORDER ||
avctx->min_prediction_order > ALAC_MAX_LPC_ORDER) {
av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n", avctx->min_prediction_order);
return -1;
}
s->min_prediction_order = avctx->min_prediction_order;
}
s->max_prediction_order = DEFAULT_MAX_PRED_ORDER;
if(avctx->max_prediction_order >= 0) {
if(avctx->max_prediction_order < MIN_LPC_ORDER ||
avctx->max_prediction_order > ALAC_MAX_LPC_ORDER) {
av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n", avctx->max_prediction_order);
return -1;
}
s->max_prediction_order = avctx->max_prediction_order;
}
if(s->max_prediction_order < s->min_prediction_order) {
av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
s->min_prediction_order, s->max_prediction_order);
return -1;
}
avctx->extradata = alac_extradata;
avctx->extradata_size = ALAC_EXTRADATA_SIZE;
avctx->coded_frame = avcodec_alloc_frame();
avctx->coded_frame->key_frame = 1;
s->avctx = avctx;
dsputil_init(&s->dspctx, avctx);
return 0;
}
static int alac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
int buf_size, void *data)
{
AlacEncodeContext *s = avctx->priv_data;
PutBitContext *pb = &s->pbctx;
int i, out_bytes, verbatim_flag = 0;
if(avctx->frame_size > DEFAULT_FRAME_SIZE) {
av_log(avctx, AV_LOG_ERROR, "input frame size exceeded\n");
return -1;
}
if(buf_size < 2*s->max_coded_frame_size) {
av_log(avctx, AV_LOG_ERROR, "buffer size is too small\n");
return -1;
}
verbatim:
init_put_bits(pb, frame, buf_size);
if((s->compression_level == 0) || verbatim_flag) {
// Verbatim mode
int16_t *samples = data;
write_frame_header(s, 1);
for(i=0; i<avctx->frame_size*avctx->channels; i++) {
put_sbits(pb, 16, *samples++);
}
} else {
init_sample_buffers(s, data);
write_frame_header(s, 0);
write_compressed_frame(s);
}
put_bits(pb, 3, 7);
flush_put_bits(pb);
out_bytes = put_bits_count(pb) >> 3;
if(out_bytes > s->max_coded_frame_size) {
/* frame too large. use verbatim mode */
if(verbatim_flag || (s->compression_level == 0)) {
/* still too large. must be an error. */
av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
return -1;
}
verbatim_flag = 1;
goto verbatim;
}
return out_bytes;
}
static av_cold int alac_encode_close(AVCodecContext *avctx)
{
av_freep(&avctx->extradata);
avctx->extradata_size = 0;
av_freep(&avctx->coded_frame);
return 0;
}
AVCodec alac_encoder = {
"alac",
CODEC_TYPE_AUDIO,
CODEC_ID_ALAC,
sizeof(AlacEncodeContext),
alac_encode_init,
alac_encode_frame,
alac_encode_close,
.capabilities = CODEC_CAP_SMALL_LAST_FRAME,
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
};
@@ -1,217 +1,336 @@
/*
* Utils for libavcodec
* Provides registration of all codecs, parsers and bitstream filters for libavcodec.
* Copyright (c) 2002 Fabrice Bellard.
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file allcodecs.c
* Utils for libavcodec.
* Provides registration of all codecs, parsers and bitstream filters for libavcodec.
*/
#include "avcodec.h"
/* If you do not call this function, then you can select exactly which
formats you want to support */
#define REGISTER_ENCODER(X,x) { \
extern AVCodec x##_encoder; \
if(ENABLE_##X##_ENCODER) register_avcodec(&x##_encoder); }
#define REGISTER_DECODER(X,x) { \
extern AVCodec x##_decoder; \
if(ENABLE_##X##_DECODER) register_avcodec(&x##_decoder); }
#define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x)
#define REGISTER_PARSER(X,x) { \
extern AVCodecParser x##_parser; \
if(ENABLE_##X##_PARSER) av_register_codec_parser(&x##_parser); }
#define REGISTER_BSF(X,x) { \
extern AVBitStreamFilter x##_bsf; \
if(ENABLE_##X##_BSF) av_register_bitstream_filter(&x##_bsf); }
/**
* simple call to register all the codecs.
* Register all the codecs, parsers and bitstream filters which were enabled at
* configuration time. If you do not call this function you can select exactly
* which formats you want to support, by using the individual registration
* functions.
*
* @see register_avcodec
* @see av_register_codec_parser
* @see av_register_bitstream_filter
*/
void avcodec_register_all(void)
{
static int inited = 0;
if (inited != 0)
return;
inited = 1;
static int initialized;
/* encoders */
#ifdef CONFIG_ENCODERS
register_avcodec(&ac3_encoder);
register_avcodec(&mp2_encoder);
#ifdef CONFIG_MP3LAME
register_avcodec(&mp3lame_encoder);
#endif
#ifdef CONFIG_VORBIS
register_avcodec(&oggvorbis_encoder);
register_avcodec(&oggvorbis_decoder);
#endif
#ifdef CONFIG_FAAC
register_avcodec(&faac_encoder);
#endif
register_avcodec(&mpeg1video_encoder);
// register_avcodec(&h264_encoder);
#ifdef CONFIG_RISKY
register_avcodec(&mpeg2video_encoder);
register_avcodec(&h263_encoder);
register_avcodec(&h263p_encoder);
register_avcodec(&flv_encoder);
register_avcodec(&rv10_encoder);
register_avcodec(&mpeg4_encoder);
register_avcodec(&msmpeg4v1_encoder);
register_avcodec(&msmpeg4v2_encoder);
register_avcodec(&msmpeg4v3_encoder);
register_avcodec(&wmv1_encoder);
register_avcodec(&wmv2_encoder);
#endif
register_avcodec(&mjpeg_encoder);
register_avcodec(&ljpeg_encoder);
register_avcodec(&huffyuv_encoder);
register_avcodec(&asv1_encoder);
register_avcodec(&asv2_encoder);
register_avcodec(&ffv1_encoder);
register_avcodec(&zlib_encoder);
#endif /* CONFIG_ENCODERS */
register_avcodec(&rawvideo_encoder);
register_avcodec(&rawvideo_decoder);
if (initialized)
return;
initialized = 1;
/* decoders */
#ifdef CONFIG_DECODERS
#ifdef CONFIG_RISKY
register_avcodec(&h263_decoder);
register_avcodec(&mpeg4_decoder);
register_avcodec(&msmpeg4v1_decoder);
register_avcodec(&msmpeg4v2_decoder);
register_avcodec(&msmpeg4v3_decoder);
register_avcodec(&wmv1_decoder);
register_avcodec(&wmv2_decoder);
register_avcodec(&h263i_decoder);
register_avcodec(&flv_decoder);
register_avcodec(&rv10_decoder);
register_avcodec(&rv20_decoder);
register_avcodec(&svq1_decoder);
register_avcodec(&svq3_decoder);
register_avcodec(&wmav1_decoder);
register_avcodec(&wmav2_decoder);
register_avcodec(&indeo3_decoder);
#ifdef CONFIG_FAAD
register_avcodec(&aac_decoder);
register_avcodec(&mpeg4aac_decoder);
#endif
#endif
register_avcodec(&mpeg1video_decoder);
register_avcodec(&mpeg2video_decoder);
register_avcodec(&mpegvideo_decoder);
#ifdef HAVE_XVMC
register_avcodec(&mpeg_xvmc_decoder);
#endif
register_avcodec(&dvvideo_decoder);
register_avcodec(&mjpeg_decoder);
register_avcodec(&mjpegb_decoder);
register_avcodec(&sp5x_decoder);
register_avcodec(&mp2_decoder);
register_avcodec(&mp3_decoder);
register_avcodec(&mace3_decoder);
register_avcodec(&mace6_decoder);
register_avcodec(&huffyuv_decoder);
register_avcodec(&ffv1_decoder);
register_avcodec(&cyuv_decoder);
register_avcodec(&h264_decoder);
register_avcodec(&vp3_decoder);
register_avcodec(&theora_decoder);
register_avcodec(&asv1_decoder);
register_avcodec(&asv2_decoder);
register_avcodec(&vcr1_decoder);
register_avcodec(&cljr_decoder);
register_avcodec(&fourxm_decoder);
register_avcodec(&mdec_decoder);
register_avcodec(&roq_decoder);
register_avcodec(&interplay_video_decoder);
register_avcodec(&xan_wc3_decoder);
register_avcodec(&rpza_decoder);
register_avcodec(&cinepak_decoder);
register_avcodec(&msrle_decoder);
register_avcodec(&msvideo1_decoder);
register_avcodec(&vqa_decoder);
register_avcodec(&idcin_decoder);
register_avcodec(&eightbps_decoder);
register_avcodec(&smc_decoder);
register_avcodec(&flic_decoder);
register_avcodec(&truemotion1_decoder);
register_avcodec(&vmdvideo_decoder);
register_avcodec(&vmdaudio_decoder);
register_avcodec(&mszh_decoder);
register_avcodec(&zlib_decoder);
#ifdef CONFIG_AC3
register_avcodec(&ac3_decoder);
#endif
register_avcodec(&ra_144_decoder);
register_avcodec(&ra_288_decoder);
register_avcodec(&roq_dpcm_decoder);
register_avcodec(&interplay_dpcm_decoder);
register_avcodec(&xan_dpcm_decoder);
#endif /* CONFIG_DECODERS */
/* video codecs */
REGISTER_DECODER (AASC, aasc);
REGISTER_DECODER (AMV, amv);
REGISTER_ENCDEC (ASV1, asv1);
REGISTER_ENCDEC (ASV2, asv2);
REGISTER_DECODER (AVS, avs);
REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
REGISTER_DECODER (BFI, bfi);
REGISTER_ENCDEC (BMP, bmp);
REGISTER_DECODER (C93, c93);
REGISTER_DECODER (CAVS, cavs);
REGISTER_DECODER (CINEPAK, cinepak);
REGISTER_DECODER (CLJR, cljr);
REGISTER_DECODER (CSCD, cscd);
REGISTER_DECODER (CYUV, cyuv);
REGISTER_ENCDEC (DNXHD, dnxhd);
REGISTER_DECODER (DSICINVIDEO, dsicinvideo);
REGISTER_ENCDEC (DVVIDEO, dvvideo);
REGISTER_DECODER (DXA, dxa);
REGISTER_DECODER (EACMV, eacmv);
REGISTER_DECODER (EATGV, eatgv);
REGISTER_DECODER (EIGHTBPS, eightbps);
REGISTER_DECODER (EIGHTSVX_EXP, eightsvx_exp);
REGISTER_DECODER (EIGHTSVX_FIB, eightsvx_fib);
REGISTER_DECODER (ESCAPE124, escape124);
REGISTER_ENCDEC (FFV1, ffv1);
REGISTER_ENCDEC (FFVHUFF, ffvhuff);
REGISTER_ENCDEC (FLASHSV, flashsv);
REGISTER_DECODER (FLIC, flic);
REGISTER_ENCDEC (FLV, flv);
REGISTER_DECODER (FOURXM, fourxm);
REGISTER_DECODER (FRAPS, fraps);
REGISTER_ENCDEC (GIF, gif);
REGISTER_ENCDEC (H261, h261);
REGISTER_ENCDEC (H263, h263);
REGISTER_DECODER (H263I, h263i);
REGISTER_ENCODER (H263P, h263p);
REGISTER_DECODER (H264, h264);
REGISTER_ENCDEC (HUFFYUV, huffyuv);
REGISTER_DECODER (IDCIN, idcin);
REGISTER_DECODER (INDEO2, indeo2);
REGISTER_DECODER (INDEO3, indeo3);
REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video);
REGISTER_ENCDEC (JPEGLS, jpegls);
REGISTER_DECODER (KMVC, kmvc);
REGISTER_ENCODER (LJPEG, ljpeg);
REGISTER_DECODER (LOCO, loco);
REGISTER_DECODER (MDEC, mdec);
REGISTER_DECODER (MIMIC, mimic);
REGISTER_ENCDEC (MJPEG, mjpeg);
REGISTER_DECODER (MJPEGB, mjpegb);
REGISTER_DECODER (MMVIDEO, mmvideo);
REGISTER_DECODER (MOTIONPIXELS, motionpixels);
REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
REGISTER_DECODER (MPEGVIDEO, mpegvideo);
REGISTER_ENCDEC (MSMPEG4V1, msmpeg4v1);
REGISTER_ENCDEC (MSMPEG4V2, msmpeg4v2);
REGISTER_ENCDEC (MSMPEG4V3, msmpeg4v3);
REGISTER_DECODER (MSRLE, msrle);
REGISTER_DECODER (MSVIDEO1, msvideo1);
REGISTER_DECODER (MSZH, mszh);
REGISTER_DECODER (NUV, nuv);
REGISTER_ENCODER (PAM, pam);
REGISTER_ENCODER (PBM, pbm);
REGISTER_DECODER (PCX, pcx);
REGISTER_ENCODER (PGM, pgm);
REGISTER_ENCODER (PGMYUV, pgmyuv);
REGISTER_ENCDEC (PNG, png);
REGISTER_ENCODER (PPM, ppm);
REGISTER_DECODER (PTX, ptx);
REGISTER_DECODER (QDRAW, qdraw);
REGISTER_DECODER (QPEG, qpeg);
REGISTER_ENCDEC (QTRLE, qtrle);
REGISTER_ENCDEC (RAWVIDEO, rawvideo);
REGISTER_DECODER (RL2, rl2);
REGISTER_ENCDEC (ROQ, roq);
REGISTER_DECODER (RPZA, rpza);
REGISTER_ENCDEC (RV10, rv10);
REGISTER_ENCDEC (RV20, rv20);
REGISTER_ENCDEC (SGI, sgi);
REGISTER_DECODER (SMACKER, smacker);
REGISTER_DECODER (SMC, smc);
REGISTER_ENCDEC (SNOW, snow);
REGISTER_DECODER (SP5X, sp5x);
REGISTER_DECODER (SUNRAST, sunrast);
REGISTER_ENCDEC (SVQ1, svq1);
REGISTER_DECODER (SVQ3, svq3);
REGISTER_ENCDEC (TARGA, targa);
REGISTER_DECODER (THEORA, theora);
REGISTER_DECODER (THP, thp);
REGISTER_DECODER (TIERTEXSEQVIDEO, tiertexseqvideo);
REGISTER_ENCDEC (TIFF, tiff);
REGISTER_DECODER (TRUEMOTION1, truemotion1);
REGISTER_DECODER (TRUEMOTION2, truemotion2);
REGISTER_DECODER (TSCC, tscc);
REGISTER_DECODER (TXD, txd);
REGISTER_DECODER (ULTI, ulti);
REGISTER_DECODER (VB, vb);
REGISTER_DECODER (VC1, vc1);
REGISTER_DECODER (VCR1, vcr1);
REGISTER_DECODER (VMDVIDEO, vmdvideo);
REGISTER_DECODER (VMNC, vmnc);
REGISTER_DECODER (VP3, vp3);
REGISTER_DECODER (VP5, vp5);
REGISTER_DECODER (VP6, vp6);
REGISTER_DECODER (VP6A, vp6a);
REGISTER_DECODER (VP6F, vp6f);
REGISTER_DECODER (VQA, vqa);
REGISTER_ENCDEC (WMV1, wmv1);
REGISTER_ENCDEC (WMV2, wmv2);
REGISTER_DECODER (WMV3, wmv3);
REGISTER_DECODER (WNV1, wnv1);
REGISTER_DECODER (XAN_WC3, xan_wc3);
REGISTER_DECODER (XL, xl);
REGISTER_DECODER (XSUB, xsub);
REGISTER_ENCDEC (ZLIB, zlib);
REGISTER_ENCDEC (ZMBV, zmbv);
#ifdef AMR_NB
register_avcodec(&amr_nb_decoder);
#ifdef CONFIG_ENCODERS
register_avcodec(&amr_nb_encoder);
#endif //CONFIG_ENCODERS
#endif /* AMR_NB */
/* audio codecs */
REGISTER_DECODER (AAC, aac);
REGISTER_ENCDEC (AC3, ac3);
REGISTER_ENCDEC (ALAC, alac);
REGISTER_DECODER (APE, ape);
REGISTER_DECODER (ATRAC3, atrac3);
REGISTER_DECODER (COOK, cook);
REGISTER_DECODER (DCA, dca);
REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
REGISTER_ENCDEC (FLAC, flac);
REGISTER_DECODER (IMC, imc);
REGISTER_DECODER (MACE3, mace3);
REGISTER_DECODER (MACE6, mace6);
REGISTER_DECODER (MLP, mlp);
REGISTER_ENCDEC (MP2, mp2);
REGISTER_DECODER (MP3, mp3);
REGISTER_DECODER (MP3ADU, mp3adu);
REGISTER_DECODER (MP3ON4, mp3on4);
REGISTER_DECODER (MPC7, mpc7);
REGISTER_DECODER (MPC8, mpc8);
REGISTER_DECODER (NELLYMOSER, nellymoser);
REGISTER_DECODER (QDM2, qdm2);
REGISTER_DECODER (RA_144, ra_144);
REGISTER_DECODER (RA_288, ra_288);
REGISTER_DECODER (SHORTEN, shorten);
REGISTER_DECODER (SMACKAUD, smackaud);
REGISTER_ENCDEC (SONIC, sonic);
REGISTER_ENCODER (SONIC_LS, sonic_ls);
REGISTER_DECODER (TRUESPEECH, truespeech);
REGISTER_DECODER (TTA, tta);
REGISTER_DECODER (VMDAUDIO, vmdaudio);
REGISTER_ENCDEC (VORBIS, vorbis);
REGISTER_DECODER (WAVPACK, wavpack);
REGISTER_ENCDEC (WMAV1, wmav1);
REGISTER_ENCDEC (WMAV2, wmav2);
REGISTER_DECODER (WS_SND1, ws_snd1);
#ifdef AMR_WB
register_avcodec(&amr_wb_decoder);
#ifdef CONFIG_ENCODERS
register_avcodec(&amr_wb_encoder);
#endif //CONFIG_ENCODERS
#endif /* AMR_WB */
/* PCM codecs */
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
REGISTER_DECODER (PCM_DVD, pcm_dvd);
REGISTER_ENCDEC (PCM_F32BE, pcm_f32be);
REGISTER_ENCDEC (PCM_F32LE, pcm_f32le);
REGISTER_ENCDEC (PCM_F64BE, pcm_f64be);
REGISTER_ENCDEC (PCM_F64LE, pcm_f64le);
REGISTER_ENCDEC (PCM_MULAW, pcm_mulaw);
REGISTER_ENCDEC (PCM_S8, pcm_s8);
REGISTER_ENCDEC (PCM_S16BE, pcm_s16be);
REGISTER_ENCDEC (PCM_S16LE, pcm_s16le);
REGISTER_DECODER (PCM_S16LE_PLANAR, pcm_s16le_planar);
REGISTER_ENCDEC (PCM_S24BE, pcm_s24be);
REGISTER_ENCDEC (PCM_S24DAUD, pcm_s24daud);
REGISTER_ENCDEC (PCM_S24LE, pcm_s24le);
REGISTER_ENCDEC (PCM_S32BE, pcm_s32be);
REGISTER_ENCDEC (PCM_S32LE, pcm_s32le);
REGISTER_ENCDEC (PCM_U8, pcm_u8);
REGISTER_ENCDEC (PCM_U16BE, pcm_u16be);
REGISTER_ENCDEC (PCM_U16LE, pcm_u16le);
REGISTER_ENCDEC (PCM_U24BE, pcm_u24be);
REGISTER_ENCDEC (PCM_U24LE, pcm_u24le);
REGISTER_ENCDEC (PCM_U32BE, pcm_u32be);
REGISTER_ENCDEC (PCM_U32LE, pcm_u32le);
REGISTER_ENCDEC (PCM_ZORK , pcm_zork);
/* pcm codecs */
/* DPCM codecs */
REGISTER_DECODER (INTERPLAY_DPCM, interplay_dpcm);
REGISTER_ENCDEC (ROQ_DPCM, roq_dpcm);
REGISTER_DECODER (SOL_DPCM, sol_dpcm);
REGISTER_DECODER (XAN_DPCM, xan_dpcm);
#ifdef CONFIG_ENCODERS
#define PCM_CODEC(id, name) \
register_avcodec(& name ## _encoder); \
register_avcodec(& name ## _decoder); \
/* ADPCM codecs */
REGISTER_DECODER (ADPCM_4XM, adpcm_4xm);
REGISTER_ENCDEC (ADPCM_ADX, adpcm_adx);
REGISTER_DECODER (ADPCM_CT, adpcm_ct);
REGISTER_DECODER (ADPCM_EA, adpcm_ea);
REGISTER_DECODER (ADPCM_EA_MAXIS_XA, adpcm_ea_maxis_xa);
REGISTER_DECODER (ADPCM_EA_R1, adpcm_ea_r1);
REGISTER_DECODER (ADPCM_EA_R2, adpcm_ea_r2);
REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3);
REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas);
REGISTER_ENCDEC (ADPCM_G726, adpcm_g726);
REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv);
REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3);
REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4);
REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs);
REGISTER_DECODER (ADPCM_IMA_EA_SEAD, adpcm_ima_ea_sead);
REGISTER_ENCDEC (ADPCM_IMA_QT, adpcm_ima_qt);
REGISTER_DECODER (ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
REGISTER_ENCDEC (ADPCM_IMA_WAV, adpcm_ima_wav);
REGISTER_DECODER (ADPCM_IMA_WS, adpcm_ima_ws);
REGISTER_ENCDEC (ADPCM_MS, adpcm_ms);
REGISTER_DECODER (ADPCM_SBPRO_2, adpcm_sbpro_2);
REGISTER_DECODER (ADPCM_SBPRO_3, adpcm_sbpro_3);
REGISTER_DECODER (ADPCM_SBPRO_4, adpcm_sbpro_4);
REGISTER_ENCDEC (ADPCM_SWF, adpcm_swf);
REGISTER_DECODER (ADPCM_THP, adpcm_thp);
REGISTER_DECODER (ADPCM_XA, adpcm_xa);
REGISTER_ENCDEC (ADPCM_YAMAHA, adpcm_yamaha);
#else
#define PCM_CODEC(id, name) \
register_avcodec(& name ## _decoder);
/* subtitles */
REGISTER_ENCDEC (DVBSUB, dvbsub);
REGISTER_ENCDEC (DVDSUB, dvdsub);
/* external libraries */
REGISTER_DECODER (LIBA52, liba52);
REGISTER_ENCDEC (LIBAMR_NB, libamr_nb);
REGISTER_ENCDEC (LIBAMR_WB, libamr_wb);
REGISTER_ENCDEC (LIBDIRAC, libdirac);
REGISTER_ENCODER (LIBFAAC, libfaac);
REGISTER_DECODER (LIBFAAD, libfaad);
REGISTER_ENCDEC (LIBGSM, libgsm);
REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
REGISTER_ENCODER (LIBTHEORA, libtheora);
REGISTER_ENCODER (LIBVORBIS, libvorbis);
REGISTER_ENCODER (LIBX264, libx264);
REGISTER_ENCODER (LIBXVID, libxvid);
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
REGISTER_DECODER (MPEG4AAC, mpeg4aac);
#endif
PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le);
PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be);
PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le);
PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be);
PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8);
PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8);
PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw);
PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw);
/* parsers */
REGISTER_PARSER (AAC, aac);
REGISTER_PARSER (AC3, ac3);
REGISTER_PARSER (CAVSVIDEO, cavsvideo);
REGISTER_PARSER (DCA, dca);
REGISTER_PARSER (DIRAC, dirac);
REGISTER_PARSER (DVBSUB, dvbsub);
REGISTER_PARSER (DVDSUB, dvdsub);
REGISTER_PARSER (H261, h261);
REGISTER_PARSER (H263, h263);
REGISTER_PARSER (H264, h264);
REGISTER_PARSER (MJPEG, mjpeg);
REGISTER_PARSER (MLP, mlp);
REGISTER_PARSER (MPEG4VIDEO, mpeg4video);
REGISTER_PARSER (MPEGAUDIO, mpegaudio);
REGISTER_PARSER (MPEGVIDEO, mpegvideo);
REGISTER_PARSER (PNM, pnm);
REGISTER_PARSER (VC1, vc1);
REGISTER_PARSER (VP3, vp3);
/* adpcm codecs */
PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt);
PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
#undef PCM_CODEC
/* parsers */
av_register_codec_parser(&mpegvideo_parser);
av_register_codec_parser(&mpeg4video_parser);
av_register_codec_parser(&h263_parser);
av_register_codec_parser(&h264_parser);
av_register_codec_parser(&mpegaudio_parser);
#ifdef CONFIG_AC3
av_register_codec_parser(&ac3_parser);
#endif
/* bitstream filters */
REGISTER_BSF (DUMP_EXTRADATA, dump_extradata);
REGISTER_BSF (H264_MP4TOANNEXB, h264_mp4toannexb);
REGISTER_BSF (IMX_DUMP_HEADER, imx_dump_header);
REGISTER_BSF (MJPEGA_DUMP_HEADER, mjpega_dump_header);
REGISTER_BSF (MP3_HEADER_COMPRESS, mp3_header_compress);
REGISTER_BSF (MP3_HEADER_DECOMPRESS, mp3_header_decompress);
REGISTER_BSF (MOV2TEXTSUB, mov2textsub);
REGISTER_BSF (NOISE, noise);
REGISTER_BSF (REMOVE_EXTRADATA, remove_extradata);
REGISTER_BSF (TEXT2MOVSUB, text2movsub);
}
@@ -0,0 +1,899 @@
/*
* Monkey's Audio lossless audio decoder
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
* based upon libdemac from Dave Chapman.
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define ALT_BITSTREAM_READER_LE
#include "avcodec.h"
#include "dsputil.h"
#include "bitstream.h"
#include "bytestream.h"
/**
* @file apedec.c
* Monkey's Audio lossless audio decoder
*/
#define BLOCKS_PER_LOOP 4608
#define MAX_CHANNELS 2
#define MAX_BYTESPERSAMPLE 3
#define APE_FRAMECODE_MONO_SILENCE 1
#define APE_FRAMECODE_STEREO_SILENCE 3
#define APE_FRAMECODE_PSEUDO_STEREO 4
#define HISTORY_SIZE 512
#define PREDICTOR_ORDER 8
/** Total size of all predictor histories */
#define PREDICTOR_SIZE 50
#define YDELAYA (18 + PREDICTOR_ORDER*4)
#define YDELAYB (18 + PREDICTOR_ORDER*3)
#define XDELAYA (18 + PREDICTOR_ORDER*2)
#define XDELAYB (18 + PREDICTOR_ORDER)
#define YADAPTCOEFFSA 18
#define XADAPTCOEFFSA 14
#define YADAPTCOEFFSB 10
#define XADAPTCOEFFSB 5
/**
* Possible compression levels
* @{
*/
enum APECompressionLevel {
COMPRESSION_LEVEL_FAST = 1000,
COMPRESSION_LEVEL_NORMAL = 2000,
COMPRESSION_LEVEL_HIGH = 3000,
COMPRESSION_LEVEL_EXTRA_HIGH = 4000,
COMPRESSION_LEVEL_INSANE = 5000
};
/** @} */
#define APE_FILTER_LEVELS 3
/** Filter orders depending on compression level */
static const uint16_t ape_filter_orders[5][APE_FILTER_LEVELS] = {
{ 0, 0, 0 },
{ 16, 0, 0 },
{ 64, 0, 0 },
{ 32, 256, 0 },
{ 16, 256, 1280 }
};
/** Filter fraction bits depending on compression level */
static const uint8_t ape_filter_fracbits[5][APE_FILTER_LEVELS] = {
{ 0, 0, 0 },
{ 11, 0, 0 },
{ 11, 0, 0 },
{ 10, 13, 0 },
{ 11, 13, 15 }
};
/** Filters applied to the decoded data */
typedef struct APEFilter {
int16_t *coeffs; ///< actual coefficients used in filtering
int16_t *adaptcoeffs; ///< adaptive filter coefficients used for correcting of actual filter coefficients
int16_t *historybuffer; ///< filter memory
int16_t *delay; ///< filtered values
int avg;
} APEFilter;
typedef struct APERice {
uint32_t k;
uint32_t ksum;
} APERice;
typedef struct APERangecoder {
uint32_t low; ///< low end of interval
uint32_t range; ///< length of interval
uint32_t help; ///< bytes_to_follow resp. intermediate value
unsigned int buffer; ///< buffer for input/output
} APERangecoder;
/** Filter histories */
typedef struct APEPredictor {
int32_t *buf;
int32_t lastA[2];
int32_t filterA[2];
int32_t filterB[2];
int32_t coeffsA[2][4]; ///< adaption coefficients
int32_t coeffsB[2][5]; ///< adaption coefficients
int32_t historybuffer[HISTORY_SIZE + PREDICTOR_SIZE];
} APEPredictor;
/** Decoder context */
typedef struct APEContext {
AVCodecContext *avctx;
DSPContext dsp;
int channels;
int samples; ///< samples left to decode in current frame
int fileversion; ///< codec version, very important in decoding process
int compression_level; ///< compression levels
int fset; ///< which filter set to use (calculated from compression level)
int flags; ///< global decoder flags
uint32_t CRC; ///< frame CRC
int frameflags; ///< frame flags
int currentframeblocks; ///< samples (per channel) in current frame
int blocksdecoded; ///< count of decoded samples in current frame
APEPredictor predictor; ///< predictor used for final reconstruction
int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel
int32_t decoded1[BLOCKS_PER_LOOP]; ///< decoded data for the second channel
int16_t* filterbuf[APE_FILTER_LEVELS]; ///< filter memory
APERangecoder rc; ///< rangecoder used to decode actual values
APERice riceX; ///< rice code parameters for the second channel
APERice riceY; ///< rice code parameters for the first channel
APEFilter filters[APE_FILTER_LEVELS][2]; ///< filters used for reconstruction
uint8_t *data; ///< current frame data
uint8_t *data_end; ///< frame data end
const uint8_t *ptr; ///< current position in frame data
const uint8_t *last_ptr; ///< position where last 4608-sample block ended
int error;
} APEContext;
// TODO: dsputilize
static av_cold int ape_decode_init(AVCodecContext * avctx)
{
APEContext *s = avctx->priv_data;
int i;
if (avctx->extradata_size != 6) {
av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n");
return -1;
}
if (avctx->bits_per_sample != 16) {
av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n");
return -1;
}
if (avctx->channels > 2) {
av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n");
return -1;
}
s->avctx = avctx;
s->channels = avctx->channels;
s->fileversion = AV_RL16(avctx->extradata);
s->compression_level = AV_RL16(avctx->extradata + 2);
s->flags = AV_RL16(avctx->extradata + 4);
av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags);
if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) {
av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level);
return -1;
}
s->fset = s->compression_level / 1000 - 1;
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[s->fset][i])
break;
s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4);
}
dsputil_init(&s->dsp, avctx);
avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
static av_cold int ape_decode_close(AVCodecContext * avctx)
{
APEContext *s = avctx->priv_data;
int i;
for (i = 0; i < APE_FILTER_LEVELS; i++)
av_freep(&s->filterbuf[i]);
return 0;
}
/**
* @defgroup rangecoder APE range decoder
* @{
*/
#define CODE_BITS 32
#define TOP_VALUE ((unsigned int)1 << (CODE_BITS-1))
#define SHIFT_BITS (CODE_BITS - 9)
#define EXTRA_BITS ((CODE_BITS-2) % 8 + 1)
#define BOTTOM_VALUE (TOP_VALUE >> 8)
/** Start the decoder */
static inline void range_start_decoding(APEContext * ctx)
{
ctx->rc.buffer = bytestream_get_byte(&ctx->ptr);
ctx->rc.low = ctx->rc.buffer >> (8 - EXTRA_BITS);
ctx->rc.range = (uint32_t) 1 << EXTRA_BITS;
}
/** Perform normalization */
static inline void range_dec_normalize(APEContext * ctx)
{
while (ctx->rc.range <= BOTTOM_VALUE) {
ctx->rc.buffer <<= 8;
if(ctx->ptr < ctx->data_end)
ctx->rc.buffer += *ctx->ptr;
ctx->ptr++;
ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF);
ctx->rc.range <<= 8;
}
}
/**
* Calculate culmulative frequency for next symbol. Does NO update!
* @param tot_f is the total frequency or (code_value)1<<shift
* @return the culmulative frequency
*/
static inline int range_decode_culfreq(APEContext * ctx, int tot_f)
{
range_dec_normalize(ctx);
ctx->rc.help = ctx->rc.range / tot_f;
return ctx->rc.low / ctx->rc.help;
}
/**
* Decode value with given size in bits
* @param shift number of bits to decode
*/
static inline int range_decode_culshift(APEContext * ctx, int shift)
{
range_dec_normalize(ctx);
ctx->rc.help = ctx->rc.range >> shift;
return ctx->rc.low / ctx->rc.help;
}
/**
* Update decoding state
* @param sy_f the interval length (frequency of the symbol)
* @param lt_f the lower end (frequency sum of < symbols)
*/
static inline void range_decode_update(APEContext * ctx, int sy_f, int lt_f)
{
ctx->rc.low -= ctx->rc.help * lt_f;
ctx->rc.range = ctx->rc.help * sy_f;
}
/** Decode n bits (n <= 16) without modelling */
static inline int range_decode_bits(APEContext * ctx, int n)
{
int sym = range_decode_culshift(ctx, n);
range_decode_update(ctx, 1, sym);
return sym;
}
#define MODEL_ELEMENTS 64
/**
* Fixed probabilities for symbols in Monkey Audio version 3.97
*/
static const uint16_t counts_3970[22] = {
0, 14824, 28224, 39348, 47855, 53994, 58171, 60926,
62682, 63786, 64463, 64878, 65126, 65276, 65365, 65419,
65450, 65469, 65480, 65487, 65491, 65493,
};
/**
* Probability ranges for symbols in Monkey Audio version 3.97
*/
static const uint16_t counts_diff_3970[21] = {
14824, 13400, 11124, 8507, 6139, 4177, 2755, 1756,
1104, 677, 415, 248, 150, 89, 54, 31,
19, 11, 7, 4, 2,
};
/**
* Fixed probabilities for symbols in Monkey Audio version 3.98
*/
static const uint16_t counts_3980[22] = {
0, 19578, 36160, 48417, 56323, 60899, 63265, 64435,
64971, 65232, 65351, 65416, 65447, 65466, 65476, 65482,
65485, 65488, 65490, 65491, 65492, 65493,
};
/**
* Probability ranges for symbols in Monkey Audio version 3.98
*/
static const uint16_t counts_diff_3980[21] = {
19578, 16582, 12257, 7906, 4576, 2366, 1170, 536,
261, 119, 65, 31, 19, 10, 6, 3,
3, 2, 1, 1, 1,
};
/**
* Decode symbol
* @param counts probability range start position
* @param count_diffs probability range widths
*/
static inline int range_get_symbol(APEContext * ctx,
const uint16_t counts[],
const uint16_t counts_diff[])
{
int symbol, cf;
cf = range_decode_culshift(ctx, 16);
if(cf > 65492){
symbol= cf - 65535 + 63;
range_decode_update(ctx, 1, cf);
if(cf > 65535)
ctx->error=1;
return symbol;
}
/* figure out the symbol inefficiently; a binary search would be much better */
for (symbol = 0; counts[symbol + 1] <= cf; symbol++);
range_decode_update(ctx, counts_diff[symbol], counts[symbol]);
return symbol;
}
/** @} */ // group rangecoder
static inline void update_rice(APERice *rice, int x)
{
rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
if (rice->k == 0)
rice->k = 1;
else if (rice->ksum < (1 << (rice->k + 4)))
rice->k--;
else if (rice->ksum >= (1 << (rice->k + 5)))
rice->k++;
}
static inline int ape_decode_value(APEContext * ctx, APERice *rice)
{
int x, overflow;
if (ctx->fileversion < 3980) {
int tmpk;
overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970);
if (overflow == (MODEL_ELEMENTS - 1)) {
tmpk = range_decode_bits(ctx, 5);
overflow = 0;
} else
tmpk = (rice->k < 1) ? 0 : rice->k - 1;
if (tmpk <= 16)
x = range_decode_bits(ctx, tmpk);
else {
x = range_decode_bits(ctx, 16);
x |= (range_decode_bits(ctx, tmpk - 16) << 16);
}
x += overflow << tmpk;
} else {
int base, pivot;
pivot = rice->ksum >> 5;
if (pivot == 0)
pivot = 1;
overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);
if (overflow == (MODEL_ELEMENTS - 1)) {
overflow = range_decode_bits(ctx, 16) << 16;
overflow |= range_decode_bits(ctx, 16);
}
base = range_decode_culfreq(ctx, pivot);
range_decode_update(ctx, 1, base);
x = base + overflow * pivot;
}
update_rice(rice, x);
/* Convert to signed */
if (x & 1)
return (x >> 1) + 1;
else
return -(x >> 1);
}
static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo)
{
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
ctx->blocksdecoded = blockstodecode;
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
/* We are pure silence, just memset the output buffer. */
memset(decoded0, 0, blockstodecode * sizeof(int32_t));
memset(decoded1, 0, blockstodecode * sizeof(int32_t));
} else {
while (blockstodecode--) {
*decoded0++ = ape_decode_value(ctx, &ctx->riceY);
if (stereo)
*decoded1++ = ape_decode_value(ctx, &ctx->riceX);
}
}
if (ctx->blocksdecoded == ctx->currentframeblocks)
range_dec_normalize(ctx); /* normalize to use up all bytes */
}
static void init_entropy_decoder(APEContext * ctx)
{
/* Read the CRC */
ctx->CRC = bytestream_get_be32(&ctx->ptr);
/* Read the frame flags if they exist */
ctx->frameflags = 0;
if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) {
ctx->CRC &= ~0x80000000;
ctx->frameflags = bytestream_get_be32(&ctx->ptr);
}
/* Keep a count of the blocks decoded in this frame */
ctx->blocksdecoded = 0;
/* Initialize the rice structs */
ctx->riceX.k = 10;
ctx->riceX.ksum = (1 << ctx->riceX.k) * 16;
ctx->riceY.k = 10;
ctx->riceY.ksum = (1 << ctx->riceY.k) * 16;
/* The first 8 bits of input are ignored. */
ctx->ptr++;
range_start_decoding(ctx);
}
static const int32_t initial_coeffs[4] = {
360, 317, -109, 98
};
static void init_predictor_decoder(APEContext * ctx)
{
APEPredictor *p = &ctx->predictor;
/* Zero the history buffers */
memset(p->historybuffer, 0, PREDICTOR_SIZE * sizeof(int32_t));
p->buf = p->historybuffer;
/* Initialize and zero the coefficients */
memcpy(p->coeffsA[0], initial_coeffs, sizeof(initial_coeffs));
memcpy(p->coeffsA[1], initial_coeffs, sizeof(initial_coeffs));
memset(p->coeffsB, 0, sizeof(p->coeffsB));
p->filterA[0] = p->filterA[1] = 0;
p->filterB[0] = p->filterB[1] = 0;
p->lastA[0] = p->lastA[1] = 0;
}
/** Get inverse sign of integer (-1 for positive, 1 for negative and 0 for zero) */
static inline int APESIGN(int32_t x) {
return (x < 0) - (x > 0);
}
static int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB)
{
int32_t predictionA, predictionB;
p->buf[delayA] = p->lastA[filter];
p->buf[adaptA] = APESIGN(p->buf[delayA]);
p->buf[delayA - 1] = p->buf[delayA] - p->buf[delayA - 1];
p->buf[adaptA - 1] = APESIGN(p->buf[delayA - 1]);
predictionA = p->buf[delayA ] * p->coeffsA[filter][0] +
p->buf[delayA - 1] * p->coeffsA[filter][1] +
p->buf[delayA - 2] * p->coeffsA[filter][2] +
p->buf[delayA - 3] * p->coeffsA[filter][3];
/* Apply a scaled first-order filter compression */
p->buf[delayB] = p->filterA[filter ^ 1] - ((p->filterB[filter] * 31) >> 5);
p->buf[adaptB] = APESIGN(p->buf[delayB]);
p->buf[delayB - 1] = p->buf[delayB] - p->buf[delayB - 1];
p->buf[adaptB - 1] = APESIGN(p->buf[delayB - 1]);
p->filterB[filter] = p->filterA[filter ^ 1];
predictionB = p->buf[delayB ] * p->coeffsB[filter][0] +
p->buf[delayB - 1] * p->coeffsB[filter][1] +
p->buf[delayB - 2] * p->coeffsB[filter][2] +
p->buf[delayB - 3] * p->coeffsB[filter][3] +
p->buf[delayB - 4] * p->coeffsB[filter][4];
p->lastA[filter] = decoded + ((predictionA + (predictionB >> 1)) >> 10);
p->filterA[filter] = p->lastA[filter] + ((p->filterA[filter] * 31) >> 5);
if (!decoded) // no need updating filter coefficients
return p->filterA[filter];
if (decoded > 0) {
p->coeffsA[filter][0] -= p->buf[adaptA ];
p->coeffsA[filter][1] -= p->buf[adaptA - 1];
p->coeffsA[filter][2] -= p->buf[adaptA - 2];
p->coeffsA[filter][3] -= p->buf[adaptA - 3];
p->coeffsB[filter][0] -= p->buf[adaptB ];
p->coeffsB[filter][1] -= p->buf[adaptB - 1];
p->coeffsB[filter][2] -= p->buf[adaptB - 2];
p->coeffsB[filter][3] -= p->buf[adaptB - 3];
p->coeffsB[filter][4] -= p->buf[adaptB - 4];
} else {
p->coeffsA[filter][0] += p->buf[adaptA ];
p->coeffsA[filter][1] += p->buf[adaptA - 1];
p->coeffsA[filter][2] += p->buf[adaptA - 2];
p->coeffsA[filter][3] += p->buf[adaptA - 3];
p->coeffsB[filter][0] += p->buf[adaptB ];
p->coeffsB[filter][1] += p->buf[adaptB - 1];
p->coeffsB[filter][2] += p->buf[adaptB - 2];
p->coeffsB[filter][3] += p->buf[adaptB - 3];
p->coeffsB[filter][4] += p->buf[adaptB - 4];
}
return p->filterA[filter];
}
static void predictor_decode_stereo(APEContext * ctx, int count)
{
int32_t predictionA, predictionB;
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
while (count--) {
/* Predictor Y */
predictionA = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB);
predictionB = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB);
*(decoded0++) = predictionA;
*(decoded1++) = predictionB;
/* Combined */
p->buf++;
/* Have we filled the history buffer? */
if (p->buf == p->historybuffer + HISTORY_SIZE) {
memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t));
p->buf = p->historybuffer;
}
}
}
static void predictor_decode_mono(APEContext * ctx, int count)
{
APEPredictor *p = &ctx->predictor;
int32_t *decoded0 = ctx->decoded0;
int32_t predictionA, currentA, A;
currentA = p->lastA[0];
while (count--) {
A = *decoded0;
p->buf[YDELAYA] = currentA;
p->buf[YDELAYA - 1] = p->buf[YDELAYA] - p->buf[YDELAYA - 1];
predictionA = p->buf[YDELAYA ] * p->coeffsA[0][0] +
p->buf[YDELAYA - 1] * p->coeffsA[0][1] +
p->buf[YDELAYA - 2] * p->coeffsA[0][2] +
p->buf[YDELAYA - 3] * p->coeffsA[0][3];
currentA = A + (predictionA >> 10);
p->buf[YADAPTCOEFFSA] = APESIGN(p->buf[YDELAYA ]);
p->buf[YADAPTCOEFFSA - 1] = APESIGN(p->buf[YDELAYA - 1]);
if (A > 0) {
p->coeffsA[0][0] -= p->buf[YADAPTCOEFFSA ];
p->coeffsA[0][1] -= p->buf[YADAPTCOEFFSA - 1];
p->coeffsA[0][2] -= p->buf[YADAPTCOEFFSA - 2];
p->coeffsA[0][3] -= p->buf[YADAPTCOEFFSA - 3];
} else if (A < 0) {
p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ];
p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1];
p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2];
p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3];
}
p->buf++;
/* Have we filled the history buffer? */
if (p->buf == p->historybuffer + HISTORY_SIZE) {
memmove(p->historybuffer, p->buf, PREDICTOR_SIZE * sizeof(int32_t));
p->buf = p->historybuffer;
}
p->filterA[0] = currentA + ((p->filterA[0] * 31) >> 5);
*(decoded0++) = p->filterA[0];
}
p->lastA[0] = currentA;
}
static void do_init_filter(APEFilter *f, int16_t * buf, int order)
{
f->coeffs = buf;
f->historybuffer = buf + order;
f->delay = f->historybuffer + order * 2;
f->adaptcoeffs = f->historybuffer + order;
memset(f->historybuffer, 0, (order * 2) * sizeof(int16_t));
memset(f->coeffs, 0, order * sizeof(int16_t));
f->avg = 0;
}
static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order)
{
do_init_filter(&f[0], buf, order);
do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order);
}
static inline void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits)
{
int res;
int absres;
while (count--) {
/* round fixedpoint scalar product */
res = (ctx->dsp.scalarproduct_int16(f->delay - order, f->coeffs, order, 0) + (1 << (fracbits - 1))) >> fracbits;
if (*data < 0)
ctx->dsp.add_int16(f->coeffs, f->adaptcoeffs - order, order);
else if (*data > 0)
ctx->dsp.sub_int16(f->coeffs, f->adaptcoeffs - order, order);
res += *data;
*data++ = res;
/* Update the output history */
*f->delay++ = av_clip_int16(res);
if (version < 3980) {
/* Version ??? to < 3.98 files (untested) */
f->adaptcoeffs[0] = (res == 0) ? 0 : ((res >> 28) & 8) - 4;
f->adaptcoeffs[-4] >>= 1;
f->adaptcoeffs[-8] >>= 1;
} else {
/* Version 3.98 and later files */
/* Update the adaption coefficients */
absres = (res < 0 ? -res : res);
if (absres > (f->avg * 3))
*f->adaptcoeffs = ((res >> 25) & 64) - 32;
else if (absres > (f->avg * 4) / 3)
*f->adaptcoeffs = ((res >> 26) & 32) - 16;
else if (absres > 0)
*f->adaptcoeffs = ((res >> 27) & 16) - 8;
else
*f->adaptcoeffs = 0;
f->avg += (absres - f->avg) / 16;
f->adaptcoeffs[-1] >>= 1;
f->adaptcoeffs[-2] >>= 1;
f->adaptcoeffs[-8] >>= 1;
}
f->adaptcoeffs++;
/* Have we filled the history buffer? */
if (f->delay == f->historybuffer + HISTORY_SIZE + (order * 2)) {
memmove(f->historybuffer, f->delay - (order * 2),
(order * 2) * sizeof(int16_t));
f->delay = f->historybuffer + order * 2;
f->adaptcoeffs = f->historybuffer + order;
}
}
}
static void apply_filter(APEContext * ctx, APEFilter *f,
int32_t * data0, int32_t * data1,
int count, int order, int fracbits)
{
do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits);
if (data1)
do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits);
}
static void ape_apply_filters(APEContext * ctx, int32_t * decoded0,
int32_t * decoded1, int count)
{
int i;
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[ctx->fset][i])
break;
apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]);
}
}
static void init_frame_decoder(APEContext * ctx)
{
int i;
init_entropy_decoder(ctx);
init_predictor_decoder(ctx);
for (i = 0; i < APE_FILTER_LEVELS; i++) {
if (!ape_filter_orders[ctx->fset][i])
break;
init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]);
}
}
static void ape_unpack_mono(APEContext * ctx, int count)
{
int32_t left;
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
entropy_decode(ctx, count, 0);
/* We are pure silence, so we're done. */
av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence mono\n");
return;
}
entropy_decode(ctx, count, 0);
ape_apply_filters(ctx, decoded0, NULL, count);
/* Now apply the predictor decoding */
predictor_decode_mono(ctx, count);
/* Pseudo-stereo - just copy left channel to right channel */
if (ctx->channels == 2) {
while (count--) {
left = *decoded0;
*(decoded1++) = *(decoded0++) = left;
}
}
}
static void ape_unpack_stereo(APEContext * ctx, int count)
{
int32_t left, right;
int32_t *decoded0 = ctx->decoded0;
int32_t *decoded1 = ctx->decoded1;
if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) {
/* We are pure silence, so we're done. */
av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence stereo\n");
return;
}
entropy_decode(ctx, count, 1);
ape_apply_filters(ctx, decoded0, decoded1, count);
/* Now apply the predictor decoding */
predictor_decode_stereo(ctx, count);
/* Decorrelate and scale to output depth */
while (count--) {
left = *decoded1 - (*decoded0 / 2);
right = left + *decoded0;
*(decoded0++) = left;
*(decoded1++) = right;
}
}
static int ape_decode_frame(AVCodecContext * avctx,
void *data, int *data_size,
const uint8_t * buf, int buf_size)
{
APEContext *s = avctx->priv_data;
int16_t *samples = data;
int nblocks;
int i, n;
int blockstodecode;
int bytes_used;
if (buf_size == 0 && !s->samples) {
*data_size = 0;
return 0;
}
/* should not happen but who knows */
if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) {
av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels);
return -1;
}
if(!s->samples){
s->data = av_realloc(s->data, (buf_size + 3) & ~3);
s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2);
s->ptr = s->last_ptr = s->data;
s->data_end = s->data + buf_size;
nblocks = s->samples = bytestream_get_be32(&s->ptr);
n = bytestream_get_be32(&s->ptr);
if(n < 0 || n > 3){
av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n");
s->data = NULL;
return -1;
}
s->ptr += n;
s->currentframeblocks = nblocks;
buf += 4;
if (s->samples <= 0) {
*data_size = 0;
return buf_size;
}
memset(s->decoded0, 0, sizeof(s->decoded0));
memset(s->decoded1, 0, sizeof(s->decoded1));
/* Initialize the frame decoder */
init_frame_decoder(s);
}
if (!s->data) {
*data_size = 0;
return buf_size;
}
nblocks = s->samples;
blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks);
s->error=0;
if ((s->channels == 1) || (s->frameflags & APE_FRAMECODE_PSEUDO_STEREO))
ape_unpack_mono(s, blockstodecode);
else
ape_unpack_stereo(s, blockstodecode);
if(s->error || s->ptr > s->data_end){
s->samples=0;
av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n");
return -1;
}
for (i = 0; i < blockstodecode; i++) {
*samples++ = s->decoded0[i];
if(s->channels == 2)
*samples++ = s->decoded1[i];
}
s->samples -= blockstodecode;
*data_size = blockstodecode * 2 * s->channels;
bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size;
s->last_ptr = s->ptr;
return bytes_used;
}
AVCodec ape_decoder = {
"ape",
CODEC_TYPE_AUDIO,
CODEC_ID_APE,
sizeof(APEContext),
ape_decode_init,
NULL,
ape_decode_close,
ape_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
};
@@ -0,0 +1,453 @@
/*
* copyright (c) 2001 Fabrice Bellard
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file apiexample.c
* avcodec API use example.
*
* Note that this library only handles codecs (mpeg, mpeg4, etc...),
* not file formats (avi, vob, etc...). See library 'libavformat' for the
* format handling
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#define PI 3.14159265358979323846
#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif
#include "avcodec.h"
#define INBUF_SIZE 4096
/*
* Audio encoding example
*/
void audio_encode_example(const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int frame_size, i, j, out_size, outbuf_size;
FILE *f;
short *samples;
float t, tincr;
uint8_t *outbuf;
printf("Audio encoding\n");
/* find the MP2 encoder */
codec = avcodec_find_encoder(CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c= avcodec_alloc_context();
/* put sample parameters */
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
/* the codec gives us the frame size, in samples */
frame_size = c->frame_size;
samples = malloc(frame_size * 2 * c->channels);
outbuf_size = 10000;
outbuf = malloc(outbuf_size);
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
/* encode a single tone sound */
t = 0;
tincr = 2 * PI * 440.0 / c->sample_rate;
for(i=0;i<200;i++) {
for(j=0;j<frame_size;j++) {
samples[2*j] = (int)(sin(t) * 10000);
samples[2*j+1] = samples[2*j];
t += tincr;
}
/* encode the samples */
out_size = avcodec_encode_audio(c, outbuf, outbuf_size, samples);
fwrite(outbuf, 1, out_size, f);
}
fclose(f);
free(outbuf);
free(samples);
avcodec_close(c);
av_free(c);
}
/*
* Audio decoding.
*/
void audio_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int out_size, size, len;
FILE *f, *outfile;
uint8_t *outbuf;
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
printf("Audio decoding\n");
/* find the mpeg audio decoder */
codec = avcodec_find_decoder(CODEC_ID_MP2);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c= avcodec_alloc_context();
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
outfile = fopen(outfilename, "wb");
if (!outfile) {
av_free(c);
exit(1);
}
/* decode until eof */
inbuf_ptr = inbuf;
for(;;) {
size = fread(inbuf, 1, INBUF_SIZE, f);
if (size == 0)
break;
inbuf_ptr = inbuf;
while (size > 0) {
len = avcodec_decode_audio(c, (short *)outbuf, &out_size,
inbuf_ptr, size);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
exit(1);
}
if (out_size > 0) {
/* if a frame has been decoded, output it */
fwrite(outbuf, 1, out_size, outfile);
}
size -= len;
inbuf_ptr += len;
}
}
fclose(outfile);
fclose(f);
free(outbuf);
avcodec_close(c);
av_free(c);
}
/*
* Video encoding example
*/
void video_encode_example(const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, out_size, size, x, y, outbuf_size;
FILE *f;
AVFrame *picture;
uint8_t *outbuf, *picture_buf;
printf("Video encoding\n");
/* find the mpeg1 video encoder */
codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c= avcodec_alloc_context();
picture= avcodec_alloc_frame();
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base= (AVRational){1,25};
c->gop_size = 10; /* emit one intra frame every ten frames */
c->max_b_frames=1;
c->pix_fmt = PIX_FMT_YUV420P;
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
/* alloc image and output buffer */
outbuf_size = 100000;
outbuf = malloc(outbuf_size);
size = c->width * c->height;
picture_buf = malloc((size * 3) / 2); /* size for YUV 420 */
picture->data[0] = picture_buf;
picture->data[1] = picture->data[0] + size;
picture->data[2] = picture->data[1] + size / 4;
picture->linesize[0] = c->width;
picture->linesize[1] = c->width / 2;
picture->linesize[2] = c->width / 2;
/* encode 1 second of video */
for(i=0;i<25;i++) {
fflush(stdout);
/* prepare a dummy image */
/* Y */
for(y=0;y<c->height;y++) {
for(x=0;x<c->width;x++) {
picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
}
}
/* Cb and Cr */
for(y=0;y<c->height/2;y++) {
for(x=0;x<c->width/2;x++) {
picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
}
}
/* encode the image */
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
printf("encoding frame %3d (size=%5d)\n", i, out_size);
fwrite(outbuf, 1, out_size, f);
}
/* get the delayed frames */
for(; out_size; i++) {
fflush(stdout);
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
printf("write frame %3d (size=%5d)\n", i, out_size);
fwrite(outbuf, 1, out_size, f);
}
/* add sequence end code to have a real mpeg file */
outbuf[0] = 0x00;
outbuf[1] = 0x00;
outbuf[2] = 0x01;
outbuf[3] = 0xb7;
fwrite(outbuf, 1, 4, f);
fclose(f);
free(picture_buf);
free(outbuf);
avcodec_close(c);
av_free(c);
av_free(picture);
printf("\n");
}
/*
* Video decoding example
*/
void pgm_save(unsigned char *buf,int wrap, int xsize,int ysize,char *filename)
{
FILE *f;
int i;
f=fopen(filename,"w");
fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
for(i=0;i<ysize;i++)
fwrite(buf + i * wrap,1,xsize,f);
fclose(f);
}
void video_decode_example(const char *outfilename, const char *filename)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int frame, size, got_picture, len;
FILE *f;
AVFrame *picture;
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;
char buf[1024];
/* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
printf("Video decoding\n");
/* find the mpeg1 video decoder */
codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c= avcodec_alloc_context();
picture= avcodec_alloc_frame();
if(codec->capabilities&CODEC_CAP_TRUNCATED)
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
/* For some codecs, such as msmpeg4 and mpeg4, width and height
MUST be initialized there because this information is not
available in the bitstream. */
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
/* the codec gives us the frame size, in samples */
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
frame = 0;
for(;;) {
size = fread(inbuf, 1, INBUF_SIZE, f);
if (size == 0)
break;
/* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
and this is the only method to use them because you cannot
know the compressed data size before analysing it.
BUT some other codecs (msmpeg4, mpeg4) are inherently frame
based, so you must call them with all the data for one
frame exactly. You must also initialize 'width' and
'height' before initializing them. */
/* NOTE2: some codecs allow the raw parameters (frame size,
sample rate) to be changed at any frame. We handle this, so
you should also take care of it */
/* here, we use a stream based decoder (mpeg1video), so we
feed decoder and see if it could decode a frame */
inbuf_ptr = inbuf;
while (size > 0) {
len = avcodec_decode_video(c, picture, &got_picture,
inbuf_ptr, size);
if (len < 0) {
fprintf(stderr, "Error while decoding frame %d\n", frame);
exit(1);
}
if (got_picture) {
printf("saving frame %3d\n", frame);
fflush(stdout);
/* the picture is allocated by the decoder. no need to
free it */
snprintf(buf, sizeof(buf), outfilename, frame);
pgm_save(picture->data[0], picture->linesize[0],
c->width, c->height, buf);
frame++;
}
size -= len;
inbuf_ptr += len;
}
}
/* some codecs, such as MPEG, transmit the I and P frame with a
latency of one frame. You must do the following to have a
chance to get the last frame of the video */
len = avcodec_decode_video(c, picture, &got_picture,
NULL, 0);
if (got_picture) {
printf("saving last frame %3d\n", frame);
fflush(stdout);
/* the picture is allocated by the decoder. no need to
free it */
snprintf(buf, sizeof(buf), outfilename, frame);
pgm_save(picture->data[0], picture->linesize[0],
c->width, c->height, buf);
frame++;
}
fclose(f);
avcodec_close(c);
av_free(c);
av_free(picture);
printf("\n");
}
int main(int argc, char **argv)
{
const char *filename;
/* must be called before using avcodec lib */
avcodec_init();
/* register all the codecs */
avcodec_register_all();
if (argc <= 1) {
audio_encode_example("/tmp/test.mp2");
audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
video_encode_example("/tmp/test.mpg");
filename = "/tmp/test.mpg";
} else {
filename = argv[1];
}
// audio_decode_example("/tmp/test.sw", filename);
video_decode_example("/tmp/test%d.pgm", filename);
return 0;
}
@@ -2,36 +2,39 @@
* ASUS V1/V2 codec
* Copyright (c) 2003 Michael Niedermayer
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file asv1.c
* ASUS V1/V2 codec.
*/
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "mpeg12data.h"
//#undef NDEBUG
//#include <assert.h>
#define VLC_BITS 6
#define ASV2_LEVEL_VLC_BITS 10
typedef struct ASV1Context{
AVCodecContext *avctx;
DSPContext dsp;
@@ -44,11 +47,11 @@ typedef struct ASV1Context{
int mb_height;
int mb_width2;
int mb_height2;
DCTELEM __align8 block[6][64];
uint16_t __align8 intra_matrix[64];
int __align8 q_intra_matrix[64];
DECLARE_ALIGNED_16(DCTELEM, block[6][64]);
DECLARE_ALIGNED_8(uint16_t, intra_matrix[64]);
DECLARE_ALIGNED_8(int, q_intra_matrix[64]);
uint8_t *bitstream_buffer;
int bitstream_buffer_size;
unsigned int bitstream_buffer_size;
} ASV1Context;
static const uint8_t scantab[64]={
@@ -63,29 +66,10 @@ static const uint8_t scantab[64]={
};
static const uint8_t reverse[256]={
0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
};
static const uint8_t ccp_tab[17][2]={
{0x2,2}, {0x7,5}, {0xB,5}, {0x3,5},
{0xD,5}, {0x5,5}, {0x9,5}, {0x1,5},
{0xE,5}, {0x6,5}, {0xA,5}, {0x2,5},
{0xE,5}, {0x6,5}, {0xA,5}, {0x2,5},
{0xC,5}, {0x4,5}, {0x8,5}, {0x3,2},
{0xF,5}, //EOB
};
@@ -129,37 +113,37 @@ static VLC dc_ccp_vlc;
static VLC ac_ccp_vlc;
static VLC asv2_level_vlc;
static void init_vlcs(ASV1Context *a){
static av_cold void init_vlcs(ASV1Context *a){
static int done = 0;
if (!done) {
done = 1;
init_vlc(&ccp_vlc, VLC_BITS, 17,
init_vlc(&ccp_vlc, VLC_BITS, 17,
&ccp_tab[0][1], 2, 1,
&ccp_tab[0][0], 2, 1);
init_vlc(&dc_ccp_vlc, VLC_BITS, 8,
&ccp_tab[0][0], 2, 1, 1);
init_vlc(&dc_ccp_vlc, VLC_BITS, 8,
&dc_ccp_tab[0][1], 2, 1,
&dc_ccp_tab[0][0], 2, 1);
init_vlc(&ac_ccp_vlc, VLC_BITS, 16,
&dc_ccp_tab[0][0], 2, 1, 1);
init_vlc(&ac_ccp_vlc, VLC_BITS, 16,
&ac_ccp_tab[0][1], 2, 1,
&ac_ccp_tab[0][0], 2, 1);
init_vlc(&level_vlc, VLC_BITS, 7,
&ac_ccp_tab[0][0], 2, 1, 1);
init_vlc(&level_vlc, VLC_BITS, 7,
&level_tab[0][1], 2, 1,
&level_tab[0][0], 2, 1);
init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
&level_tab[0][0], 2, 1, 1);
init_vlc(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
&asv2_level_tab[0][1], 2, 1,
&asv2_level_tab[0][0], 2, 1);
&asv2_level_tab[0][0], 2, 1, 1);
}
}
//FIXME write a reversed bitstream reader to avoid the double reverse
static inline int asv2_get_bits(GetBitContext *gb, int n){
return reverse[ get_bits(gb, n) << (8-n) ];
return ff_reverse[ get_bits(gb, n) << (8-n) ];
}
static inline void asv2_put_bits(PutBitContext *pb, int n, int v){
put_bits(pb, n, reverse[ v << (8-n) ]);
put_bits(pb, n, ff_reverse[ v << (8-n) ]);
}
static inline int asv1_get_level(GetBitContext *gb){
@@ -182,7 +166,7 @@ static inline void asv1_put_level(PutBitContext *pb, int level){
if(index <= 6) put_bits(pb, level_tab[index][1], level_tab[index][0]);
else{
put_bits(pb, level_tab[3][1], level_tab[3][0]);
put_bits(pb, 8, level&0xFF);
put_sbits(pb, 8, level);
}
}
@@ -200,7 +184,7 @@ static inline int asv1_decode_block(ASV1Context *a, DCTELEM block[64]){
int i;
block[0]= 8*get_bits(&a->gb, 8);
for(i=0; i<11; i++){
const int ccp= get_vlc2(&a->gb, ccp_vlc.table, VLC_BITS, 1);
@@ -225,9 +209,9 @@ static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){
int i, count, ccp;
count= asv2_get_bits(&a->gb, 4);
block[0]= 8*asv2_get_bits(&a->gb, 8);
ccp= get_vlc2(&a->gb, dc_ccp_vlc.table, VLC_BITS, 1);
if(ccp){
if(ccp&4) block[a->scantable.permutated[1]]= (asv2_get_level(&a->gb) * a->intra_matrix[1])>>4;
@@ -245,17 +229,17 @@ static inline int asv2_decode_block(ASV1Context *a, DCTELEM block[64]){
if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
}
}
return 0;
}
static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
int i;
int nc_count=0;
put_bits(&a->pb, 8, (block[0] + 32)>>6);
block[0]= 0;
for(i=0; i<10; i++){
const int index= scantab[4*i];
int ccp=0;
@@ -266,11 +250,11 @@ static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1;
if(ccp){
for(;nc_count; nc_count--)
for(;nc_count; nc_count--)
put_bits(&a->pb, ccp_tab[0][1], ccp_tab[0][0]);
put_bits(&a->pb, ccp_tab[ccp][1], ccp_tab[ccp][0]);
if(ccp&8) asv1_put_level(&a->pb, block[index + 0]);
if(ccp&4) asv1_put_level(&a->pb, block[index + 8]);
if(ccp&2) asv1_put_level(&a->pb, block[index + 1]);
@@ -285,20 +269,20 @@ static inline void asv1_encode_block(ASV1Context *a, DCTELEM block[64]){
static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
int i;
int count=0;
for(count=63; count>3; count--){
const int index= scantab[count];
if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 )
if( (block[index]*a->q_intra_matrix[index] + (1<<15))>>16 )
break;
}
count >>= 2;
asv2_put_bits(&a->pb, 4, count);
asv2_put_bits(&a->pb, 8, (block[0] + 32)>>6);
block[0]= 0;
for(i=0; i<=count; i++){
const int index= scantab[4*i];
int ccp=0;
@@ -308,6 +292,7 @@ static inline void asv2_encode_block(ASV1Context *a, DCTELEM block[64]){
if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2;
if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1;
assert(i || ccp<8);
if(i) put_bits(&a->pb, ac_ccp_tab[ccp][1], ac_ccp_tab[ccp][0]);
else put_bits(&a->pb, dc_ccp_tab[ccp][1], dc_ccp_tab[ccp][0]);
@@ -324,24 +309,29 @@ static inline int decode_mb(ASV1Context *a, DCTELEM block[6][64]){
int i;
a->dsp.clear_blocks(block[0]);
if(a->avctx->codec_id == CODEC_ID_ASV1){
for(i=0; i<6; i++){
if( asv1_decode_block(a, block[i]) < 0)
if( asv1_decode_block(a, block[i]) < 0)
return -1;
}
}else{
for(i=0; i<6; i++){
if( asv2_decode_block(a, block[i]) < 0)
if( asv2_decode_block(a, block[i]) < 0)
return -1;
}
}
return 0;
}
static inline void encode_mb(ASV1Context *a, DCTELEM block[6][64]){
static inline int encode_mb(ASV1Context *a, DCTELEM block[6][64]){
int i;
if(a->pb.buf_end - a->pb.buf - (put_bits_count(&a->pb)>>3) < 30*16*16*3/2/8){
av_log(a->avctx, AV_LOG_ERROR, "encoded frame too large\n");
return -1;
}
if(a->avctx->codec_id == CODEC_ID_ASV1){
for(i=0; i<6; i++)
asv1_encode_block(a, block[i]);
@@ -349,12 +339,13 @@ static inline void encode_mb(ASV1Context *a, DCTELEM block[6][64]){
for(i=0; i<6; i++)
asv2_encode_block(a, block[i]);
}
return 0;
}
static inline void idct_put(ASV1Context *a, int mb_x, int mb_y){
DCTELEM (*block)[64]= a->block;
int linesize= a->picture.linesize[0];
uint8_t *dest_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16;
uint8_t *dest_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
uint8_t *dest_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
@@ -374,7 +365,7 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
DCTELEM (*block)[64]= a->block;
int linesize= a->picture.linesize[0];
int i;
uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16;
uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8;
uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8;
@@ -385,7 +376,7 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
a->dsp.get_pixels(block[3], ptr_y + 8*linesize + 8, linesize);
for(i=0; i<4; i++)
a->dsp.fdct(block[i]);
if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]);
a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]);
@@ -394,22 +385,15 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){
}
}
static int decode_frame(AVCodecContext *avctx,
static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
ASV1Context * const a = avctx->priv_data;
AVFrame *picture = data;
AVFrame * const p= (AVFrame*)&a->picture;
int mb_x, mb_y;
*data_size = 0;
/* special case for last picture */
if (buf_size == 0) {
return 0;
}
if(p->data[0])
avctx->release_buffer(avctx, p);
@@ -418,17 +402,17 @@ static int decode_frame(AVCodecContext *avctx,
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
p->pict_type= I_TYPE;
p->pict_type= FF_I_TYPE;
p->key_frame= 1;
a->bitstream_buffer= av_fast_realloc(a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
if(avctx->codec_id == CODEC_ID_ASV1)
a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (uint32_t*)buf, buf_size/4);
a->dsp.bswap_buf((uint32_t*)a->bitstream_buffer, (const uint32_t*)buf, buf_size/4);
else{
int i;
for(i=0; i<buf_size; i++)
a->bitstream_buffer[i]= reverse[ buf[i] ];
a->bitstream_buffer[i]= ff_reverse[ buf[i] ];
}
init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
@@ -437,7 +421,7 @@ static int decode_frame(AVCodecContext *avctx,
for(mb_x=0; mb_x<a->mb_width2; mb_x++){
if( decode_mb(a, a->block) <0)
return -1;
idct_put(a, mb_x, mb_y);
}
}
@@ -447,7 +431,7 @@ static int decode_frame(AVCodecContext *avctx,
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
if( decode_mb(a, a->block) <0)
return -1;
idct_put(a, mb_x, mb_y);
}
}
@@ -457,11 +441,11 @@ static int decode_frame(AVCodecContext *avctx,
for(mb_x=0; mb_x<a->mb_width; mb_x++){
if( decode_mb(a, a->block) <0)
return -1;
idct_put(a, mb_x, mb_y);
}
}
#if 0
#if 0
int i;
printf("%d %d\n", 8*buf_size, get_bits_count(&a->gb));
for(i=get_bits_count(&a->gb); i<8*buf_size; i++){
@@ -477,10 +461,11 @@ for(i=0; i<s->avctx->extradata_size; i++){
*data_size = sizeof(AVPicture);
emms_c();
return (get_bits_count(&a->gb)+31)/32*4;
}
#ifdef CONFIG_ENCODERS
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
ASV1Context * const a = avctx->priv_data;
AVFrame *pict = data;
@@ -489,9 +474,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
int mb_x, mb_y;
init_put_bits(&a->pb, buf, buf_size);
*p = *pict;
p->pict_type= I_TYPE;
p->pict_type= FF_I_TYPE;
p->key_frame= 1;
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
@@ -517,25 +502,26 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size,
}
}
emms_c();
align_put_bits(&a->pb);
while(get_bit_count(&a->pb)&31)
while(put_bits_count(&a->pb)&31)
put_bits(&a->pb, 8, 0);
size= get_bit_count(&a->pb)/32;
size= put_bits_count(&a->pb)/32;
if(avctx->codec_id == CODEC_ID_ASV1)
a->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
else{
int i;
for(i=0; i<4*size; i++)
buf[i]= reverse[ buf[i] ];
buf[i]= ff_reverse[ buf[i] ];
}
return size*4;
}
#endif /* CONFIG_ENCODERS */
static void common_init(AVCodecContext *avctx){
static av_cold void common_init(AVCodecContext *avctx){
ASV1Context * const a = avctx->priv_data;
dsputil_init(&a->dsp, avctx);
@@ -549,15 +535,16 @@ static void common_init(AVCodecContext *avctx){
a->avctx= avctx;
}
static int decode_init(AVCodecContext *avctx){
static av_cold int decode_init(AVCodecContext *avctx){
ASV1Context * const a = avctx->priv_data;
AVFrame *p= (AVFrame*)&a->picture;
int i;
const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2;
common_init(avctx);
init_vlcs(a);
ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab);
avctx->pix_fmt= PIX_FMT_YUV420P;
a->inv_qscale= ((uint8_t*)avctx->extradata)[0];
if(a->inv_qscale == 0){
@@ -575,29 +562,30 @@ static int decode_init(AVCodecContext *avctx){
}
p->qstride= a->mb_width;
p->qscale_table= av_mallocz( p->qstride * a->mb_height);
p->qscale_table= av_malloc( p->qstride * a->mb_height);
p->quality= (32*scale + a->inv_qscale/2)/a->inv_qscale;
memset(p->qscale_table, p->quality, p->qstride*a->mb_height);
return 0;
}
static int encode_init(AVCodecContext *avctx){
#ifdef CONFIG_ENCODERS
static av_cold int encode_init(AVCodecContext *avctx){
ASV1Context * const a = avctx->priv_data;
int i;
const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2;
common_init(avctx);
if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE;
a->inv_qscale= (32*scale*FF_QUALITY_SCALE + avctx->global_quality/2) / avctx->global_quality;
avctx->extradata= av_mallocz(8);
avctx->extradata_size=8;
((uint32_t*)avctx->extradata)[0]= le2me_32(a->inv_qscale);
((uint32_t*)avctx->extradata)[1]= le2me_32(ff_get_fourcc("ASUS"));
for(i=0; i<64; i++){
int q= 32*scale*ff_mpeg1_default_intra_matrix[i];
a->q_intra_matrix[i]= ((a->inv_qscale<<16) + q/2) / q;
@@ -605,15 +593,14 @@ static int encode_init(AVCodecContext *avctx){
return 0;
}
#endif
static int decode_end(AVCodecContext *avctx){
static av_cold int decode_end(AVCodecContext *avctx){
ASV1Context * const a = avctx->priv_data;
av_freep(&a->bitstream_buffer);
av_freep(&a->picture.qscale_table);
a->bitstream_buffer_size=0;
avcodec_default_free_buffers(avctx);
return 0;
}
@@ -628,6 +615,7 @@ AVCodec asv1_decoder = {
decode_end,
decode_frame,
CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
};
AVCodec asv2_decoder = {
@@ -640,6 +628,7 @@ AVCodec asv2_decoder = {
decode_end,
decode_frame,
CODEC_CAP_DR1,
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
};
#ifdef CONFIG_ENCODERS
@@ -652,6 +641,8 @@ AVCodec asv1_encoder = {
encode_init,
encode_frame,
//encode_end,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
};
AVCodec asv2_encoder = {
@@ -662,6 +653,8 @@ AVCodec asv2_encoder = {
encode_init,
encode_frame,
//encode_end,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
};
#endif //CONFIG_ENCODERS
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,155 @@
/*
* audio conversion
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file audioconvert.c
* audio conversion
* @author Michael Niedermayer <michaelni@gmx.at>
*/
#include "avcodec.h"
#include "audioconvert.h"
typedef struct SampleFmtInfo {
const char *name;
int bits;
} SampleFmtInfo;
/** this table gives more information about formats */
static const SampleFmtInfo sample_fmt_info[SAMPLE_FMT_NB] = {
[SAMPLE_FMT_U8] = { .name = "u8", .bits = 8 },
[SAMPLE_FMT_S16] = { .name = "s16", .bits = 16 },
[SAMPLE_FMT_S24] = { .name = "s24", .bits = 24 },
[SAMPLE_FMT_S32] = { .name = "s32", .bits = 32 },
[SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32 },
[SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64 },
};
const char *avcodec_get_sample_fmt_name(int sample_fmt)
{
if (sample_fmt < 0 || sample_fmt >= SAMPLE_FMT_NB)
return NULL;
return sample_fmt_info[sample_fmt].name;
}
enum SampleFormat avcodec_get_sample_fmt(const char* name)
{
int i;
for (i=0; i < SAMPLE_FMT_NB; i++)
if (!strcmp(sample_fmt_info[i].name, name))
return i;
return SAMPLE_FMT_NONE;
}
void avcodec_sample_fmt_string (char *buf, int buf_size, int sample_fmt)
{
/* print header */
if (sample_fmt < 0)
snprintf (buf, buf_size, "name " " depth");
else if (sample_fmt < SAMPLE_FMT_NB) {
SampleFmtInfo info= sample_fmt_info[sample_fmt];
snprintf (buf, buf_size, "%-6s" " %2d ", info.name, info.bits);
}
}
struct AVAudioConvert {
int in_channels, out_channels;
int fmt_pair;
};
AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels,
enum SampleFormat in_fmt, int in_channels,
const float *matrix, int flags)
{
AVAudioConvert *ctx;
if (in_channels!=out_channels)
return NULL; /* FIXME: not supported */
ctx = av_malloc(sizeof(AVAudioConvert));
if (!ctx)
return NULL;
ctx->in_channels = in_channels;
ctx->out_channels = out_channels;
ctx->fmt_pair = out_fmt + SAMPLE_FMT_NB*in_fmt;
return ctx;
}
void av_audio_convert_free(AVAudioConvert *ctx)
{
av_free(ctx);
}
int av_audio_convert(AVAudioConvert *ctx,
void * const out[6], const int out_stride[6],
const void * const in[6], const int in_stride[6], int len)
{
int ch;
//FIXME optimize common cases
for(ch=0; ch<ctx->out_channels; ch++){
const int is= in_stride[ch];
const int os= out_stride[ch];
uint8_t *pi= in[ch];
uint8_t *po= out[ch];
uint8_t *end= po + os*len;
if(!out[ch])
continue;
#define CONV(ofmt, otype, ifmt, expr)\
if(ctx->fmt_pair == ofmt + SAMPLE_FMT_NB*ifmt){\
do{\
*(otype*)po = expr; pi += is; po += os;\
}while(po < end);\
}
//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
//FIXME rounding and clipping ?
CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(uint8_t*)pi)
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<8)
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)<<24)
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(int16_t*)pi>>8) + 0x80)
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16, *(int16_t*)pi)
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16, *(int16_t*)pi<<16)
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S16, *(int16_t*)pi*(1.0 / (1<<15)))
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16, *(int16_t*)pi*(1.0 / (1<<15)))
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(int32_t*)pi>>24) + 0x80)
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32, *(int32_t*)pi>>16)
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32, *(int32_t*)pi)
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S32, *(int32_t*)pi*(1.0 / (1<<31)))
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32, *(int32_t*)pi*(1.0 / (1<<31)))
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<7)) + 0x80)
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<15)))
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, lrintf(*(float*)pi * (1<<31)))
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_FLT, *(float*)pi)
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(float*)pi)
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<7)) + 0x80)
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<15)))
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, lrint(*(double*)pi * (1<<31)))
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_DBL, *(double*)pi)
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(double*)pi)
else return -1;
}
return 0;
}
@@ -0,0 +1,162 @@
/*
* AVS video decoder.
* Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
#include "bitstream.h"
typedef struct {
AVFrame picture;
} avs_context_t;
typedef enum {
AVS_VIDEO = 0x01,
AVS_AUDIO = 0x02,
AVS_PALETTE = 0x03,
AVS_GAME_DATA = 0x04,
} avs_block_type_t;
typedef enum {
AVS_I_FRAME = 0x00,
AVS_P_FRAME_3X3 = 0x01,
AVS_P_FRAME_2X2 = 0x02,
AVS_P_FRAME_2X3 = 0x03,
} avs_video_sub_type_t;
static int
avs_decode_frame(AVCodecContext * avctx,
void *data, int *data_size, const uint8_t * buf, int buf_size)
{
avs_context_t *const avs = avctx->priv_data;
AVFrame *picture = data;
AVFrame *const p = (AVFrame *) & avs->picture;
const uint8_t *table, *vect;
uint8_t *out;
int i, j, x, y, stride, vect_w = 3, vect_h = 3;
int sub_type;
avs_block_type_t type;
GetBitContext change_map;
if (avctx->reget_buffer(avctx, p)) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
p->reference = 1;
p->pict_type = FF_P_TYPE;
p->key_frame = 0;
out = avs->picture.data[0];
stride = avs->picture.linesize[0];
sub_type = buf[0];
type = buf[1];
buf += 4;
if (type == AVS_PALETTE) {
int first, last;
uint32_t *pal = (uint32_t *) avs->picture.data[1];
first = AV_RL16(buf);
last = first + AV_RL16(buf + 2);
buf += 4;
for (i=first; i<last; i++, buf+=3)
pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2);
sub_type = buf[0];
type = buf[1];
buf += 4;
}
if (type != AVS_VIDEO)
return -1;
switch (sub_type) {
case AVS_I_FRAME:
p->pict_type = FF_I_TYPE;
p->key_frame = 1;
case AVS_P_FRAME_3X3:
vect_w = 3;
vect_h = 3;
break;
case AVS_P_FRAME_2X2:
vect_w = 2;
vect_h = 2;
break;
case AVS_P_FRAME_2X3:
vect_w = 2;
vect_h = 3;
break;
default:
return -1;
}
table = buf + (256 * vect_w * vect_h);
if (sub_type != AVS_I_FRAME) {
int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h);
init_get_bits(&change_map, table, map_size);
table += map_size;
}
for (y=0; y<198; y+=vect_h) {
for (x=0; x<318; x+=vect_w) {
if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) {
vect = &buf[*table++ * (vect_w * vect_h)];
for (j=0; j<vect_w; j++) {
out[(y + 0) * stride + x + j] = vect[(0 * vect_w) + j];
out[(y + 1) * stride + x + j] = vect[(1 * vect_w) + j];
if (vect_h == 3)
out[(y + 2) * stride + x + j] =
vect[(2 * vect_w) + j];
}
}
}
if (sub_type != AVS_I_FRAME)
align_get_bits(&change_map);
}
*picture = *(AVFrame *) & avs->picture;
*data_size = sizeof(AVPicture);
return buf_size;
}
static av_cold int avs_decode_init(AVCodecContext * avctx)
{
avctx->pix_fmt = PIX_FMT_PAL8;
return 0;
}
AVCodec avs_decoder = {
"avs",
CODEC_TYPE_VIDEO,
CODEC_ID_AVS,
sizeof(avs_context_t),
avs_decode_init,
NULL,
NULL,
avs_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
};