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:
@@ -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 <[email protected]>
|
||||
*
|
||||
* 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 <[email protected]>
|
||||
* 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"),
|
||||
};
|
||||
Reference in New Issue
Block a user