FFMpeg plugin: now build against the optional package for 0.10
* added optional feature package for ffmpeg 0.10 gcc4 and gcc2 * increased probe buffer size to 8K for now. * built the optional packages the default way, it might need adjustments like dependencies on speex, ogg, theora, vorbis, which I left out for now.
This commit is contained in:
@@ -211,6 +211,42 @@ if $(TARGET_ARCH) = x86 {
|
||||
}
|
||||
|
||||
|
||||
# FFmpeg
|
||||
local ffmpegBaseURL = http://haiku-files.org/files/optional-packages ;
|
||||
if $(TARGET_ARCH) = x86 {
|
||||
if $(HAIKU_GCC_VERSION[1]) >= 4 {
|
||||
HAIKU_FFMPEG_FILE = ffmpeg-0.10-x86-gcc4-2012-02-19.zip ;
|
||||
} else {
|
||||
HAIKU_FFMPEG_FILE = ffmpeg-0.10-x86-gcc2-2012-03-07.zip ;
|
||||
}
|
||||
|
||||
local zipFile = [ DownloadFile $(HAIKU_FFMPEG_FILE)
|
||||
: $(ffmpegBaseURL)/$(HAIKU_FFMPEG_FILE) ] ;
|
||||
|
||||
HAIKU_FFMPEG_DIR = [ FDirName $(HAIKU_OPTIONAL_BUILD_PACKAGES_DIR)
|
||||
$(HAIKU_FFMPEG_FILE:B) ] ;
|
||||
|
||||
HAIKU_FFMPEG_HEADERS_DEPENDENCY = [ ExtractArchive $(HAIKU_FFMPEG_DIR)
|
||||
: common/include/ : $(zipFile) : extracted-ffmpeg ] ;
|
||||
|
||||
HAIKU_FFMPEG_LIBS = [ ExtractArchive $(HAIKU_FFMPEG_DIR)
|
||||
:
|
||||
common/lib/libavformat.a
|
||||
common/lib/libavcodec.a
|
||||
common/lib/libavdevice.a
|
||||
common/lib/libavfilter.a
|
||||
common/lib/libswscale.a
|
||||
common/lib/libavutil.a
|
||||
: $(zipFile)
|
||||
: extracted-ffmpeg ] ;
|
||||
|
||||
HAIKU_FFMPEG_HEADERS = [ FDirName $(HAIKU_FFMPEG_DIR) common include ] ;
|
||||
|
||||
} else {
|
||||
Echo "FFMpeg support not available on $(TARGET_ARCH)" ;
|
||||
}
|
||||
|
||||
|
||||
# TagLib
|
||||
|
||||
# Automatically install the TagLib feature, when the optional TagLib optional
|
||||
|
||||
@@ -255,7 +255,7 @@ StreamBase::Open()
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
size_t probeSize = 2048;
|
||||
size_t probeSize = 8192;
|
||||
AVProbeData probeData;
|
||||
probeData.filename = "";
|
||||
probeData.buf = buffer;
|
||||
@@ -417,10 +417,10 @@ StreamBase::FrameRate() const
|
||||
// TODO: Find a way to always calculate a correct frame rate...
|
||||
double frameRate = 1.0;
|
||||
switch (fStream->codec->codec_type) {
|
||||
case CODEC_TYPE_AUDIO:
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
frameRate = (double)fStream->codec->sample_rate;
|
||||
break;
|
||||
case CODEC_TYPE_VIDEO:
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if (fStream->avg_frame_rate.den && fStream->avg_frame_rate.num)
|
||||
frameRate = av_q2d(fStream->avg_frame_rate);
|
||||
else if (fStream->r_frame_rate.den && fStream->r_frame_rate.num)
|
||||
@@ -734,7 +734,7 @@ StreamBase::GetNextChunk(const void** chunkBuffer,
|
||||
break;
|
||||
case B_MEDIA_ENCODED_AUDIO:
|
||||
mediaHeader->u.encoded_audio.buffer_flags
|
||||
= (fPacket.flags & PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0;
|
||||
= (fPacket.flags & AV_PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0;
|
||||
break;
|
||||
case B_MEDIA_RAW_VIDEO:
|
||||
mediaHeader->u.raw_video.line_count
|
||||
@@ -742,7 +742,7 @@ StreamBase::GetNextChunk(const void** chunkBuffer,
|
||||
break;
|
||||
case B_MEDIA_ENCODED_VIDEO:
|
||||
mediaHeader->u.encoded_video.field_flags
|
||||
= (fPacket.flags & PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0;
|
||||
= (fPacket.flags & AV_PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0;
|
||||
mediaHeader->u.encoded_video.line_count
|
||||
= fFormat.u.encoded_video.output.display.line_count;
|
||||
break;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
extern "C" {
|
||||
#include "avcodec.h"
|
||||
#include "libavformat/internal.h"
|
||||
#include "avformat.h"
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,10 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders media shared ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) libavcodec ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) libavformat ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) libavutil ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) libswscale ] ;
|
||||
SubDirC++Flags -D__STDC_CONSTANT_MACROS -Wno-deprecated-declarations ;
|
||||
|
||||
SubDirC++Flags -D__STDC_CONSTANT_MACROS ;
|
||||
|
||||
Addon ffmpeg :
|
||||
AVCodecDecoder.cpp
|
||||
local sources =
|
||||
AVCodecDecoder.cpp
|
||||
AVCodecEncoder.cpp
|
||||
AVFormatReader.cpp
|
||||
AVFormatWriter.cpp
|
||||
@@ -22,6 +17,22 @@ Addon ffmpeg :
|
||||
FFmpegPlugin.cpp
|
||||
MuxerTable.cpp
|
||||
CpuCapabilities.cpp
|
||||
;
|
||||
|
||||
|
||||
SubDirSysHdrs $(HAIKU_FFMPEG_HEADERS) ;
|
||||
Includes [ FGristFiles $(sources) ] : $(HAIKU_FFMPEG_HEADERS_DEPENDENCY) ;
|
||||
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libavcodec ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libavdevice ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libavfilter ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libavformat ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libavutil ] ;
|
||||
UseHeaders [ FDirName $(HAIKU_FFMPEG_HEADERS) libswscale ] ;
|
||||
|
||||
Addon ffmpeg :
|
||||
$(sources)
|
||||
|
||||
gfx_conv_c.cpp
|
||||
gfx_conv_c_lookup.cpp
|
||||
@@ -31,11 +42,9 @@ Addon ffmpeg :
|
||||
yuvrgb_sse2.nasm
|
||||
yuvrgb_ssse3.nasm
|
||||
:
|
||||
libavformat.a
|
||||
libavcodec.a
|
||||
libavcodec_$(TARGET_ARCH).a
|
||||
libavutil.a
|
||||
libswscale.a
|
||||
|
||||
# FFmpeg libraries (from FFmpeg optional package):
|
||||
$(HAIKU_FFMPEG_LIBS)
|
||||
|
||||
libvorbis_ffmpeg.a
|
||||
libspeex_ffmpeg.a
|
||||
@@ -44,9 +53,10 @@ Addon ffmpeg :
|
||||
libbz2_ffmpeg.a
|
||||
|
||||
be
|
||||
libmedia.so
|
||||
media
|
||||
libz.a
|
||||
$(TARGET_LIBSUPC++)
|
||||
$(TARGET_NETWORK_LIBS)
|
||||
;
|
||||
|
||||
# FFmpeg libs configuration is in the config.h header. Architecture specific
|
||||
@@ -112,12 +122,8 @@ if $(HAIKU_INCLUDE_GPL_ADDONS) = 1 {
|
||||
|
||||
HAIKU_FFMPEG_DEFINES = [ FDefines $(HAIKU_FFMPEG_DEFINES) ] ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavcodec ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavformat ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavutil ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libbz2 ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libogg ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libswscale ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libspeex ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libtheora ;
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libvorbis ;
|
||||
|
||||
@@ -1,855 +0,0 @@
|
||||
/*
|
||||
* 4XM codec
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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
|
||||
* 4XM codec.
|
||||
*/
|
||||
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "get_bits.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
//#undef NDEBUG
|
||||
//#include <assert.h>
|
||||
|
||||
#define BLOCK_TYPE_VLC_BITS 5
|
||||
#define ACDC_VLC_BITS 9
|
||||
|
||||
#define CFRAME_BUFFER_COUNT 100
|
||||
|
||||
static const uint8_t block_type_tab[2][4][8][2]={
|
||||
{
|
||||
{ //{8,4,2}x{8,4,2}
|
||||
{ 0,1}, { 2,2}, { 6,3}, {14,4}, {30,5}, {31,5}, { 0,0}
|
||||
},{ //{8,4}x1
|
||||
{ 0,1}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}, { 0,0}
|
||||
},{ //1x{8,4}
|
||||
{ 0,1}, { 2,2}, { 0,0}, { 6,3}, {14,4}, {15,4}, { 0,0}
|
||||
},{ //1x2, 2x1
|
||||
{ 0,1}, { 0,0}, { 0,0}, { 2,2}, { 6,3}, {14,4}, {15,4}
|
||||
}
|
||||
},{
|
||||
{ //{8,4,2}x{8,4,2}
|
||||
{ 1,2}, { 4,3}, { 5,3}, {0,2}, {6,3}, {7,3}, {0,0}
|
||||
},{//{8,4}x1
|
||||
{ 1,2}, { 0,0}, { 2,2}, {0,2}, {6,3}, {7,3}, {0,0}
|
||||
},{//1x{8,4}
|
||||
{ 1,2}, { 2,2}, { 0,0}, {0,2}, {6,3}, {7,3}, {0,0}
|
||||
},{//1x2, 2x1
|
||||
{ 1,2}, { 0,0}, { 0,0}, {0,2}, {2,2}, {6,3}, {7,3}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const uint8_t size2index[4][4]={
|
||||
{-1, 3, 1, 1},
|
||||
{ 3, 0, 0, 0},
|
||||
{ 2, 0, 0, 0},
|
||||
{ 2, 0, 0, 0},
|
||||
};
|
||||
|
||||
static const int8_t mv[256][2]={
|
||||
{ 0, 0},{ 0, -1},{ -1, 0},{ 1, 0},{ 0, 1},{ -1, -1},{ 1, -1},{ -1, 1},
|
||||
{ 1, 1},{ 0, -2},{ -2, 0},{ 2, 0},{ 0, 2},{ -1, -2},{ 1, -2},{ -2, -1},
|
||||
{ 2, -1},{ -2, 1},{ 2, 1},{ -1, 2},{ 1, 2},{ -2, -2},{ 2, -2},{ -2, 2},
|
||||
{ 2, 2},{ 0, -3},{ -3, 0},{ 3, 0},{ 0, 3},{ -1, -3},{ 1, -3},{ -3, -1},
|
||||
{ 3, -1},{ -3, 1},{ 3, 1},{ -1, 3},{ 1, 3},{ -2, -3},{ 2, -3},{ -3, -2},
|
||||
{ 3, -2},{ -3, 2},{ 3, 2},{ -2, 3},{ 2, 3},{ 0, -4},{ -4, 0},{ 4, 0},
|
||||
{ 0, 4},{ -1, -4},{ 1, -4},{ -4, -1},{ 4, -1},{ 4, 1},{ -1, 4},{ 1, 4},
|
||||
{ -3, -3},{ -3, 3},{ 3, 3},{ -2, -4},{ -4, -2},{ 4, -2},{ -4, 2},{ -2, 4},
|
||||
{ 2, 4},{ -3, -4},{ 3, -4},{ 4, -3},{ -5, 0},{ -4, 3},{ -3, 4},{ 3, 4},
|
||||
{ -1, -5},{ -5, -1},{ -5, 1},{ -1, 5},{ -2, -5},{ 2, -5},{ 5, -2},{ 5, 2},
|
||||
{ -4, -4},{ -4, 4},{ -3, -5},{ -5, -3},{ -5, 3},{ 3, 5},{ -6, 0},{ 0, 6},
|
||||
{ -6, -1},{ -6, 1},{ 1, 6},{ 2, -6},{ -6, 2},{ 2, 6},{ -5, -4},{ 5, 4},
|
||||
{ 4, 5},{ -6, -3},{ 6, 3},{ -7, 0},{ -1, -7},{ 5, -5},{ -7, 1},{ -1, 7},
|
||||
{ 4, -6},{ 6, 4},{ -2, -7},{ -7, 2},{ -3, -7},{ 7, -3},{ 3, 7},{ 6, -5},
|
||||
{ 0, -8},{ -1, -8},{ -7, -4},{ -8, 1},{ 4, 7},{ 2, -8},{ -2, 8},{ 6, 6},
|
||||
{ -8, 3},{ 5, -7},{ -5, 7},{ 8, -4},{ 0, -9},{ -9, -1},{ 1, 9},{ 7, -6},
|
||||
{ -7, 6},{ -5, -8},{ -5, 8},{ -9, 3},{ 9, -4},{ 7, -7},{ 8, -6},{ 6, 8},
|
||||
{ 10, 1},{-10, 2},{ 9, -5},{ 10, -3},{ -8, -7},{-10, -4},{ 6, -9},{-11, 0},
|
||||
{ 11, 1},{-11, -2},{ -2, 11},{ 7, -9},{ -7, 9},{ 10, 6},{ -4, 11},{ 8, -9},
|
||||
{ 8, 9},{ 5, 11},{ 7,-10},{ 12, -3},{ 11, 6},{ -9, -9},{ 8, 10},{ 5, 12},
|
||||
{-11, 7},{ 13, 2},{ 6,-12},{ 10, 9},{-11, 8},{ -7, 12},{ 0, 14},{ 14, -2},
|
||||
{ -9, 11},{ -6, 13},{-14, -4},{ -5,-14},{ 5, 14},{-15, -1},{-14, -6},{ 3,-15},
|
||||
{ 11,-11},{ -7, 14},{ -5, 15},{ 8,-14},{ 15, 6},{ 3, 16},{ 7,-15},{-16, 5},
|
||||
{ 0, 17},{-16, -6},{-10, 14},{-16, 7},{ 12, 13},{-16, 8},{-17, 6},{-18, 3},
|
||||
{ -7, 17},{ 15, 11},{ 16, 10},{ 2,-19},{ 3,-19},{-11,-16},{-18, 8},{-19, -6},
|
||||
{ 2,-20},{-17,-11},{-10,-18},{ 8, 19},{-21, -1},{-20, 7},{ -4, 21},{ 21, 5},
|
||||
{ 15, 16},{ 2,-22},{-10,-20},{-22, 5},{ 20,-11},{ -7,-22},{-12, 20},{ 23, -5},
|
||||
{ 13,-20},{ 24, -2},{-15, 19},{-11, 22},{ 16, 19},{ 23,-10},{-18,-18},{ -9,-24},
|
||||
{ 24,-10},{ -3, 26},{-23, 13},{-18,-20},{ 17, 21},{ -4, 27},{ 27, 6},{ 1,-28},
|
||||
{-11, 26},{-17,-23},{ 7, 28},{ 11,-27},{ 29, 5},{-23,-19},{-28,-11},{-21, 22},
|
||||
{-30, 7},{-17, 26},{-27, 16},{ 13, 29},{ 19,-26},{ 10,-31},{-14,-30},{ 20,-27},
|
||||
{-29, 18},{-16,-31},{-28,-22},{ 21,-30},{-25, 28},{ 26,-29},{ 25,-32},{-32,-32}
|
||||
};
|
||||
|
||||
// this is simply the scaled down elementwise product of the standard jpeg quantizer table and the AAN premul table
|
||||
static const uint8_t dequant_table[64]={
|
||||
16, 15, 13, 19, 24, 31, 28, 17,
|
||||
17, 23, 25, 31, 36, 63, 45, 21,
|
||||
18, 24, 27, 37, 52, 59, 49, 20,
|
||||
16, 28, 34, 40, 60, 80, 51, 20,
|
||||
18, 31, 48, 66, 68, 86, 56, 21,
|
||||
19, 38, 56, 59, 64, 64, 48, 20,
|
||||
27, 48, 55, 55, 56, 51, 35, 15,
|
||||
20, 35, 34, 32, 31, 22, 15, 8,
|
||||
};
|
||||
|
||||
static VLC block_type_vlc[2][4];
|
||||
|
||||
|
||||
typedef struct CFrameBuffer{
|
||||
unsigned int allocated_size;
|
||||
unsigned int size;
|
||||
int id;
|
||||
uint8_t *data;
|
||||
}CFrameBuffer;
|
||||
|
||||
typedef struct FourXContext{
|
||||
AVCodecContext *avctx;
|
||||
DSPContext dsp;
|
||||
AVFrame current_picture, last_picture;
|
||||
GetBitContext pre_gb; ///< ac/dc prefix
|
||||
GetBitContext gb;
|
||||
const uint8_t *bytestream;
|
||||
const uint16_t *wordstream;
|
||||
int mv[256];
|
||||
VLC pre_vlc;
|
||||
int last_dc;
|
||||
DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
|
||||
void *bitstream_buffer;
|
||||
unsigned int bitstream_buffer_size;
|
||||
int version;
|
||||
CFrameBuffer cfrm[CFRAME_BUFFER_COUNT];
|
||||
} FourXContext;
|
||||
|
||||
|
||||
#define FIX_1_082392200 70936
|
||||
#define FIX_1_414213562 92682
|
||||
#define FIX_1_847759065 121095
|
||||
#define FIX_2_613125930 171254
|
||||
|
||||
#define MULTIPLY(var,const) (((var)*(const)) >> 16)
|
||||
|
||||
static void idct(DCTELEM block[64]){
|
||||
int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
|
||||
int tmp10, tmp11, tmp12, tmp13;
|
||||
int z5, z10, z11, z12, z13;
|
||||
int i;
|
||||
int temp[64];
|
||||
|
||||
for(i=0; i<8; i++){
|
||||
tmp10 = block[8*0 + i] + block[8*4 + i];
|
||||
tmp11 = block[8*0 + i] - block[8*4 + i];
|
||||
|
||||
tmp13 = block[8*2 + i] + block[8*6 + i];
|
||||
tmp12 = MULTIPLY(block[8*2 + i] - block[8*6 + i], FIX_1_414213562) - tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
z13 = block[8*5 + i] + block[8*3 + i];
|
||||
z10 = block[8*5 + i] - block[8*3 + i];
|
||||
z11 = block[8*1 + i] + block[8*7 + i];
|
||||
z12 = block[8*1 + i] - block[8*7 + i];
|
||||
|
||||
tmp7 = z11 + z13;
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
|
||||
|
||||
tmp6 = tmp12 - tmp7;
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
temp[8*0 + i] = tmp0 + tmp7;
|
||||
temp[8*7 + i] = tmp0 - tmp7;
|
||||
temp[8*1 + i] = tmp1 + tmp6;
|
||||
temp[8*6 + i] = tmp1 - tmp6;
|
||||
temp[8*2 + i] = tmp2 + tmp5;
|
||||
temp[8*5 + i] = tmp2 - tmp5;
|
||||
temp[8*4 + i] = tmp3 + tmp4;
|
||||
temp[8*3 + i] = tmp3 - tmp4;
|
||||
}
|
||||
|
||||
for(i=0; i<8*8; i+=8){
|
||||
tmp10 = temp[0 + i] + temp[4 + i];
|
||||
tmp11 = temp[0 + i] - temp[4 + i];
|
||||
|
||||
tmp13 = temp[2 + i] + temp[6 + i];
|
||||
tmp12 = MULTIPLY(temp[2 + i] - temp[6 + i], FIX_1_414213562) - tmp13;
|
||||
|
||||
tmp0 = tmp10 + tmp13;
|
||||
tmp3 = tmp10 - tmp13;
|
||||
tmp1 = tmp11 + tmp12;
|
||||
tmp2 = tmp11 - tmp12;
|
||||
|
||||
z13 = temp[5 + i] + temp[3 + i];
|
||||
z10 = temp[5 + i] - temp[3 + i];
|
||||
z11 = temp[1 + i] + temp[7 + i];
|
||||
z12 = temp[1 + i] - temp[7 + i];
|
||||
|
||||
tmp7 = z11 + z13;
|
||||
tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562);
|
||||
|
||||
z5 = MULTIPLY(z10 + z12, FIX_1_847759065);
|
||||
tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5;
|
||||
tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5;
|
||||
|
||||
tmp6 = tmp12 - tmp7;
|
||||
tmp5 = tmp11 - tmp6;
|
||||
tmp4 = tmp10 + tmp5;
|
||||
|
||||
block[0 + i] = (tmp0 + tmp7)>>6;
|
||||
block[7 + i] = (tmp0 - tmp7)>>6;
|
||||
block[1 + i] = (tmp1 + tmp6)>>6;
|
||||
block[6 + i] = (tmp1 - tmp6)>>6;
|
||||
block[2 + i] = (tmp2 + tmp5)>>6;
|
||||
block[5 + i] = (tmp2 - tmp5)>>6;
|
||||
block[4 + i] = (tmp3 + tmp4)>>6;
|
||||
block[3 + i] = (tmp3 - tmp4)>>6;
|
||||
}
|
||||
}
|
||||
|
||||
static av_cold void init_vlcs(FourXContext *f){
|
||||
static VLC_TYPE table[8][32][2];
|
||||
int i;
|
||||
|
||||
for(i=0; i<8; i++){
|
||||
block_type_vlc[0][i].table= table[i];
|
||||
block_type_vlc[0][i].table_allocated= 32;
|
||||
init_vlc(&block_type_vlc[0][i], BLOCK_TYPE_VLC_BITS, 7,
|
||||
&block_type_tab[0][i][0][1], 2, 1,
|
||||
&block_type_tab[0][i][0][0], 2, 1, INIT_VLC_USE_NEW_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_mv(FourXContext *f){
|
||||
int i;
|
||||
|
||||
for(i=0; i<256; i++){
|
||||
if(f->version>1)
|
||||
f->mv[i] = mv[i][0] + mv[i][1] *f->current_picture.linesize[0]/2;
|
||||
else
|
||||
f->mv[i] = (i&15) - 8 + ((i>>4)-8)*f->current_picture.linesize[0]/2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w, int h, int stride, int scale, int dc){
|
||||
int i;
|
||||
dc*= 0x10001;
|
||||
|
||||
switch(log2w){
|
||||
case 0:
|
||||
for(i=0; i<h; i++){
|
||||
dst[0] = scale*src[0] + dc;
|
||||
if(scale) src += stride;
|
||||
dst += stride;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for(i=0; i<h; i++){
|
||||
((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
|
||||
if(scale) src += stride;
|
||||
dst += stride;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for(i=0; i<h; i++){
|
||||
((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
|
||||
((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
|
||||
if(scale) src += stride;
|
||||
dst += stride;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
for(i=0; i<h; i++){
|
||||
((uint32_t*)dst)[0] = scale*((uint32_t*)src)[0] + dc;
|
||||
((uint32_t*)dst)[1] = scale*((uint32_t*)src)[1] + dc;
|
||||
((uint32_t*)dst)[2] = scale*((uint32_t*)src)[2] + dc;
|
||||
((uint32_t*)dst)[3] = scale*((uint32_t*)src)[3] + dc;
|
||||
if(scale) src += stride;
|
||||
dst += stride;
|
||||
}
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride){
|
||||
const int index= size2index[log2h][log2w];
|
||||
const int h= 1<<log2h;
|
||||
int code= get_vlc2(&f->gb, block_type_vlc[1-(f->version>1)][index].table, BLOCK_TYPE_VLC_BITS, 1);
|
||||
uint16_t *start= (uint16_t*)f->last_picture.data[0];
|
||||
uint16_t *end= start + stride*(f->avctx->height-h+1) - (1<<log2w);
|
||||
|
||||
assert(code>=0 && code<=6);
|
||||
|
||||
if(code == 0){
|
||||
src += f->mv[ *f->bytestream++ ];
|
||||
if(start > src || src > end){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
||||
return;
|
||||
}
|
||||
mcdc(dst, src, log2w, h, stride, 1, 0);
|
||||
}else if(code == 1){
|
||||
log2h--;
|
||||
decode_p_block(f, dst , src , log2w, log2h, stride);
|
||||
decode_p_block(f, dst + (stride<<log2h), src + (stride<<log2h), log2w, log2h, stride);
|
||||
}else if(code == 2){
|
||||
log2w--;
|
||||
decode_p_block(f, dst , src , log2w, log2h, stride);
|
||||
decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride);
|
||||
}else if(code == 3 && f->version<2){
|
||||
mcdc(dst, src, log2w, h, stride, 1, 0);
|
||||
}else if(code == 4){
|
||||
src += f->mv[ *f->bytestream++ ];
|
||||
if(start > src || src > end){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
|
||||
return;
|
||||
}
|
||||
mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
|
||||
}else if(code == 5){
|
||||
mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
|
||||
}else if(code == 6){
|
||||
if(log2w){
|
||||
dst[0] = le2me_16(*f->wordstream++);
|
||||
dst[1] = le2me_16(*f->wordstream++);
|
||||
}else{
|
||||
dst[0 ] = le2me_16(*f->wordstream++);
|
||||
dst[stride] = le2me_16(*f->wordstream++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
|
||||
int x, y;
|
||||
const int width= f->avctx->width;
|
||||
const int height= f->avctx->height;
|
||||
uint16_t *src= (uint16_t*)f->last_picture.data[0];
|
||||
uint16_t *dst= (uint16_t*)f->current_picture.data[0];
|
||||
const int stride= f->current_picture.linesize[0]>>1;
|
||||
unsigned int bitstream_size, bytestream_size, wordstream_size, extra;
|
||||
|
||||
if(f->version>1){
|
||||
extra=20;
|
||||
bitstream_size= AV_RL32(buf+8);
|
||||
wordstream_size= AV_RL32(buf+12);
|
||||
bytestream_size= AV_RL32(buf+16);
|
||||
}else{
|
||||
extra=0;
|
||||
bitstream_size = AV_RL16(buf-4);
|
||||
wordstream_size= AV_RL16(buf-2);
|
||||
bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
|
||||
}
|
||||
|
||||
if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
|
||||
|| bitstream_size > (1<<26)
|
||||
|| bytestream_size > (1<<26)
|
||||
|| wordstream_size > (1<<26)
|
||||
){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
|
||||
bitstream_size+ bytestream_size+ wordstream_size - length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, bitstream_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!f->bitstream_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4);
|
||||
init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
|
||||
|
||||
f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
|
||||
f->bytestream= buf + extra + bitstream_size + wordstream_size;
|
||||
|
||||
init_mv(f);
|
||||
|
||||
for(y=0; y<height; y+=8){
|
||||
for(x=0; x<width; x+=8){
|
||||
decode_p_block(f, dst + x, src + x, 3, 3, stride);
|
||||
}
|
||||
src += 8*stride;
|
||||
dst += 8*stride;
|
||||
}
|
||||
|
||||
if( bitstream_size != (get_bits_count(&f->gb)+31)/32*4
|
||||
|| (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size
|
||||
|| (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size)
|
||||
av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n",
|
||||
bitstream_size - (get_bits_count(&f->gb)+31)/32*4,
|
||||
-(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size),
|
||||
-(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size)
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode block and dequantize.
|
||||
* Note this is almost identical to MJPEG.
|
||||
*/
|
||||
static int decode_i_block(FourXContext *f, DCTELEM *block){
|
||||
int code, i, j, level, val;
|
||||
|
||||
/* DC coef */
|
||||
val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
|
||||
if (val>>4){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");
|
||||
}
|
||||
|
||||
if(val)
|
||||
val = get_xbits(&f->gb, val);
|
||||
|
||||
val = val * dequant_table[0] + f->last_dc;
|
||||
f->last_dc =
|
||||
block[0] = val;
|
||||
/* AC coefs */
|
||||
i = 1;
|
||||
for(;;) {
|
||||
code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
|
||||
|
||||
/* EOB */
|
||||
if (code == 0)
|
||||
break;
|
||||
if (code == 0xf0) {
|
||||
i += 16;
|
||||
} else {
|
||||
level = get_xbits(&f->gb, code & 0xf);
|
||||
i += code >> 4;
|
||||
if (i >= 64) {
|
||||
av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
j= ff_zigzag_direct[i];
|
||||
block[j] = level * dequant_table[j];
|
||||
i++;
|
||||
if (i >= 64)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void idct_put(FourXContext *f, int x, int y){
|
||||
DCTELEM (*block)[64]= f->block;
|
||||
int stride= f->current_picture.linesize[0]>>1;
|
||||
int i;
|
||||
uint16_t *dst = ((uint16_t*)f->current_picture.data[0]) + y * stride + x;
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
block[i][0] += 0x80*8*8;
|
||||
idct(block[i]);
|
||||
}
|
||||
|
||||
if(!(f->avctx->flags&CODEC_FLAG_GRAY)){
|
||||
for(i=4; i<6; i++) idct(block[i]);
|
||||
}
|
||||
|
||||
/* Note transform is:
|
||||
y= ( 1b + 4g + 2r)/14
|
||||
cb=( 3b - 2g - 1r)/14
|
||||
cr=(-1b - 4g + 5r)/14
|
||||
*/
|
||||
for(y=0; y<8; y++){
|
||||
for(x=0; x<8; x++){
|
||||
DCTELEM *temp= block[(x>>2) + 2*(y>>2)] + 2*(x&3) + 2*8*(y&3); //FIXME optimize
|
||||
int cb= block[4][x + 8*y];
|
||||
int cr= block[5][x + 8*y];
|
||||
int cg= (cb + cr)>>1;
|
||||
int y;
|
||||
|
||||
cb+=cb;
|
||||
|
||||
y = temp[0];
|
||||
dst[0 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
|
||||
y = temp[1];
|
||||
dst[1 ]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
|
||||
y = temp[8];
|
||||
dst[ stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
|
||||
y = temp[9];
|
||||
dst[1+stride]= ((y+cb)>>3) + (((y-cg)&0xFC)<<3) + (((y+cr)&0xF8)<<8);
|
||||
dst += 2;
|
||||
}
|
||||
dst += 2*stride - 2*8;
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_i_mb(FourXContext *f){
|
||||
int i;
|
||||
|
||||
f->dsp.clear_blocks(f->block[0]);
|
||||
|
||||
for(i=0; i<6; i++){
|
||||
if(decode_i_block(f, f->block[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){
|
||||
int frequency[512];
|
||||
uint8_t flag[512];
|
||||
int up[512];
|
||||
uint8_t len_tab[257];
|
||||
int bits_tab[257];
|
||||
int start, end;
|
||||
const uint8_t *ptr= buf;
|
||||
int j;
|
||||
|
||||
memset(frequency, 0, sizeof(frequency));
|
||||
memset(up, -1, sizeof(up));
|
||||
|
||||
start= *ptr++;
|
||||
end= *ptr++;
|
||||
for(;;){
|
||||
int i;
|
||||
|
||||
for(i=start; i<=end; i++){
|
||||
frequency[i]= *ptr++;
|
||||
}
|
||||
start= *ptr++;
|
||||
if(start==0) break;
|
||||
|
||||
end= *ptr++;
|
||||
}
|
||||
frequency[256]=1;
|
||||
|
||||
while((ptr - buf)&3) ptr++; // 4byte align
|
||||
|
||||
for(j=257; j<512; j++){
|
||||
int min_freq[2]= {256*256, 256*256};
|
||||
int smallest[2]= {0, 0};
|
||||
int i;
|
||||
for(i=0; i<j; i++){
|
||||
if(frequency[i] == 0) continue;
|
||||
if(frequency[i] < min_freq[1]){
|
||||
if(frequency[i] < min_freq[0]){
|
||||
min_freq[1]= min_freq[0]; smallest[1]= smallest[0];
|
||||
min_freq[0]= frequency[i];smallest[0]= i;
|
||||
}else{
|
||||
min_freq[1]= frequency[i];smallest[1]= i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(min_freq[1] == 256*256) break;
|
||||
|
||||
frequency[j]= min_freq[0] + min_freq[1];
|
||||
flag[ smallest[0] ]= 0;
|
||||
flag[ smallest[1] ]= 1;
|
||||
up[ smallest[0] ]=
|
||||
up[ smallest[1] ]= j;
|
||||
frequency[ smallest[0] ]= frequency[ smallest[1] ]= 0;
|
||||
}
|
||||
|
||||
for(j=0; j<257; j++){
|
||||
int node;
|
||||
int len=0;
|
||||
int bits=0;
|
||||
|
||||
for(node= j; up[node] != -1; node= up[node]){
|
||||
bits += flag[node]<<len;
|
||||
len++;
|
||||
if(len > 31) av_log(f->avctx, AV_LOG_ERROR, "vlc length overflow\n"); //can this happen at all ?
|
||||
}
|
||||
|
||||
bits_tab[j]= bits;
|
||||
len_tab[j]= len;
|
||||
}
|
||||
|
||||
init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257,
|
||||
len_tab , 1, 1,
|
||||
bits_tab, 4, 4, 0);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int mix(int c0, int c1){
|
||||
int blue = 2*(c0&0x001F) + (c1&0x001F);
|
||||
int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5;
|
||||
int red = 2*(c0>>10) + (c1>>10);
|
||||
return red/3*1024 + green/3*32 + blue/3;
|
||||
}
|
||||
|
||||
static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
|
||||
int x, y, x2, y2;
|
||||
const int width= f->avctx->width;
|
||||
const int height= f->avctx->height;
|
||||
uint16_t *dst= (uint16_t*)f->current_picture.data[0];
|
||||
const int stride= f->current_picture.linesize[0]>>1;
|
||||
|
||||
for(y=0; y<height; y+=16){
|
||||
for(x=0; x<width; x+=16){
|
||||
unsigned int color[4], bits;
|
||||
memset(color, 0, sizeof(color));
|
||||
//warning following is purely guessed ...
|
||||
color[0]= bytestream_get_le16(&buf);
|
||||
color[1]= bytestream_get_le16(&buf);
|
||||
|
||||
if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");
|
||||
if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");
|
||||
|
||||
color[2]= mix(color[0], color[1]);
|
||||
color[3]= mix(color[1], color[0]);
|
||||
|
||||
bits= bytestream_get_le32(&buf);
|
||||
for(y2=0; y2<16; y2++){
|
||||
for(x2=0; x2<16; x2++){
|
||||
int index= 2*(x2>>2) + 8*(y2>>2);
|
||||
dst[y2*stride+x2]= color[(bits>>index)&3];
|
||||
}
|
||||
}
|
||||
dst+=16;
|
||||
}
|
||||
dst += 16*stride - width;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
|
||||
int x, y;
|
||||
const int width= f->avctx->width;
|
||||
const int height= f->avctx->height;
|
||||
uint16_t *dst= (uint16_t*)f->current_picture.data[0];
|
||||
const int stride= f->current_picture.linesize[0]>>1;
|
||||
const unsigned int bitstream_size= AV_RL32(buf);
|
||||
const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
|
||||
unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
|
||||
const uint8_t *prestream= buf + bitstream_size + 12;
|
||||
|
||||
if(prestream_size + bitstream_size + 12 != length
|
||||
|| bitstream_size > (1<<26)
|
||||
|| prestream_size > (1<<26)){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
prestream= read_huffman_tables(f, prestream);
|
||||
|
||||
init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
|
||||
|
||||
prestream_size= length + buf - prestream;
|
||||
|
||||
av_fast_malloc(&f->bitstream_buffer, &f->bitstream_buffer_size, prestream_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!f->bitstream_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4);
|
||||
init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size);
|
||||
|
||||
f->last_dc= 0*128*8*8;
|
||||
|
||||
for(y=0; y<height; y+=16){
|
||||
for(x=0; x<width; x+=16){
|
||||
if(decode_i_mb(f) < 0)
|
||||
return -1;
|
||||
|
||||
idct_put(f, x, y);
|
||||
}
|
||||
dst += 16*stride;
|
||||
}
|
||||
|
||||
if(get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3) != 256)
|
||||
av_log(f->avctx, AV_LOG_ERROR, "end mismatch\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
AVFrame *picture = data;
|
||||
AVFrame *p, temp;
|
||||
int i, frame_4cc, frame_size;
|
||||
|
||||
frame_4cc= AV_RL32(buf);
|
||||
if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4));
|
||||
}
|
||||
|
||||
if(frame_4cc == AV_RL32("cfrm")){
|
||||
int free_index=-1;
|
||||
const int data_size= buf_size - 20;
|
||||
const int id= AV_RL32(buf+12);
|
||||
const int whole_size= AV_RL32(buf+16);
|
||||
CFrameBuffer *cfrm;
|
||||
|
||||
for(i=0; i<CFRAME_BUFFER_COUNT; i++){
|
||||
if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
|
||||
av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
|
||||
}
|
||||
|
||||
for(i=0; i<CFRAME_BUFFER_COUNT; i++){
|
||||
if(f->cfrm[i].id == id) break;
|
||||
if(f->cfrm[i].size == 0 ) free_index= i;
|
||||
}
|
||||
|
||||
if(i>=CFRAME_BUFFER_COUNT){
|
||||
i= free_index;
|
||||
f->cfrm[i].id= id;
|
||||
}
|
||||
cfrm= &f->cfrm[i];
|
||||
|
||||
cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
|
||||
av_log(f->avctx, AV_LOG_ERROR, "realloc falure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(cfrm->data + cfrm->size, buf+20, data_size);
|
||||
cfrm->size += data_size;
|
||||
|
||||
if(cfrm->size >= whole_size){
|
||||
buf= cfrm->data;
|
||||
frame_size= cfrm->size;
|
||||
|
||||
if(id != avctx->frame_number){
|
||||
av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number);
|
||||
}
|
||||
|
||||
cfrm->size= cfrm->id= 0;
|
||||
frame_4cc= AV_RL32("pfrm");
|
||||
}else
|
||||
return buf_size;
|
||||
}else{
|
||||
buf= buf + 12;
|
||||
frame_size= buf_size - 12;
|
||||
}
|
||||
|
||||
temp= f->current_picture;
|
||||
f->current_picture= f->last_picture;
|
||||
f->last_picture= temp;
|
||||
|
||||
p= &f->current_picture;
|
||||
avctx->coded_frame= p;
|
||||
|
||||
avctx->flags |= CODEC_FLAG_EMU_EDGE; // alternatively we would have to use our own buffer management
|
||||
|
||||
if(p->data[0])
|
||||
avctx->release_buffer(avctx, p);
|
||||
|
||||
p->reference= 1;
|
||||
if(avctx->get_buffer(avctx, p) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(frame_4cc == AV_RL32("ifr2")){
|
||||
p->pict_type= FF_I_TYPE;
|
||||
if(decode_i2_frame(f, buf-4, frame_size) < 0)
|
||||
return -1;
|
||||
}else if(frame_4cc == AV_RL32("ifrm")){
|
||||
p->pict_type= FF_I_TYPE;
|
||||
if(decode_i_frame(f, buf, frame_size) < 0)
|
||||
return -1;
|
||||
}else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){
|
||||
p->pict_type= FF_P_TYPE;
|
||||
if(decode_p_frame(f, buf, frame_size) < 0)
|
||||
return -1;
|
||||
}else if(frame_4cc == AV_RL32("snd_")){
|
||||
av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size);
|
||||
}else{
|
||||
av_log(avctx, AV_LOG_ERROR, "ignoring unknown chunk length:%d\n", buf_size);
|
||||
}
|
||||
|
||||
p->key_frame= p->pict_type == FF_I_TYPE;
|
||||
|
||||
*picture= *p;
|
||||
*data_size = sizeof(AVPicture);
|
||||
|
||||
emms_c();
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
|
||||
static av_cold void common_init(AVCodecContext *avctx){
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
|
||||
dsputil_init(&f->dsp, avctx);
|
||||
|
||||
f->avctx= avctx;
|
||||
}
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx){
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
|
||||
if(avctx->extradata_size != 4 || !avctx->extradata) {
|
||||
av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
f->version= AV_RL32(avctx->extradata)>>16;
|
||||
common_init(avctx);
|
||||
init_vlcs(f);
|
||||
|
||||
if(f->version>2) avctx->pix_fmt= PIX_FMT_RGB565;
|
||||
else avctx->pix_fmt= PIX_FMT_BGR555;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx){
|
||||
FourXContext * const f = avctx->priv_data;
|
||||
int i;
|
||||
|
||||
av_freep(&f->bitstream_buffer);
|
||||
f->bitstream_buffer_size=0;
|
||||
for(i=0; i<CFRAME_BUFFER_COUNT; i++){
|
||||
av_freep(&f->cfrm[i].data);
|
||||
f->cfrm[i].allocated_size= 0;
|
||||
}
|
||||
free_vlc(&f->pre_vlc);
|
||||
if(f->current_picture.data[0])
|
||||
avctx->release_buffer(avctx, &f->current_picture);
|
||||
if(f->last_picture.data[0])
|
||||
avctx->release_buffer(avctx, &f->last_picture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec fourxm_decoder = {
|
||||
"4xm",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_4XM,
|
||||
sizeof(FourXContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("4X Movie"),
|
||||
};
|
||||
|
||||
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Quicktime Planar RGB (8BPS) Video Decoder
|
||||
* Copyright (C) 2003 Roberto Togni
|
||||
*
|
||||
* 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
|
||||
* QT 8BPS Video Decoder by Roberto Togni
|
||||
* For more information about the 8BPS format, visit:
|
||||
* http://www.pcisys.net/~melanson/codecs/
|
||||
*
|
||||
* Supports: PAL8 (RGB 8bpp, paletted)
|
||||
* : BGR24 (RGB 24bpp) (can also output it as RGB32)
|
||||
* : RGB32 (RGB 32bpp, 4th plane is probably alpha and it's ignored)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
|
||||
|
||||
static const enum PixelFormat pixfmt_rgb24[] = {PIX_FMT_BGR24, PIX_FMT_RGB32, PIX_FMT_NONE};
|
||||
|
||||
/*
|
||||
* Decoder context
|
||||
*/
|
||||
typedef struct EightBpsContext {
|
||||
|
||||
AVCodecContext *avctx;
|
||||
AVFrame pic;
|
||||
|
||||
unsigned char planes;
|
||||
unsigned char planemap[4];
|
||||
} EightBpsContext;
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Decode a frame
|
||||
*
|
||||
*/
|
||||
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
EightBpsContext * const c = avctx->priv_data;
|
||||
const unsigned char *encoded = buf;
|
||||
unsigned char *pixptr, *pixptr_end;
|
||||
unsigned int height = avctx->height; // Real image height
|
||||
unsigned int dlen, p, row;
|
||||
const unsigned char *lp, *dp;
|
||||
unsigned char count;
|
||||
unsigned int px_inc;
|
||||
unsigned int planes = c->planes;
|
||||
unsigned char *planemap = c->planemap;
|
||||
|
||||
if(c->pic.data[0])
|
||||
avctx->release_buffer(avctx, &c->pic);
|
||||
|
||||
c->pic.reference = 0;
|
||||
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
|
||||
if(avctx->get_buffer(avctx, &c->pic) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set data pointer after line lengths */
|
||||
dp = encoded + planes * (height << 1);
|
||||
|
||||
/* Ignore alpha plane, don't know what to do with it */
|
||||
if (planes == 4)
|
||||
planes--;
|
||||
|
||||
px_inc = planes + (avctx->pix_fmt == PIX_FMT_RGB32);
|
||||
|
||||
for (p = 0; p < planes; p++) {
|
||||
/* Lines length pointer for this plane */
|
||||
lp = encoded + p * (height << 1);
|
||||
|
||||
/* Decode a plane */
|
||||
for(row = 0; row < height; row++) {
|
||||
pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p];
|
||||
pixptr_end = pixptr + c->pic.linesize[0];
|
||||
dlen = be2me_16(*(const unsigned short *)(lp+row*2));
|
||||
/* Decode a row of this plane */
|
||||
while(dlen > 0) {
|
||||
if(dp + 1 >= buf+buf_size) return -1;
|
||||
if ((count = *dp++) <= 127) {
|
||||
count++;
|
||||
dlen -= count + 1;
|
||||
if (pixptr + count * px_inc > pixptr_end)
|
||||
break;
|
||||
if(dp + count > buf+buf_size) return -1;
|
||||
while(count--) {
|
||||
*pixptr = *dp++;
|
||||
pixptr += px_inc;
|
||||
}
|
||||
} else {
|
||||
count = 257 - count;
|
||||
if (pixptr + count * px_inc > pixptr_end)
|
||||
break;
|
||||
while(count--) {
|
||||
*pixptr = *dp;
|
||||
pixptr += px_inc;
|
||||
}
|
||||
dp++;
|
||||
dlen -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (avctx->palctrl) {
|
||||
memcpy (c->pic.data[1], avctx->palctrl->palette, AVPALETTE_SIZE);
|
||||
if (avctx->palctrl->palette_changed) {
|
||||
c->pic.palette_has_changed = 1;
|
||||
avctx->palctrl->palette_changed = 0;
|
||||
} else
|
||||
c->pic.palette_has_changed = 0;
|
||||
}
|
||||
|
||||
*data_size = sizeof(AVFrame);
|
||||
*(AVFrame*)data = c->pic;
|
||||
|
||||
/* always report that the buffer was completely consumed */
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Init 8BPS decoder
|
||||
*
|
||||
*/
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
EightBpsContext * const c = avctx->priv_data;
|
||||
|
||||
c->avctx = avctx;
|
||||
|
||||
c->pic.data[0] = NULL;
|
||||
|
||||
switch (avctx->bits_per_coded_sample) {
|
||||
case 8:
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
c->planes = 1;
|
||||
c->planemap[0] = 0; // 1st plane is palette indexes
|
||||
if (avctx->palctrl == NULL) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error: PAL8 format but no palette from demuxer.\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
avctx->pix_fmt = avctx->get_format(avctx, pixfmt_rgb24);
|
||||
c->planes = 3;
|
||||
c->planemap[0] = 2; // 1st plane is red
|
||||
c->planemap[1] = 1; // 2nd plane is green
|
||||
c->planemap[2] = 0; // 3rd plane is blue
|
||||
break;
|
||||
case 32:
|
||||
avctx->pix_fmt = PIX_FMT_RGB32;
|
||||
c->planes = 4;
|
||||
#if HAVE_BIGENDIAN
|
||||
c->planemap[0] = 1; // 1st plane is red
|
||||
c->planemap[1] = 2; // 2nd plane is green
|
||||
c->planemap[2] = 3; // 3rd plane is blue
|
||||
c->planemap[3] = 0; // 4th plane is alpha???
|
||||
#else
|
||||
c->planemap[0] = 2; // 1st plane is red
|
||||
c->planemap[1] = 1; // 2nd plane is green
|
||||
c->planemap[2] = 0; // 3rd plane is blue
|
||||
c->planemap[3] = 3; // 4th plane is alpha???
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "Error: Unsupported color depth: %u.\n", avctx->bits_per_coded_sample);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Uninit 8BPS decoder
|
||||
*
|
||||
*/
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
EightBpsContext * const c = avctx->priv_data;
|
||||
|
||||
if (c->pic.data[0])
|
||||
avctx->release_buffer(avctx, &c->pic);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AVCodec eightbps_decoder = {
|
||||
"8bps",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_8BPS,
|
||||
sizeof(EightBpsContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("QuickTime 8BPS video"),
|
||||
};
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 8SVX audio decoder
|
||||
* Copyright (C) 2008 Jaikrishnan Menon
|
||||
*
|
||||
* 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
|
||||
* 8svx audio decoder
|
||||
* @author Jaikrishnan Menon
|
||||
* supports: fibonacci delta encoding
|
||||
* : exponential encoding
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
/** decoder context */
|
||||
typedef struct EightSvxContext {
|
||||
int16_t fib_acc;
|
||||
const int16_t *table;
|
||||
} EightSvxContext;
|
||||
|
||||
static const int16_t fibonacci[16] = { -34<<8, -21<<8, -13<<8, -8<<8, -5<<8, -3<<8, -2<<8, -1<<8,
|
||||
0, 1<<8, 2<<8, 3<<8, 5<<8, 8<<8, 13<<8, 21<<8 };
|
||||
static const int16_t exponential[16] = { -128<<8, -64<<8, -32<<8, -16<<8, -8<<8, -4<<8, -2<<8, -1<<8,
|
||||
0, 1<<8, 2<<8, 4<<8, 8<<8, 16<<8, 32<<8, 64<<8 };
|
||||
|
||||
/** decode a frame */
|
||||
static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
EightSvxContext *esc = avctx->priv_data;
|
||||
int16_t *out_data = data;
|
||||
int consumed = buf_size;
|
||||
const uint8_t *buf_end = buf + buf_size;
|
||||
|
||||
if((*data_size >> 2) < buf_size)
|
||||
return -1;
|
||||
|
||||
if(avctx->frame_number == 0) {
|
||||
esc->fib_acc = buf[1] << 8;
|
||||
buf_size -= 2;
|
||||
buf += 2;
|
||||
}
|
||||
|
||||
*data_size = buf_size << 2;
|
||||
|
||||
while(buf < buf_end) {
|
||||
uint8_t d = *buf++;
|
||||
esc->fib_acc += esc->table[d & 0x0f];
|
||||
*out_data++ = esc->fib_acc;
|
||||
esc->fib_acc += esc->table[d >> 4];
|
||||
*out_data++ = esc->fib_acc;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
/** initialize 8svx decoder */
|
||||
static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
EightSvxContext *esc = avctx->priv_data;
|
||||
|
||||
switch(avctx->codec->id) {
|
||||
case CODEC_ID_8SVX_FIB:
|
||||
esc->table = fibonacci;
|
||||
break;
|
||||
case CODEC_ID_8SVX_EXP:
|
||||
esc->table = exponential;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
avctx->sample_fmt = SAMPLE_FMT_S16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec eightsvx_fib_decoder = {
|
||||
.name = "8svx_fib",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = CODEC_ID_8SVX_FIB,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
.init = eightsvx_decode_init,
|
||||
.decode = eightsvx_decode_frame,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
|
||||
};
|
||||
|
||||
AVCodec eightsvx_exp_decoder = {
|
||||
.name = "8svx_exp",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = CODEC_ID_8SVX_EXP,
|
||||
.priv_data_size = sizeof (EightSvxContext),
|
||||
.init = eightsvx_decode_init,
|
||||
.decode = eightsvx_decode_frame,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("8SVX exponential"),
|
||||
};
|
||||
@@ -1,392 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons media plugins ffmpeg libavcodec ;
|
||||
|
||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) $(TARGET_ARCH) ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libavutil ] ;
|
||||
SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) libswscale ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libogg include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libtheora include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libvorbis include ] ;
|
||||
SubDirSysHdrs [ FDirName $(SUBDIR) $(DOTDOT) libspeex include ] ;
|
||||
|
||||
|
||||
UseLibraryHeaders zlib ;
|
||||
|
||||
# filter warnings we don't want here
|
||||
TARGET_WARNING_CCFLAGS = [ FFilter $(TARGET_WARNING_CCFLAGS)
|
||||
: -Wall -Wmissing-prototypes -Wsign-compare -Wpointer-arith ] ;
|
||||
|
||||
# Some targets in this subdir fail to build with DEBUG=1
|
||||
DEBUG = 0 ;
|
||||
|
||||
SubDirCcFlags $(HAIKU_FFMPEG_GCC_EXTRA_FLAGS) ;
|
||||
SubDirCcFlags $(HAIKU_FFMPEG_DEFINES) ;
|
||||
SubDirC++Flags $(HAIKU_FFMPEG_DEFINES) ;
|
||||
|
||||
|
||||
StaticLibrary libavcodec.a :
|
||||
4xm.c
|
||||
8bps.c
|
||||
8svx.c
|
||||
aac_ac3_parser.c
|
||||
aac_adtstoasc_bsf.c
|
||||
aac_parser.c
|
||||
aaccoder.c
|
||||
aacdec.c
|
||||
aacenc.c
|
||||
aacps.c
|
||||
aacpsy.c
|
||||
aacsbr.c
|
||||
aactab.c
|
||||
aandcttab.c
|
||||
aasc.c
|
||||
ac3.c
|
||||
ac3_parser.c
|
||||
ac3dec.c
|
||||
ac3dec_data.c
|
||||
ac3enc.c
|
||||
ac3tab.c
|
||||
acelp_filters.c
|
||||
acelp_pitch_delay.c
|
||||
acelp_vectors.c
|
||||
adpcm.c
|
||||
adxdec.c
|
||||
alac.c
|
||||
allcodecs.c
|
||||
alsdec.c
|
||||
amrnbdec.c
|
||||
anm.c
|
||||
apedec.c
|
||||
asv1.c
|
||||
atrac.c
|
||||
atrac1.c
|
||||
atrac3.c
|
||||
audioconvert.c
|
||||
aura.c
|
||||
avfft.c
|
||||
avpacket.c
|
||||
avs.c
|
||||
beosthread.c
|
||||
bethsoftvideo.c
|
||||
bgmc.c
|
||||
bfi.c
|
||||
bink.c
|
||||
binkaudio.c
|
||||
binkidct.c
|
||||
bitstream.c
|
||||
bitstream_filter.c
|
||||
bmp.c
|
||||
c93.c
|
||||
cabac.c
|
||||
cavs.c
|
||||
cavs_parser.c
|
||||
cavsdec.c
|
||||
cavsdsp.c
|
||||
# cbrt_tablegen.c
|
||||
cdgraphics.c
|
||||
celp_filters.c
|
||||
celp_math.c
|
||||
cinepak.c
|
||||
cljr.c
|
||||
cook.c
|
||||
# costablegen.c
|
||||
cscd.c
|
||||
cyuv.c
|
||||
dca.c
|
||||
dca_parser.c
|
||||
dcadsp.c
|
||||
dct.c
|
||||
dirac.c
|
||||
dirac_parser.c
|
||||
dnxhd_parser.c
|
||||
dnxhddata.c
|
||||
dnxhddec.c
|
||||
dpcm.c
|
||||
dsicinav.c
|
||||
dsputil.c
|
||||
dump_extradata_bsf.c
|
||||
dv.c
|
||||
# dv_tablegen.c
|
||||
dvbsub.c
|
||||
dvbsub_parser.c
|
||||
dvbsubdec.c
|
||||
dvdata.c
|
||||
dvdsub_parser.c
|
||||
dvdsubdec.c
|
||||
dwt.c
|
||||
dxa.c
|
||||
# dxva2.c
|
||||
# dxva2_h264.c
|
||||
# dxva2_vc1.c
|
||||
eac3dec.c
|
||||
eac3dec_data.c
|
||||
eacmv.c
|
||||
eaidct.c
|
||||
eatgq.c
|
||||
eatgv.c
|
||||
eatqi.c
|
||||
elbg.c
|
||||
error_resilience.c
|
||||
escape124.c
|
||||
eval.c
|
||||
faandct.c
|
||||
faanidct.c
|
||||
faxcompr.c
|
||||
# fdctref.c # GPL, only used for DCT test program
|
||||
fft.c
|
||||
ffv1.c
|
||||
flac.c
|
||||
flacdata.c
|
||||
flacdec.c
|
||||
flacenc.c
|
||||
flashsv.c
|
||||
flicvideo.c
|
||||
flvenc.c
|
||||
flvdec.c
|
||||
fraps.c
|
||||
frwu.c
|
||||
g726.c
|
||||
# g729dec.c
|
||||
gif.c
|
||||
gifdec.c
|
||||
golomb.c
|
||||
h261.c
|
||||
h261_parser.c
|
||||
h261dec.c
|
||||
h263.c
|
||||
h263_parser.c
|
||||
h263dec.c
|
||||
h264.c
|
||||
h264_cabac.c
|
||||
h264_cavlc.c
|
||||
h264_direct.c
|
||||
h264_loopfilter.c
|
||||
h264_mp4toannexb_bsf.c
|
||||
h264_parser.c
|
||||
h264_ps.c
|
||||
h264_refs.c
|
||||
h264_sei.c
|
||||
h264dsp.c
|
||||
# h264dspenc.c
|
||||
h264idct.c
|
||||
h264pred.c
|
||||
huffman.c
|
||||
huffyuv.c
|
||||
idcinvideo.c
|
||||
iff.c
|
||||
iirfilter.c
|
||||
imc.c
|
||||
imgconvert.c
|
||||
imx_dump_header_bsf.c
|
||||
indeo2.c
|
||||
indeo3.c
|
||||
indeo5.c
|
||||
intelh263dec.c
|
||||
interplayvideo.c
|
||||
intrax8.c
|
||||
intrax8dsp.c
|
||||
ituh263dec.c
|
||||
ituh263enc.c
|
||||
ivi_common.c
|
||||
ivi_dsp.c
|
||||
jfdctfst.c
|
||||
jfdctint.c
|
||||
jpegls.c
|
||||
jpeglsdec.c
|
||||
jrevdct.c
|
||||
kgv1dec.c
|
||||
kmvc.c
|
||||
lcldec.c
|
||||
# lclenc.c
|
||||
libspeexdec.c
|
||||
libtheoraenc.c
|
||||
libvorbis.c
|
||||
# ljpegenc.c
|
||||
loco.c
|
||||
lpc.c
|
||||
lsp.c
|
||||
lzw.c
|
||||
# lzwenc.c
|
||||
mace.c
|
||||
mdct.c
|
||||
# mdct_tablegen.c
|
||||
mdec.c
|
||||
mimic.c
|
||||
mjpeg.c
|
||||
mjpeg_parser.c
|
||||
mjpega_dump_header_bsf.c
|
||||
mjpegbdec.c
|
||||
mjpegdec.c
|
||||
mjpegenc.c
|
||||
mlp.c
|
||||
mlp_parser.c
|
||||
mlpdec.c
|
||||
mlpdsp.c
|
||||
mmvideo.c
|
||||
motion_est.c
|
||||
motionpixels.c
|
||||
# motionpixels_tablegen.c
|
||||
movsub_bsf.c
|
||||
mp3_header_compress_bsf.c
|
||||
mp3_header_decompress_bsf.c
|
||||
mpc.c
|
||||
mpc7.c
|
||||
mpc8.c
|
||||
mpeg4audio.c
|
||||
mpeg4video.c
|
||||
mpeg4video_parser.c
|
||||
mpeg4videoenc.c
|
||||
mpeg4videodec.c
|
||||
mpeg12.c
|
||||
mpeg12data.c
|
||||
mpeg12enc.c
|
||||
mpegaudio.c
|
||||
mpegaudio_parser.c
|
||||
# mpegaudio_tablegen.c
|
||||
mpegaudiodata.c
|
||||
mpegaudiodec.c
|
||||
mpegaudiodecheader.c
|
||||
mpegaudioenc.c
|
||||
mpegvideo.c
|
||||
mpegvideo_enc.c
|
||||
mpegvideo_parser.c
|
||||
# mpegvideo_xvmc.c
|
||||
msmpeg4.c
|
||||
msmpeg4data.c
|
||||
msrle.c
|
||||
msrledec.c
|
||||
msvideo1.c
|
||||
nellymoser.c
|
||||
nellymoserdec.c
|
||||
noise_bsf.c
|
||||
nuv.c
|
||||
opt.c
|
||||
options.c
|
||||
pamenc.c
|
||||
parser.c
|
||||
pcm.c
|
||||
pcm-mpeg.c
|
||||
# pcm_tablegen.c
|
||||
pcx.c
|
||||
pgssubdec.c
|
||||
png.c
|
||||
pngdec.c
|
||||
pnm.c
|
||||
pnm_parser.c
|
||||
pnmdec.c
|
||||
# pnmenc.c
|
||||
psymodel.c
|
||||
pthread.c
|
||||
ptx.c
|
||||
qcelpdec.c
|
||||
qdm2.c
|
||||
# qdm2_tablegen.c
|
||||
qdrw.c
|
||||
qpeg.c
|
||||
qtrle.c
|
||||
r210dec.c
|
||||
ra144.c
|
||||
ra288.c
|
||||
rangecoder.c
|
||||
ratecontrol.c
|
||||
raw.c
|
||||
rawdec.c
|
||||
rawenc.c
|
||||
rdft.c
|
||||
remove_extradata_bsf.c
|
||||
resample.c
|
||||
resample2.c
|
||||
rl2.c
|
||||
rle.c
|
||||
# roqaudioenc.c
|
||||
roqvideo.c
|
||||
roqvideodec.c
|
||||
# roqvideoenc.c
|
||||
rpza.c
|
||||
rtjpeg.c
|
||||
rv10.c
|
||||
rv30.c
|
||||
rv30dsp.c
|
||||
rv34.c
|
||||
rv40.c
|
||||
rv40dsp.c
|
||||
s3tc.c
|
||||
sgidec.c
|
||||
shorten.c
|
||||
simple_idct.c
|
||||
sipr.c
|
||||
sipr16k.c
|
||||
smacker.c
|
||||
smc.c
|
||||
snow.c
|
||||
sonic.c
|
||||
sp5xdec.c
|
||||
sunrast.c
|
||||
svq1.c
|
||||
svq1dec.c
|
||||
svq3.c
|
||||
synth_filter.c
|
||||
tableprint.c
|
||||
targa.c
|
||||
tiertexseqv.c
|
||||
tiff.c
|
||||
# tiffenc.c
|
||||
truemotion1.c
|
||||
truemotion2.c
|
||||
truespeech.c
|
||||
tscc.c
|
||||
tta.c
|
||||
twinvq.c
|
||||
txd.c
|
||||
ulti.c
|
||||
utils.c
|
||||
# vaapi_h264.c
|
||||
vb.c
|
||||
vc1.c
|
||||
vc1dec.c
|
||||
vc1_parser.c
|
||||
vc1data.c
|
||||
vc1dsp.c
|
||||
vcr1.c
|
||||
vmdav.c
|
||||
vmnc.c
|
||||
vorbis.c
|
||||
vorbis_data.c
|
||||
vorbis_dec.c
|
||||
vp3.c
|
||||
vp3_parser.c
|
||||
vp3dsp.c
|
||||
vp5.c
|
||||
vp56.c
|
||||
vp56data.c
|
||||
vp56dsp.c
|
||||
vp6.c
|
||||
vp6dsp.c
|
||||
vqavideo.c
|
||||
wavpack.c
|
||||
wma.c
|
||||
wmadec.c
|
||||
wmaprodec.c
|
||||
wmavoice.c
|
||||
wmv2.c
|
||||
wmv2dec.c
|
||||
wnv1.c
|
||||
ws-snd1.c
|
||||
xan.c
|
||||
xiph.c
|
||||
xl.c
|
||||
xsubdec.c
|
||||
yop.c
|
||||
zmbv.c
|
||||
;
|
||||
|
||||
# GCC2 needs this in order to find codec.h in each of these directories
|
||||
# respectively and to find the correct codec.h, we need to define this
|
||||
# per individual file.
|
||||
SourceHdrs libvorbis.c : [ FDirName $(SUBDIR) .. libvorbis include vorbis ] ;
|
||||
SourceHdrs libtheoraenc.c : [ FDirName $(SUBDIR) .. libtheora include theora ] ;
|
||||
SourceHdrs libspeexdec.c : [ FDirName $(SUBDIR) .. libspeex include speex ] ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons media plugins ffmpeg libavcodec
|
||||
$(TARGET_ARCH) ;
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* AAC definitions and structures
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC definitions and structures
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_H
|
||||
#define AVCODEC_AAC_H
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "fft.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "sbr.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
#define MAX_ELEM_ID 16
|
||||
|
||||
#define TNS_MAX_ORDER 20
|
||||
|
||||
enum RawDataBlockType {
|
||||
TYPE_SCE,
|
||||
TYPE_CPE,
|
||||
TYPE_CCE,
|
||||
TYPE_LFE,
|
||||
TYPE_DSE,
|
||||
TYPE_PCE,
|
||||
TYPE_FIL,
|
||||
TYPE_END,
|
||||
};
|
||||
|
||||
enum ExtensionPayloadID {
|
||||
EXT_FILL,
|
||||
EXT_FILL_DATA,
|
||||
EXT_DATA_ELEMENT,
|
||||
EXT_DYNAMIC_RANGE = 0xb,
|
||||
EXT_SBR_DATA = 0xd,
|
||||
EXT_SBR_DATA_CRC = 0xe,
|
||||
};
|
||||
|
||||
enum WindowSequence {
|
||||
ONLY_LONG_SEQUENCE,
|
||||
LONG_START_SEQUENCE,
|
||||
EIGHT_SHORT_SEQUENCE,
|
||||
LONG_STOP_SEQUENCE,
|
||||
};
|
||||
|
||||
enum BandType {
|
||||
ZERO_BT = 0, ///< Scalefactors and spectral data are all zero.
|
||||
FIRST_PAIR_BT = 5, ///< This and later band types encode two values (rather than four) with one code word.
|
||||
ESC_BT = 11, ///< Spectral data are coded with an escape sequence.
|
||||
NOISE_BT = 13, ///< Spectral data are scaled white noise not coded in the bitstream.
|
||||
INTENSITY_BT2 = 14, ///< Scalefactor data are intensity stereo positions.
|
||||
INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions.
|
||||
};
|
||||
|
||||
#define IS_CODEBOOK_UNSIGNED(x) ((x - 1) & 10)
|
||||
|
||||
enum ChannelPosition {
|
||||
AAC_CHANNEL_FRONT = 1,
|
||||
AAC_CHANNEL_SIDE = 2,
|
||||
AAC_CHANNEL_BACK = 3,
|
||||
AAC_CHANNEL_LFE = 4,
|
||||
AAC_CHANNEL_CC = 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* The point during decoding at which channel coupling is applied.
|
||||
*/
|
||||
enum CouplingPoint {
|
||||
BEFORE_TNS,
|
||||
BETWEEN_TNS_AND_IMDCT,
|
||||
AFTER_IMDCT = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Output configuration status
|
||||
*/
|
||||
enum OCStatus {
|
||||
OC_NONE, //< Output unconfigured
|
||||
OC_TRIAL_PCE, //< Output configuration under trial specified by an inband PCE
|
||||
OC_TRIAL_FRAME, //< Output configuration under trial specified by a frame header
|
||||
OC_GLOBAL_HDR, //< Output configuration set in a global header but not yet locked
|
||||
OC_LOCKED, //< Output configuration locked in place
|
||||
};
|
||||
|
||||
/**
|
||||
* Predictor State
|
||||
*/
|
||||
typedef struct {
|
||||
float cor0;
|
||||
float cor1;
|
||||
float var0;
|
||||
float var1;
|
||||
float r0;
|
||||
float r1;
|
||||
} PredictorState;
|
||||
|
||||
#define MAX_PREDICTORS 672
|
||||
|
||||
#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times
|
||||
#define SCALE_ONE_POS 140 ///< scalefactor index that corresponds to scale=1.0
|
||||
#define SCALE_MAX_POS 255 ///< scalefactor index maximum value
|
||||
#define SCALE_MAX_DIFF 60 ///< maximum scalefactor difference allowed by standard
|
||||
#define SCALE_DIFF_ZERO 60 ///< codebook index corresponding to zero scalefactor indices difference
|
||||
|
||||
/**
|
||||
* Individual Channel Stream
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t max_sfb; ///< number of scalefactor bands per group
|
||||
enum WindowSequence window_sequence[2];
|
||||
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sinus window.
|
||||
int num_window_groups;
|
||||
uint8_t group_len[8];
|
||||
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
|
||||
const uint8_t *swb_sizes; ///< table of scalefactor band sizes for a particular window
|
||||
int num_swb; ///< number of scalefactor window bands
|
||||
int num_windows;
|
||||
int tns_max_bands;
|
||||
int predictor_present;
|
||||
int predictor_initialized;
|
||||
int predictor_reset_group;
|
||||
uint8_t prediction_used[41];
|
||||
} IndividualChannelStream;
|
||||
|
||||
/**
|
||||
* Temporal Noise Shaping
|
||||
*/
|
||||
typedef struct {
|
||||
int present;
|
||||
int n_filt[8];
|
||||
int length[8][4];
|
||||
int direction[8][4];
|
||||
int order[8][4];
|
||||
float coef[8][4][TNS_MAX_ORDER];
|
||||
} TemporalNoiseShaping;
|
||||
|
||||
/**
|
||||
* Dynamic Range Control - decoded from the bitstream but not processed further.
|
||||
*/
|
||||
typedef struct {
|
||||
int pce_instance_tag; ///< Indicates with which program the DRC info is associated.
|
||||
int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative
|
||||
int dyn_rng_ctl[17]; ///< DRC magnitude information
|
||||
int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing.
|
||||
int band_incr; ///< Number of DRC bands greater than 1 having DRC info.
|
||||
int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain.
|
||||
int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
|
||||
int prog_ref_level; /**< A reference level for the long-term program audio level for all
|
||||
* channels combined.
|
||||
*/
|
||||
} DynamicRangeControl;
|
||||
|
||||
typedef struct {
|
||||
int num_pulse;
|
||||
int start;
|
||||
int pos[4];
|
||||
int amp[4];
|
||||
} Pulse;
|
||||
|
||||
/**
|
||||
* coupling parameters
|
||||
*/
|
||||
typedef struct {
|
||||
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
|
||||
int num_coupled; ///< number of target elements
|
||||
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
|
||||
int id_select[8]; ///< element id
|
||||
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
|
||||
* [2] list of gains for left channel; [3] lists of gains for both channels
|
||||
*/
|
||||
float gain[16][120];
|
||||
} ChannelCoupling;
|
||||
|
||||
/**
|
||||
* Single Channel Element - used for both SCE and LFE elements.
|
||||
*/
|
||||
typedef struct {
|
||||
IndividualChannelStream ics;
|
||||
TemporalNoiseShaping tns;
|
||||
Pulse pulse;
|
||||
enum BandType band_type[128]; ///< band types
|
||||
int band_type_run_end[120]; ///< band type run end points
|
||||
float sf[120]; ///< scalefactors
|
||||
int sf_idx[128]; ///< scalefactor indices (used by encoder)
|
||||
uint8_t zeroes[128]; ///< band is not coded (used by encoder)
|
||||
DECLARE_ALIGNED(16, float, coeffs)[1024]; ///< coefficients for IMDCT
|
||||
DECLARE_ALIGNED(16, float, saved)[1024]; ///< overlap
|
||||
DECLARE_ALIGNED(16, float, ret)[2048]; ///< PCM output
|
||||
PredictorState predictor_state[MAX_PREDICTORS];
|
||||
} SingleChannelElement;
|
||||
|
||||
/**
|
||||
* channel element - generic struct for SCE/CPE/CCE/LFE
|
||||
*/
|
||||
typedef struct {
|
||||
// CPE specific
|
||||
int common_window; ///< Set if channels share a common 'IndividualChannelStream' in bitstream.
|
||||
int ms_mode; ///< Signals mid/side stereo flags coding mode (used by encoder)
|
||||
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
|
||||
// shared
|
||||
SingleChannelElement ch[2];
|
||||
// CCE specific
|
||||
ChannelCoupling coup;
|
||||
SpectralBandReplication sbr;
|
||||
} ChannelElement;
|
||||
|
||||
/**
|
||||
* main AAC context
|
||||
*/
|
||||
typedef struct {
|
||||
AVCodecContext *avctx;
|
||||
|
||||
MPEG4AudioConfig m4ac;
|
||||
|
||||
int is_saved; ///< Set if elements have stored overlap from previous frame.
|
||||
DynamicRangeControl che_drc;
|
||||
|
||||
/**
|
||||
* @defgroup elements Channel element related data.
|
||||
* @{
|
||||
*/
|
||||
enum ChannelPosition che_pos[4][MAX_ELEM_ID]; /**< channel element channel mapping with the
|
||||
* first index as the first 4 raw data block types
|
||||
*/
|
||||
ChannelElement *che[4][MAX_ELEM_ID];
|
||||
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
|
||||
uint8_t tags_seen_this_frame[4][MAX_ELEM_ID];
|
||||
int tags_mapped;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup temporary aligned temporary buffers (We do not want to have these on the stack.)
|
||||
* @{
|
||||
*/
|
||||
DECLARE_ALIGNED(16, float, buf_mdct)[1024];
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup tables Computed / set up during initialization.
|
||||
* @{
|
||||
*/
|
||||
FFTContext mdct;
|
||||
FFTContext mdct_small;
|
||||
DSPContext dsp;
|
||||
int random_state;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup output Members used for output interleaving.
|
||||
* @{
|
||||
*/
|
||||
float *output_data[MAX_CHANNELS]; ///< Points to each element's 'ret' buffer (PCM output).
|
||||
float add_bias; ///< offset for dsp.float_to_int16
|
||||
float sf_scale; ///< Pre-scale for correct IMDCT and dsp.float_to_int16.
|
||||
int sf_offset; ///< offset into pow2sf_tab as appropriate for dsp.float_to_int16
|
||||
/** @} */
|
||||
|
||||
DECLARE_ALIGNED(16, float, temp)[128];
|
||||
|
||||
enum OCStatus output_configured;
|
||||
} AACContext;
|
||||
|
||||
#endif /* AVCODEC_AAC_H */
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Common AAC and AC-3 parser
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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 "parser.h"
|
||||
#include "aac_ac3_parser.h"
|
||||
|
||||
int ff_aac_ac3_parse(AVCodecParserContext *s1,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
AACAC3ParseContext *s = s1->priv_data;
|
||||
ParseContext *pc = &s->pc;
|
||||
int len, i;
|
||||
int new_frame_start;
|
||||
|
||||
get_next:
|
||||
i=END_NOT_FOUND;
|
||||
if(s->remaining_size <= buf_size){
|
||||
if(s->remaining_size && !s->need_next_header){
|
||||
i= s->remaining_size;
|
||||
s->remaining_size = 0;
|
||||
}else{ //we need a header first
|
||||
len=0;
|
||||
for(i=s->remaining_size; i<buf_size; i++){
|
||||
s->state = (s->state<<8) + buf[i];
|
||||
if((len=s->sync(s->state, s, &s->need_next_header, &new_frame_start)))
|
||||
break;
|
||||
}
|
||||
if(len<=0){
|
||||
i=END_NOT_FOUND;
|
||||
}else{
|
||||
s->state=0;
|
||||
i-= s->header_size -1;
|
||||
s->remaining_size = len;
|
||||
if(!new_frame_start || pc->index+i<=0){
|
||||
s->remaining_size += i;
|
||||
goto get_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ff_combine_frame(pc, i, &buf, &buf_size)<0){
|
||||
s->remaining_size -= FFMIN(s->remaining_size, buf_size);
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
|
||||
/* update codec info */
|
||||
if(s->codec_id)
|
||||
avctx->codec_id = s->codec_id;
|
||||
|
||||
/* Due to backwards compatible HE-AAC the sample rate, channel count,
|
||||
and total number of samples found in an AAC ADTS header are not
|
||||
reliable. Bit rate is still accurate because the total frame duration in
|
||||
seconds is still correct (as is the number of bits in the frame). */
|
||||
if (avctx->codec_id != CODEC_ID_AAC) {
|
||||
avctx->sample_rate = s->sample_rate;
|
||||
|
||||
/* allow downmixing to stereo (or mono for AC-3) */
|
||||
if(avctx->request_channels > 0 &&
|
||||
avctx->request_channels < s->channels &&
|
||||
(avctx->request_channels <= 2 ||
|
||||
(avctx->request_channels == 1 &&
|
||||
(avctx->codec_id == CODEC_ID_AC3 ||
|
||||
avctx->codec_id == CODEC_ID_EAC3)))) {
|
||||
avctx->channels = avctx->request_channels;
|
||||
} else {
|
||||
avctx->channels = s->channels;
|
||||
avctx->channel_layout = s->channel_layout;
|
||||
}
|
||||
avctx->frame_size = s->samples;
|
||||
}
|
||||
|
||||
avctx->bit_rate = s->bit_rate;
|
||||
|
||||
return i;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Common AAC and AC-3 parser prototypes
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AC3_PARSER_H
|
||||
#define AVCODEC_AAC_AC3_PARSER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "avcodec.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef enum {
|
||||
AAC_AC3_PARSE_ERROR_SYNC = -1,
|
||||
AAC_AC3_PARSE_ERROR_BSID = -2,
|
||||
AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -3,
|
||||
AAC_AC3_PARSE_ERROR_FRAME_SIZE = -4,
|
||||
AAC_AC3_PARSE_ERROR_FRAME_TYPE = -5,
|
||||
AAC_AC3_PARSE_ERROR_CRC = -6,
|
||||
AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -7,
|
||||
} AACAC3ParseError;
|
||||
|
||||
typedef struct AACAC3ParseContext {
|
||||
ParseContext pc;
|
||||
int frame_size;
|
||||
int header_size;
|
||||
int (*sync)(uint64_t state, struct AACAC3ParseContext *hdr_info,
|
||||
int *need_next_header, int *new_frame_start);
|
||||
|
||||
int channels;
|
||||
int sample_rate;
|
||||
int bit_rate;
|
||||
int samples;
|
||||
int64_t channel_layout;
|
||||
|
||||
int remaining_size;
|
||||
uint64_t state;
|
||||
|
||||
int need_next_header;
|
||||
enum CodecID codec_id;
|
||||
} AACAC3ParseContext;
|
||||
|
||||
int ff_aac_ac3_parse(AVCodecParserContext *s1,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size);
|
||||
|
||||
#endif /* AVCODEC_AAC_AC3_PARSER_H */
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
|
||||
* Copyright (c) 2009 Alex Converse <[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 "aac_parser.h"
|
||||
#include "put_bits.h"
|
||||
#include "get_bits.h"
|
||||
#include "mpeg4audio.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef struct AACBSFContext {
|
||||
int first_frame_done;
|
||||
} AACBSFContext;
|
||||
|
||||
/**
|
||||
* This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
|
||||
* ADTS header and removes the ADTS header.
|
||||
*/
|
||||
static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
|
||||
AVCodecContext *avctx, const char *args,
|
||||
uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size,
|
||||
int keyframe)
|
||||
{
|
||||
GetBitContext gb;
|
||||
PutBitContext pb;
|
||||
AACADTSHeaderInfo hdr;
|
||||
|
||||
AACBSFContext *ctx = bsfc->priv_data;
|
||||
|
||||
init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8);
|
||||
|
||||
*poutbuf = (uint8_t*) buf;
|
||||
*poutbuf_size = buf_size;
|
||||
|
||||
if (avctx->extradata)
|
||||
if (show_bits(&gb, 12) != 0xfff)
|
||||
return 0;
|
||||
|
||||
if (ff_aac_parse_header(&gb, &hdr) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!hdr.crc_absent && hdr.num_aac_frames > 1) {
|
||||
av_log_missing_feature(avctx, "Multiple RDBs per frame with CRC is", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;
|
||||
buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;
|
||||
|
||||
if (!ctx->first_frame_done) {
|
||||
int pce_size = 0;
|
||||
uint8_t pce_data[MAX_PCE_SIZE];
|
||||
if (!hdr.chan_config) {
|
||||
init_get_bits(&gb, buf, buf_size);
|
||||
if (get_bits(&gb, 3) != 5) {
|
||||
av_log_missing_feature(avctx, "PCE based channel configuration, where the PCE is not the first syntax element is", 0);
|
||||
return -1;
|
||||
}
|
||||
init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
|
||||
pce_size = ff_copy_pce_data(&pb, &gb)/8;
|
||||
flush_put_bits(&pb);
|
||||
buf_size -= get_bits_count(&gb)/8;
|
||||
buf += get_bits_count(&gb)/8;
|
||||
}
|
||||
avctx->extradata_size = 2 + pce_size;
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
|
||||
put_bits(&pb, 5, hdr.object_type);
|
||||
put_bits(&pb, 4, hdr.sampling_index);
|
||||
put_bits(&pb, 4, hdr.chan_config);
|
||||
put_bits(&pb, 1, 0); //frame length - 1024 samples
|
||||
put_bits(&pb, 1, 0); //does not depend on core coder
|
||||
put_bits(&pb, 1, 0); //is not extension
|
||||
flush_put_bits(&pb);
|
||||
if (pce_size) {
|
||||
memcpy(avctx->extradata + 2, pce_data, pce_size);
|
||||
}
|
||||
|
||||
ctx->first_frame_done = 1;
|
||||
}
|
||||
|
||||
*poutbuf = (uint8_t*) buf;
|
||||
*poutbuf_size = buf_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVBitStreamFilter aac_adtstoasc_bsf = {
|
||||
"aac_adtstoasc",
|
||||
sizeof(AACBSFContext),
|
||||
aac_adtstoasc_filter,
|
||||
};
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Audio and Video frame extraction
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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 "parser.h"
|
||||
#include "aac_ac3_parser.h"
|
||||
#include "aac_parser.h"
|
||||
#include "get_bits.h"
|
||||
#include "mpeg4audio.h"
|
||||
|
||||
int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr)
|
||||
{
|
||||
int size, rdb, ch, sr;
|
||||
int aot, crc_abs;
|
||||
|
||||
if(get_bits(gbc, 12) != 0xfff)
|
||||
return AAC_AC3_PARSE_ERROR_SYNC;
|
||||
|
||||
skip_bits1(gbc); /* id */
|
||||
skip_bits(gbc, 2); /* layer */
|
||||
crc_abs = get_bits1(gbc); /* protection_absent */
|
||||
aot = get_bits(gbc, 2); /* profile_objecttype */
|
||||
sr = get_bits(gbc, 4); /* sample_frequency_index */
|
||||
if(!ff_mpeg4audio_sample_rates[sr])
|
||||
return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
|
||||
skip_bits1(gbc); /* private_bit */
|
||||
ch = get_bits(gbc, 3); /* channel_configuration */
|
||||
|
||||
skip_bits1(gbc); /* original/copy */
|
||||
skip_bits1(gbc); /* home */
|
||||
|
||||
/* adts_variable_header */
|
||||
skip_bits1(gbc); /* copyright_identification_bit */
|
||||
skip_bits1(gbc); /* copyright_identification_start */
|
||||
size = get_bits(gbc, 13); /* aac_frame_length */
|
||||
if(size < AAC_ADTS_HEADER_SIZE)
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
|
||||
|
||||
skip_bits(gbc, 11); /* adts_buffer_fullness */
|
||||
rdb = get_bits(gbc, 2); /* number_of_raw_data_blocks_in_frame */
|
||||
|
||||
hdr->object_type = aot + 1;
|
||||
hdr->chan_config = ch;
|
||||
hdr->crc_absent = crc_abs;
|
||||
hdr->num_aac_frames = rdb + 1;
|
||||
hdr->sampling_index = sr;
|
||||
hdr->sample_rate = ff_mpeg4audio_sample_rates[sr];
|
||||
hdr->samples = (rdb + 1) * 1024;
|
||||
hdr->bit_rate = size * 8 * hdr->sample_rate / hdr->samples;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,
|
||||
int *need_next_header, int *new_frame_start)
|
||||
{
|
||||
GetBitContext bits;
|
||||
AACADTSHeaderInfo hdr;
|
||||
int size;
|
||||
union {
|
||||
uint64_t u64;
|
||||
uint8_t u8[8];
|
||||
} tmp;
|
||||
|
||||
tmp.u64 = be2me_64(state);
|
||||
init_get_bits(&bits, tmp.u8+8-AAC_ADTS_HEADER_SIZE, AAC_ADTS_HEADER_SIZE * 8);
|
||||
|
||||
if ((size = ff_aac_parse_header(&bits, &hdr)) < 0)
|
||||
return 0;
|
||||
*need_next_header = 0;
|
||||
*new_frame_start = 1;
|
||||
hdr_info->sample_rate = hdr.sample_rate;
|
||||
hdr_info->channels = ff_mpeg4audio_channels[hdr.chan_config];
|
||||
hdr_info->samples = hdr.samples;
|
||||
hdr_info->bit_rate = hdr.bit_rate;
|
||||
return size;
|
||||
}
|
||||
|
||||
static av_cold int aac_parse_init(AVCodecParserContext *s1)
|
||||
{
|
||||
AACAC3ParseContext *s = s1->priv_data;
|
||||
s->header_size = AAC_ADTS_HEADER_SIZE;
|
||||
s->sync = aac_sync;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVCodecParser aac_parser = {
|
||||
{ CODEC_ID_AAC },
|
||||
sizeof(AACAC3ParseContext),
|
||||
aac_parse_init,
|
||||
ff_aac_ac3_parse,
|
||||
ff_parse_close,
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* AAC parser prototypes
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_PARSER_H
|
||||
#define AVCODEC_AAC_PARSER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "aac_ac3_parser.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
#define AAC_ADTS_HEADER_SIZE 7
|
||||
|
||||
typedef struct {
|
||||
uint32_t sample_rate;
|
||||
uint32_t samples;
|
||||
uint32_t bit_rate;
|
||||
uint8_t crc_absent;
|
||||
uint8_t object_type;
|
||||
uint8_t sampling_index;
|
||||
uint8_t chan_config;
|
||||
uint8_t num_aac_frames;
|
||||
} AACADTSHeaderInfo;
|
||||
|
||||
/**
|
||||
* Parses AAC frame header.
|
||||
* Parses the ADTS frame header to the end of the variable header, which is
|
||||
* the first 54 bits.
|
||||
* @param gbc[in] BitContext containing the first 54 bits of the frame.
|
||||
* @param hdr[out] Pointer to struct where header info is written.
|
||||
* @return Returns 0 on success, -1 if there is a sync word mismatch,
|
||||
* -2 if the version element is invalid, -3 if the sample rate
|
||||
* element is invalid, or -4 if the bit rate element is invalid.
|
||||
*/
|
||||
int ff_aac_parse_header(GetBitContext *gbc, AACADTSHeaderInfo *hdr);
|
||||
|
||||
#endif /* AVCODEC_AAC_PARSER_H */
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Generate a header file for hardcoded AAC tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <[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 <stdlib.h>
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#include "aac_tablegen.h"
|
||||
#include "tableprint.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ff_aac_tableinit();
|
||||
|
||||
write_fileheader();
|
||||
|
||||
printf("const float ff_aac_pow2sf_tab[428] = {\n");
|
||||
write_float_array(ff_aac_pow2sf_tab, 428);
|
||||
printf("};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Header file for hardcoded AAC tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <[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
|
||||
*/
|
||||
|
||||
#ifndef AAC_TABLEGEN_H
|
||||
#define AAC_TABLEGEN_H
|
||||
|
||||
#include "aac_tablegen_decl.h"
|
||||
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#include "libavcodec/aac_tables.h"
|
||||
#else
|
||||
#include "../libavutil/mathematics.h"
|
||||
float ff_aac_pow2sf_tab[428];
|
||||
|
||||
void ff_aac_tableinit(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 428; i++)
|
||||
ff_aac_pow2sf_tab[i] = pow(2, (i - 200) / 4.);
|
||||
}
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AAC_TABLEGEN_H */
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Header file for hardcoded AAC tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <[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
|
||||
*/
|
||||
|
||||
#ifndef AAC_TABLEGEN_INIT_H
|
||||
#define AAC_TABLEGEN_INIT_H
|
||||
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#define ff_aac_tableinit()
|
||||
extern const float ff_aac_pow2sf_tab[428];
|
||||
#else
|
||||
void ff_aac_tableinit(void);
|
||||
extern float ff_aac_pow2sf_tab[428];
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AAC_TABLEGEN_INIT_H */
|
||||
@@ -1,960 +0,0 @@
|
||||
/*
|
||||
* AAC coefficients encoder
|
||||
* Copyright (C) 2008-2009 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
* AAC coefficients encoder
|
||||
*/
|
||||
|
||||
/***********************************
|
||||
* TODOs:
|
||||
* speedup quantizer selection
|
||||
* add sane pulse detection
|
||||
***********************************/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "put_bits.h"
|
||||
#include "aac.h"
|
||||
#include "aacenc.h"
|
||||
#include "aactab.h"
|
||||
|
||||
/** bits needed to code codebook run value for long windows */
|
||||
static const uint8_t run_value_bits_long[64] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
|
||||
};
|
||||
|
||||
/** bits needed to code codebook run value for short windows */
|
||||
static const uint8_t run_value_bits_short[16] = {
|
||||
3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
|
||||
};
|
||||
|
||||
static const uint8_t *run_value_bits[2] = {
|
||||
run_value_bits_long, run_value_bits_short
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Quantize one coefficient.
|
||||
* @return absolute value of the quantized coefficient
|
||||
* @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
|
||||
*/
|
||||
static av_always_inline int quant(float coef, const float Q)
|
||||
{
|
||||
float a = coef * Q;
|
||||
return sqrtf(a * sqrtf(a)) + 0.4054;
|
||||
}
|
||||
|
||||
static void quantize_bands(int (*out)[2], const float *in, const float *scaled,
|
||||
int size, float Q34, int is_signed, int maxval)
|
||||
{
|
||||
int i;
|
||||
double qc;
|
||||
for (i = 0; i < size; i++) {
|
||||
qc = scaled[i] * Q34;
|
||||
out[i][0] = (int)FFMIN(qc, (double)maxval);
|
||||
out[i][1] = (int)FFMIN(qc + 0.4054, (double)maxval);
|
||||
if (is_signed && in[i] < 0.0f) {
|
||||
out[i][0] = -out[i][0];
|
||||
out[i][1] = -out[i][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void abs_pow34_v(float *out, const float *in, const int size)
|
||||
{
|
||||
#ifndef USE_REALLY_FULL_SEARCH
|
||||
int i;
|
||||
for (i = 0; i < size; i++) {
|
||||
float a = fabsf(in[i]);
|
||||
out[i] = sqrtf(a * sqrtf(a));
|
||||
}
|
||||
#endif /* USE_REALLY_FULL_SEARCH */
|
||||
}
|
||||
|
||||
static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
|
||||
static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
|
||||
|
||||
/**
|
||||
* Calculate rate distortion cost for quantizing with given codebook
|
||||
*
|
||||
* @return quantization distortion
|
||||
*/
|
||||
static float quantize_and_encode_band_cost(struct AACEncContext *s,
|
||||
PutBitContext *pb, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits)
|
||||
{
|
||||
const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
|
||||
const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
|
||||
const float CLIPPED_ESCAPE = 165140.0f*IQ;
|
||||
int i, j, k;
|
||||
float cost = 0;
|
||||
const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
|
||||
int resbits = 0;
|
||||
#ifndef USE_REALLY_FULL_SEARCH
|
||||
const float Q34 = sqrtf(Q * sqrtf(Q));
|
||||
const int range = aac_cb_range[cb];
|
||||
const int maxval = aac_cb_maxval[cb];
|
||||
int offs[4];
|
||||
#endif /* USE_REALLY_FULL_SEARCH */
|
||||
|
||||
if (!cb) {
|
||||
for (i = 0; i < size; i++)
|
||||
cost += in[i]*in[i];
|
||||
if (bits)
|
||||
*bits = 0;
|
||||
return cost * lambda;
|
||||
}
|
||||
#ifndef USE_REALLY_FULL_SEARCH
|
||||
offs[0] = 1;
|
||||
for (i = 1; i < dim; i++)
|
||||
offs[i] = offs[i-1]*range;
|
||||
if (!scaled) {
|
||||
abs_pow34_v(s->scoefs, in, size);
|
||||
scaled = s->scoefs;
|
||||
}
|
||||
quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval);
|
||||
#endif /* USE_REALLY_FULL_SEARCH */
|
||||
for (i = 0; i < size; i += dim) {
|
||||
float mincost;
|
||||
int minidx = 0;
|
||||
int minbits = 0;
|
||||
const float *vec;
|
||||
#ifndef USE_REALLY_FULL_SEARCH
|
||||
int (*quants)[2] = &s->qcoefs[i];
|
||||
mincost = 0.0f;
|
||||
for (j = 0; j < dim; j++)
|
||||
mincost += in[i+j]*in[i+j];
|
||||
minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
|
||||
minbits = ff_aac_spectral_bits[cb-1][minidx];
|
||||
mincost = mincost * lambda + minbits;
|
||||
for (j = 0; j < (1<<dim); j++) {
|
||||
float rd = 0.0f;
|
||||
int curbits;
|
||||
int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
|
||||
int same = 0;
|
||||
for (k = 0; k < dim; k++) {
|
||||
if ((j & (1 << k)) && quants[k][0] == quants[k][1]) {
|
||||
same = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (same)
|
||||
continue;
|
||||
for (k = 0; k < dim; k++)
|
||||
curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
|
||||
curbits = ff_aac_spectral_bits[cb-1][curidx];
|
||||
vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
|
||||
#else
|
||||
mincost = INFINITY;
|
||||
vec = ff_aac_codebook_vectors[cb-1];
|
||||
for (j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim) {
|
||||
float rd = 0.0f;
|
||||
int curbits = ff_aac_spectral_bits[cb-1][j];
|
||||
int curidx = j;
|
||||
#endif /* USE_REALLY_FULL_SEARCH */
|
||||
if (IS_CODEBOOK_UNSIGNED(cb)) {
|
||||
for (k = 0; k < dim; k++) {
|
||||
float t = fabsf(in[i+k]);
|
||||
float di;
|
||||
if (vec[k] == 64.0f) { //FIXME: slow
|
||||
//do not code with escape sequence small values
|
||||
if (t < 39.0f*IQ) {
|
||||
rd = INFINITY;
|
||||
break;
|
||||
}
|
||||
if (t >= CLIPPED_ESCAPE) {
|
||||
di = t - CLIPPED_ESCAPE;
|
||||
curbits += 21;
|
||||
} else {
|
||||
int c = av_clip(quant(t, Q), 0, 8191);
|
||||
di = t - c*cbrtf(c)*IQ;
|
||||
curbits += av_log2(c)*2 - 4 + 1;
|
||||
}
|
||||
} else {
|
||||
di = t - vec[k]*IQ;
|
||||
}
|
||||
if (vec[k] != 0.0f)
|
||||
curbits++;
|
||||
rd += di*di;
|
||||
}
|
||||
} else {
|
||||
for (k = 0; k < dim; k++) {
|
||||
float di = in[i+k] - vec[k]*IQ;
|
||||
rd += di*di;
|
||||
}
|
||||
}
|
||||
rd = rd * lambda + curbits;
|
||||
if (rd < mincost) {
|
||||
mincost = rd;
|
||||
minidx = curidx;
|
||||
minbits = curbits;
|
||||
}
|
||||
}
|
||||
cost += mincost;
|
||||
resbits += minbits;
|
||||
if (cost >= uplim)
|
||||
return uplim;
|
||||
if (pb) {
|
||||
put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
|
||||
if (IS_CODEBOOK_UNSIGNED(cb))
|
||||
for (j = 0; j < dim; j++)
|
||||
if (ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
|
||||
put_bits(pb, 1, in[i+j] < 0.0f);
|
||||
if (cb == ESC_BT) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f) {
|
||||
int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191);
|
||||
int len = av_log2(coef);
|
||||
|
||||
put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
|
||||
put_bits(pb, len, coef & ((1 << len) - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bits)
|
||||
*bits = resbits;
|
||||
return cost;
|
||||
}
|
||||
static float quantize_band_cost(struct AACEncContext *s, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits)
|
||||
{
|
||||
return quantize_and_encode_band_cost(s, NULL, in, scaled, size, scale_idx,
|
||||
cb, lambda, uplim, bits);
|
||||
}
|
||||
|
||||
static void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,
|
||||
const float *in, int size, int scale_idx,
|
||||
int cb, const float lambda)
|
||||
{
|
||||
quantize_and_encode_band_cost(s, pb, in, NULL, size, scale_idx, cb, lambda,
|
||||
INFINITY, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* structure used in optimal codebook search
|
||||
*/
|
||||
typedef struct BandCodingPath {
|
||||
int prev_idx; ///< pointer to the previous path point
|
||||
float cost; ///< path cost
|
||||
int run;
|
||||
} BandCodingPath;
|
||||
|
||||
/**
|
||||
* Encode band info for single window group bands.
|
||||
*/
|
||||
static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
|
||||
int win, int group_len, const float lambda)
|
||||
{
|
||||
BandCodingPath path[120][12];
|
||||
int w, swb, cb, start, start2, size;
|
||||
int i, j;
|
||||
const int max_sfb = sce->ics.max_sfb;
|
||||
const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
|
||||
const int run_esc = (1 << run_bits) - 1;
|
||||
int idx, ppos, count;
|
||||
int stackrun[120], stackcb[120], stack_len;
|
||||
float next_minrd = INFINITY;
|
||||
int next_mincb = 0;
|
||||
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
start = win*128;
|
||||
for (cb = 0; cb < 12; cb++) {
|
||||
path[0][cb].cost = 0.0f;
|
||||
path[0][cb].prev_idx = -1;
|
||||
path[0][cb].run = 0;
|
||||
}
|
||||
for (swb = 0; swb < max_sfb; swb++) {
|
||||
start2 = start;
|
||||
size = sce->ics.swb_sizes[swb];
|
||||
if (sce->zeroes[win*16 + swb]) {
|
||||
for (cb = 0; cb < 12; cb++) {
|
||||
path[swb+1][cb].prev_idx = cb;
|
||||
path[swb+1][cb].cost = path[swb][cb].cost;
|
||||
path[swb+1][cb].run = path[swb][cb].run + 1;
|
||||
}
|
||||
} else {
|
||||
float minrd = next_minrd;
|
||||
int mincb = next_mincb;
|
||||
next_minrd = INFINITY;
|
||||
next_mincb = 0;
|
||||
for (cb = 0; cb < 12; cb++) {
|
||||
float cost_stay_here, cost_get_here;
|
||||
float rd = 0.0f;
|
||||
for (w = 0; w < group_len; w++) {
|
||||
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
|
||||
rd += quantize_band_cost(s, sce->coeffs + start + w*128,
|
||||
s->scoefs + start + w*128, size,
|
||||
sce->sf_idx[(win+w)*16+swb], cb,
|
||||
lambda / band->threshold, INFINITY, NULL);
|
||||
}
|
||||
cost_stay_here = path[swb][cb].cost + rd;
|
||||
cost_get_here = minrd + rd + run_bits + 4;
|
||||
if ( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
|
||||
!= run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
|
||||
cost_stay_here += run_bits;
|
||||
if (cost_get_here < cost_stay_here) {
|
||||
path[swb+1][cb].prev_idx = mincb;
|
||||
path[swb+1][cb].cost = cost_get_here;
|
||||
path[swb+1][cb].run = 1;
|
||||
} else {
|
||||
path[swb+1][cb].prev_idx = cb;
|
||||
path[swb+1][cb].cost = cost_stay_here;
|
||||
path[swb+1][cb].run = path[swb][cb].run + 1;
|
||||
}
|
||||
if (path[swb+1][cb].cost < next_minrd) {
|
||||
next_minrd = path[swb+1][cb].cost;
|
||||
next_mincb = cb;
|
||||
}
|
||||
}
|
||||
}
|
||||
start += sce->ics.swb_sizes[swb];
|
||||
}
|
||||
|
||||
//convert resulting path from backward-linked list
|
||||
stack_len = 0;
|
||||
idx = 0;
|
||||
for (cb = 1; cb < 12; cb++)
|
||||
if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)
|
||||
idx = cb;
|
||||
ppos = max_sfb;
|
||||
while (ppos > 0) {
|
||||
cb = idx;
|
||||
stackrun[stack_len] = path[ppos][cb].run;
|
||||
stackcb [stack_len] = cb;
|
||||
idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;
|
||||
ppos -= path[ppos][cb].run;
|
||||
stack_len++;
|
||||
}
|
||||
//perform actual band info encoding
|
||||
start = 0;
|
||||
for (i = stack_len - 1; i >= 0; i--) {
|
||||
put_bits(&s->pb, 4, stackcb[i]);
|
||||
count = stackrun[i];
|
||||
memset(sce->zeroes + win*16 + start, !stackcb[i], count);
|
||||
//XXX: memset when band_type is also uint8_t
|
||||
for (j = 0; j < count; j++) {
|
||||
sce->band_type[win*16 + start] = stackcb[i];
|
||||
start++;
|
||||
}
|
||||
while (count >= run_esc) {
|
||||
put_bits(&s->pb, run_bits, run_esc);
|
||||
count -= run_esc;
|
||||
}
|
||||
put_bits(&s->pb, run_bits, count);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct TrellisPath {
|
||||
float cost;
|
||||
int prev;
|
||||
int min_val;
|
||||
int max_val;
|
||||
} TrellisPath;
|
||||
|
||||
#define TRELLIS_STAGES 121
|
||||
#define TRELLIS_STATES 256
|
||||
|
||||
static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
const float lambda)
|
||||
{
|
||||
int q, w, w2, g, start = 0;
|
||||
int i, j;
|
||||
int idx;
|
||||
TrellisPath paths[TRELLIS_STAGES][TRELLIS_STATES];
|
||||
int bandaddr[TRELLIS_STAGES];
|
||||
int minq;
|
||||
float mincost;
|
||||
|
||||
for (i = 0; i < TRELLIS_STATES; i++) {
|
||||
paths[0][i].cost = 0.0f;
|
||||
paths[0][i].prev = -1;
|
||||
paths[0][i].min_val = i;
|
||||
paths[0][i].max_val = i;
|
||||
}
|
||||
for (j = 1; j < TRELLIS_STAGES; j++) {
|
||||
for (i = 0; i < TRELLIS_STATES; i++) {
|
||||
paths[j][i].cost = INFINITY;
|
||||
paths[j][i].prev = -2;
|
||||
paths[j][i].min_val = INT_MAX;
|
||||
paths[j][i].max_val = 0;
|
||||
}
|
||||
}
|
||||
idx = 1;
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = sce->coeffs + start;
|
||||
float qmin, qmax;
|
||||
int nz = 0;
|
||||
|
||||
bandaddr[idx] = w * 16 + g;
|
||||
qmin = INT_MAX;
|
||||
qmax = 0.0f;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
if (band->energy <= band->threshold || band->threshold == 0.0f) {
|
||||
sce->zeroes[(w+w2)*16+g] = 1;
|
||||
continue;
|
||||
}
|
||||
sce->zeroes[(w+w2)*16+g] = 0;
|
||||
nz = 1;
|
||||
for (i = 0; i < sce->ics.swb_sizes[g]; i++) {
|
||||
float t = fabsf(coefs[w2*128+i]);
|
||||
if (t > 0.0f)
|
||||
qmin = FFMIN(qmin, t);
|
||||
qmax = FFMAX(qmax, t);
|
||||
}
|
||||
}
|
||||
if (nz) {
|
||||
int minscale, maxscale;
|
||||
float minrd = INFINITY;
|
||||
//minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped
|
||||
minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
//maximum scalefactor index is when maximum coefficient after quantizing is still not zero
|
||||
maxscale = av_clip_uint8(log2(qmax)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
|
||||
for (q = minscale; q < maxscale; q++) {
|
||||
float dists[12], dist;
|
||||
memset(dists, 0, sizeof(dists));
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
int cb;
|
||||
for (cb = 0; cb <= ESC_BT; cb++)
|
||||
dists[cb] += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
|
||||
q, cb, lambda / band->threshold, INFINITY, NULL);
|
||||
}
|
||||
dist = dists[0];
|
||||
for (i = 1; i <= ESC_BT; i++)
|
||||
dist = FFMIN(dist, dists[i]);
|
||||
minrd = FFMIN(minrd, dist);
|
||||
|
||||
for (i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, TRELLIS_STATES); i++) {
|
||||
float cost;
|
||||
int minv, maxv;
|
||||
if (isinf(paths[idx - 1][i].cost))
|
||||
continue;
|
||||
cost = paths[idx - 1][i].cost + dist
|
||||
+ ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
|
||||
minv = FFMIN(paths[idx - 1][i].min_val, q);
|
||||
maxv = FFMAX(paths[idx - 1][i].max_val, q);
|
||||
if (cost < paths[idx][q].cost && maxv-minv < SCALE_MAX_DIFF) {
|
||||
paths[idx][q].cost = cost;
|
||||
paths[idx][q].prev = i;
|
||||
paths[idx][q].min_val = minv;
|
||||
paths[idx][q].max_val = maxv;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (q = 0; q < TRELLIS_STATES; q++) {
|
||||
if (!isinf(paths[idx - 1][q].cost)) {
|
||||
paths[idx][q].cost = paths[idx - 1][q].cost + 1;
|
||||
paths[idx][q].prev = q;
|
||||
paths[idx][q].min_val = FFMIN(paths[idx - 1][q].min_val, q);
|
||||
paths[idx][q].max_val = FFMAX(paths[idx - 1][q].max_val, q);
|
||||
continue;
|
||||
}
|
||||
for (i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, TRELLIS_STATES); i++) {
|
||||
float cost;
|
||||
int minv, maxv;
|
||||
if (isinf(paths[idx - 1][i].cost))
|
||||
continue;
|
||||
cost = paths[idx - 1][i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
|
||||
minv = FFMIN(paths[idx - 1][i].min_val, q);
|
||||
maxv = FFMAX(paths[idx - 1][i].max_val, q);
|
||||
if (cost < paths[idx][q].cost && maxv-minv < SCALE_MAX_DIFF) {
|
||||
paths[idx][q].cost = cost;
|
||||
paths[idx][q].prev = i;
|
||||
paths[idx][q].min_val = minv;
|
||||
paths[idx][q].max_val = maxv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sce->zeroes[w*16+g] = !nz;
|
||||
start += sce->ics.swb_sizes[g];
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
idx--;
|
||||
mincost = paths[idx][0].cost;
|
||||
minq = 0;
|
||||
for (i = 1; i < TRELLIS_STATES; i++) {
|
||||
if (paths[idx][i].cost < mincost) {
|
||||
mincost = paths[idx][i].cost;
|
||||
minq = i;
|
||||
}
|
||||
}
|
||||
while (idx) {
|
||||
sce->sf_idx[bandaddr[idx]] = minq;
|
||||
minq = paths[idx][minq].prev;
|
||||
idx--;
|
||||
}
|
||||
//set the same quantizers inside window groups
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
|
||||
for (g = 0; g < sce->ics.num_swb; g++)
|
||||
for (w2 = 1; w2 < sce->ics.group_len[w]; w2++)
|
||||
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
|
||||
}
|
||||
|
||||
/**
|
||||
* two-loop quantizers search taken from ISO 13818-7 Appendix C
|
||||
*/
|
||||
static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
const float lambda)
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
|
||||
float dists[128], uplims[128];
|
||||
int fflag, minscaler;
|
||||
int its = 0;
|
||||
int allz = 0;
|
||||
float minthr = INFINITY;
|
||||
|
||||
//XXX: some heuristic to determine initial quantizers will reduce search time
|
||||
memset(dists, 0, sizeof(dists));
|
||||
//determine zero bands and upper limits
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
int nz = 0;
|
||||
float uplim = 0.0f;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
uplim += band->threshold;
|
||||
if (band->energy <= band->threshold || band->threshold == 0.0f) {
|
||||
sce->zeroes[(w+w2)*16+g] = 1;
|
||||
continue;
|
||||
}
|
||||
nz = 1;
|
||||
}
|
||||
uplims[w*16+g] = uplim *512;
|
||||
sce->zeroes[w*16+g] = !nz;
|
||||
if (nz)
|
||||
minthr = FFMIN(minthr, uplim);
|
||||
allz = FFMAX(allz, nz);
|
||||
}
|
||||
}
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
if (sce->zeroes[w*16+g]) {
|
||||
sce->sf_idx[w*16+g] = SCALE_ONE_POS;
|
||||
continue;
|
||||
}
|
||||
sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2(uplims[w*16+g]/minthr)*4,59);
|
||||
}
|
||||
}
|
||||
|
||||
if (!allz)
|
||||
return;
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
//perform two-loop search
|
||||
//outer loop - improve quality
|
||||
do {
|
||||
int tbits, qstep;
|
||||
minscaler = sce->sf_idx[0];
|
||||
//inner loop - quantize spectrum to fit into given number of bits
|
||||
qstep = its ? 1 : 32;
|
||||
do {
|
||||
int prev = -1;
|
||||
tbits = 0;
|
||||
fflag = 0;
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = sce->coeffs + start;
|
||||
const float *scaled = s->scoefs + start;
|
||||
int bits = 0;
|
||||
int cb;
|
||||
float mindist = INFINITY;
|
||||
int minbits = 0;
|
||||
|
||||
if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) {
|
||||
start += sce->ics.swb_sizes[g];
|
||||
continue;
|
||||
}
|
||||
minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
|
||||
for (cb = 0; cb <= ESC_BT; cb++) {
|
||||
float dist = 0.0f;
|
||||
int bb = 0;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[w*16+g],
|
||||
cb,
|
||||
lambda,
|
||||
INFINITY,
|
||||
&b);
|
||||
bb += b;
|
||||
}
|
||||
if (dist < mindist) {
|
||||
mindist = dist;
|
||||
minbits = bb;
|
||||
}
|
||||
}
|
||||
dists[w*16+g] = (mindist - minbits) / lambda;
|
||||
bits = minbits;
|
||||
if (prev != -1) {
|
||||
bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
|
||||
}
|
||||
tbits += bits;
|
||||
start += sce->ics.swb_sizes[g];
|
||||
prev = sce->sf_idx[w*16+g];
|
||||
}
|
||||
}
|
||||
if (tbits > destbits) {
|
||||
for (i = 0; i < 128; i++)
|
||||
if (sce->sf_idx[i] < 218 - qstep)
|
||||
sce->sf_idx[i] += qstep;
|
||||
} else {
|
||||
for (i = 0; i < 128; i++)
|
||||
if (sce->sf_idx[i] > 60 - qstep)
|
||||
sce->sf_idx[i] -= qstep;
|
||||
}
|
||||
qstep >>= 1;
|
||||
if (!qstep && tbits > destbits*1.02)
|
||||
qstep = 1;
|
||||
if (sce->sf_idx[0] >= 217)
|
||||
break;
|
||||
} while (qstep);
|
||||
|
||||
fflag = 0;
|
||||
minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
int prevsc = sce->sf_idx[w*16+g];
|
||||
if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)
|
||||
sce->sf_idx[w*16+g]--;
|
||||
sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
|
||||
sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
|
||||
if (sce->sf_idx[w*16+g] != prevsc)
|
||||
fflag = 1;
|
||||
}
|
||||
}
|
||||
its++;
|
||||
} while (fflag && its < 10);
|
||||
}
|
||||
|
||||
static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
const float lambda)
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
float uplim[128], maxq[128];
|
||||
int minq, maxsf;
|
||||
float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
|
||||
int last = 0, lastband = 0, curband = 0;
|
||||
float avg_energy = 0.0;
|
||||
if (sce->ics.num_windows == 1) {
|
||||
start = 0;
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (i - start >= sce->ics.swb_sizes[curband]) {
|
||||
start += sce->ics.swb_sizes[curband];
|
||||
curband++;
|
||||
}
|
||||
if (sce->coeffs[i]) {
|
||||
avg_energy += sce->coeffs[i] * sce->coeffs[i];
|
||||
last = i;
|
||||
lastband = curband;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (w = 0; w < 8; w++) {
|
||||
const float *coeffs = sce->coeffs + w*128;
|
||||
start = 0;
|
||||
for (i = 0; i < 128; i++) {
|
||||
if (i - start >= sce->ics.swb_sizes[curband]) {
|
||||
start += sce->ics.swb_sizes[curband];
|
||||
curband++;
|
||||
}
|
||||
if (coeffs[i]) {
|
||||
avg_energy += coeffs[i] * coeffs[i];
|
||||
last = FFMAX(last, i);
|
||||
lastband = FFMAX(lastband, curband);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
last++;
|
||||
avg_energy /= last;
|
||||
if (avg_energy == 0.0f) {
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sce->sf_idx); i++)
|
||||
sce->sf_idx[i] = SCALE_ONE_POS;
|
||||
return;
|
||||
}
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
float *coefs = sce->coeffs + start;
|
||||
const int size = sce->ics.swb_sizes[g];
|
||||
int start2 = start, end2 = start + size, peakpos = start;
|
||||
float maxval = -1, thr = 0.0f, t;
|
||||
maxq[w*16+g] = 0.0f;
|
||||
if (g > lastband) {
|
||||
maxq[w*16+g] = 0.0f;
|
||||
start += size;
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++)
|
||||
memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
|
||||
continue;
|
||||
}
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
float t = coefs[w2*128+i]*coefs[w2*128+i];
|
||||
maxq[w*16+g] = FFMAX(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
|
||||
thr += t;
|
||||
if (sce->ics.num_windows == 1 && maxval < t) {
|
||||
maxval = t;
|
||||
peakpos = start+i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sce->ics.num_windows == 1) {
|
||||
start2 = FFMAX(peakpos - 2, start2);
|
||||
end2 = FFMIN(peakpos + 3, end2);
|
||||
} else {
|
||||
start2 -= start;
|
||||
end2 -= start;
|
||||
}
|
||||
start += size;
|
||||
thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
|
||||
t = 1.0 - (1.0 * start2 / last);
|
||||
uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
|
||||
}
|
||||
}
|
||||
memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
const float *coefs = sce->coeffs + start;
|
||||
const float *scaled = s->scoefs + start;
|
||||
const int size = sce->ics.swb_sizes[g];
|
||||
int scf, prev_scf, step;
|
||||
int min_scf = -1, max_scf = 256;
|
||||
float curdiff;
|
||||
if (maxq[w*16+g] < 21.544) {
|
||||
sce->zeroes[w*16+g] = 1;
|
||||
start += size;
|
||||
continue;
|
||||
}
|
||||
sce->zeroes[w*16+g] = 0;
|
||||
scf = prev_scf = av_clip(SCALE_ONE_POS - SCALE_DIV_512 - log2(1/maxq[w*16+g])*16/3, 60, 218);
|
||||
step = 16;
|
||||
for (;;) {
|
||||
float dist = 0.0f;
|
||||
int quant_max;
|
||||
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
scf,
|
||||
ESC_BT,
|
||||
lambda,
|
||||
INFINITY,
|
||||
&b);
|
||||
dist -= b;
|
||||
}
|
||||
dist *= 1.0f / 512.0f / lambda;
|
||||
quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS - SCALE_DIV_512]);
|
||||
if (quant_max >= 8191) { // too much, return to the previous quantizer
|
||||
sce->sf_idx[w*16+g] = prev_scf;
|
||||
break;
|
||||
}
|
||||
prev_scf = scf;
|
||||
curdiff = fabsf(dist - uplim[w*16+g]);
|
||||
if (curdiff <= 1.0f)
|
||||
step = 0;
|
||||
else
|
||||
step = log2(curdiff);
|
||||
if (dist > uplim[w*16+g])
|
||||
step = -step;
|
||||
scf += step;
|
||||
scf = av_clip_uint8(scf);
|
||||
step = scf - prev_scf;
|
||||
if (FFABS(step) <= 1 || (step > 0 && scf >= max_scf) || (step < 0 && scf <= min_scf)) {
|
||||
sce->sf_idx[w*16+g] = av_clip(scf, min_scf, max_scf);
|
||||
break;
|
||||
}
|
||||
if (step > 0)
|
||||
min_scf = prev_scf;
|
||||
else
|
||||
max_scf = prev_scf;
|
||||
}
|
||||
start += size;
|
||||
}
|
||||
}
|
||||
minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
|
||||
for (i = 1; i < 128; i++) {
|
||||
if (!sce->sf_idx[i])
|
||||
sce->sf_idx[i] = sce->sf_idx[i-1];
|
||||
else
|
||||
minq = FFMIN(minq, sce->sf_idx[i]);
|
||||
}
|
||||
if (minq == INT_MAX)
|
||||
minq = 0;
|
||||
minq = FFMIN(minq, SCALE_MAX_POS);
|
||||
maxsf = FFMIN(minq + SCALE_MAX_DIFF, SCALE_MAX_POS);
|
||||
for (i = 126; i >= 0; i--) {
|
||||
if (!sce->sf_idx[i])
|
||||
sce->sf_idx[i] = sce->sf_idx[i+1];
|
||||
sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, maxsf);
|
||||
}
|
||||
}
|
||||
|
||||
static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
const float lambda)
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
int minq = 255;
|
||||
|
||||
memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
for (g = 0; g < sce->ics.num_swb; g++) {
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
if (band->energy <= band->threshold) {
|
||||
sce->sf_idx[(w+w2)*16+g] = 218;
|
||||
sce->zeroes[(w+w2)*16+g] = 1;
|
||||
} else {
|
||||
sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218);
|
||||
sce->zeroes[(w+w2)*16+g] = 0;
|
||||
}
|
||||
minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 128; i++) {
|
||||
sce->sf_idx[i] = 140;
|
||||
//av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
|
||||
}
|
||||
//set the same quantizers inside window groups
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
|
||||
for (g = 0; g < sce->ics.num_swb; g++)
|
||||
for (w2 = 1; w2 < sce->ics.group_len[w]; w2++)
|
||||
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
|
||||
}
|
||||
|
||||
static void search_for_ms(AACEncContext *s, ChannelElement *cpe,
|
||||
const float lambda)
|
||||
{
|
||||
int start = 0, i, w, w2, g;
|
||||
float M[128], S[128];
|
||||
float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3;
|
||||
SingleChannelElement *sce0 = &cpe->ch[0];
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
if (!cpe->common_window)
|
||||
return;
|
||||
for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) {
|
||||
for (g = 0; g < sce0->ics.num_swb; g++) {
|
||||
if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) {
|
||||
float dist1 = 0.0f, dist2 = 0.0f;
|
||||
for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) {
|
||||
FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
|
||||
float minthr = FFMIN(band0->threshold, band1->threshold);
|
||||
float maxthr = FFMAX(band0->threshold, band1->threshold);
|
||||
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
|
||||
M[i] = (sce0->coeffs[start+w2*128+i]
|
||||
+ sce1->coeffs[start+w2*128+i]) * 0.5;
|
||||
S[i] = sce0->coeffs[start+w2*128+i]
|
||||
- sce1->coeffs[start+w2*128+i];
|
||||
}
|
||||
abs_pow34_v(L34, sce0->coeffs+start+w2*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(R34, sce1->coeffs+start+w2*128, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(M34, M, sce0->ics.swb_sizes[g]);
|
||||
abs_pow34_v(S34, S, sce0->ics.swb_sizes[g]);
|
||||
dist1 += quantize_band_cost(s, sce0->coeffs + start + w2*128,
|
||||
L34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[(w+w2)*16+g],
|
||||
sce0->band_type[(w+w2)*16+g],
|
||||
lambda / band0->threshold, INFINITY, NULL);
|
||||
dist1 += quantize_band_cost(s, sce1->coeffs + start + w2*128,
|
||||
R34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[(w+w2)*16+g],
|
||||
sce1->band_type[(w+w2)*16+g],
|
||||
lambda / band1->threshold, INFINITY, NULL);
|
||||
dist2 += quantize_band_cost(s, M,
|
||||
M34,
|
||||
sce0->ics.swb_sizes[g],
|
||||
sce0->sf_idx[(w+w2)*16+g],
|
||||
sce0->band_type[(w+w2)*16+g],
|
||||
lambda / maxthr, INFINITY, NULL);
|
||||
dist2 += quantize_band_cost(s, S,
|
||||
S34,
|
||||
sce1->ics.swb_sizes[g],
|
||||
sce1->sf_idx[(w+w2)*16+g],
|
||||
sce1->band_type[(w+w2)*16+g],
|
||||
lambda / minthr, INFINITY, NULL);
|
||||
}
|
||||
cpe->ms_mask[w*16+g] = dist2 < dist1;
|
||||
}
|
||||
start += sce0->ics.swb_sizes[g];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AACCoefficientsEncoder ff_aac_coders[] = {
|
||||
{
|
||||
search_for_quantizers_faac,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
search_for_ms,
|
||||
},
|
||||
{
|
||||
search_for_quantizers_anmr,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
search_for_ms,
|
||||
},
|
||||
{
|
||||
search_for_quantizers_twoloop,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
search_for_ms,
|
||||
},
|
||||
{
|
||||
search_for_quantizers_fast,
|
||||
encode_window_bands_info,
|
||||
quantize_and_encode_band,
|
||||
search_for_ms,
|
||||
},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* AAC decoder data
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC decoder data
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACDECTAB_H
|
||||
#define AVCODEC_AACDECTAB_H
|
||||
|
||||
#include "aac.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* @name tns_tmp2_map
|
||||
* Tables of the tmp2[] arrays of LPC coefficients used for TNS.
|
||||
* The suffix _M_N[] indicate the values of coef_compress and coef_res
|
||||
* respectively.
|
||||
* @{
|
||||
*/
|
||||
static const float tns_tmp2_map_1_3[4] = {
|
||||
0.00000000, -0.43388373, 0.64278758, 0.34202015,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_0_3[8] = {
|
||||
0.00000000, -0.43388373, -0.78183150, -0.97492790,
|
||||
0.98480773, 0.86602539, 0.64278758, 0.34202015,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_1_4[8] = {
|
||||
0.00000000, -0.20791170, -0.40673664, -0.58778524,
|
||||
0.67369562, 0.52643216, 0.36124167, 0.18374951,
|
||||
};
|
||||
|
||||
static const float tns_tmp2_map_0_4[16] = {
|
||||
0.00000000, -0.20791170, -0.40673664, -0.58778524,
|
||||
-0.74314481, -0.86602539, -0.95105654, -0.99452192,
|
||||
0.99573416, 0.96182561, 0.89516330, 0.79801720,
|
||||
0.67369562, 0.52643216, 0.36124167, 0.18374951,
|
||||
};
|
||||
|
||||
static const float * const tns_tmp2_map[4] = {
|
||||
tns_tmp2_map_0_3,
|
||||
tns_tmp2_map_0_4,
|
||||
tns_tmp2_map_1_3,
|
||||
tns_tmp2_map_1_4
|
||||
};
|
||||
// @}
|
||||
|
||||
static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static const uint8_t aac_channel_layout_map[7][5][2] = {
|
||||
{ { TYPE_SCE, 0 }, },
|
||||
{ { TYPE_CPE, 0 }, },
|
||||
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, },
|
||||
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_SCE, 1 }, },
|
||||
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_CPE, 1 }, },
|
||||
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_LFE, 0 }, { TYPE_CPE, 1 }, },
|
||||
{ { TYPE_CPE, 0 }, { TYPE_SCE, 0 }, { TYPE_LFE, 0 }, { TYPE_CPE, 2 }, { TYPE_CPE, 1 }, },
|
||||
};
|
||||
|
||||
static const int64_t aac_channel_layout[8] = {
|
||||
CH_LAYOUT_MONO,
|
||||
CH_LAYOUT_STEREO,
|
||||
CH_LAYOUT_SURROUND,
|
||||
CH_LAYOUT_4POINT0,
|
||||
CH_LAYOUT_5POINT0_BACK,
|
||||
CH_LAYOUT_5POINT1_BACK,
|
||||
CH_LAYOUT_7POINT1_WIDE,
|
||||
0,
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_AACDECTAB_H */
|
||||
@@ -1,644 +0,0 @@
|
||||
/*
|
||||
* AAC encoder
|
||||
* Copyright (C) 2008 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder
|
||||
*/
|
||||
|
||||
/***********************************
|
||||
* TODOs:
|
||||
* add sane pulse detection
|
||||
* add temporal noise shaping
|
||||
***********************************/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "put_bits.h"
|
||||
#include "dsputil.h"
|
||||
#include "mpeg4audio.h"
|
||||
|
||||
#include "aac.h"
|
||||
#include "aactab.h"
|
||||
#include "aacenc.h"
|
||||
|
||||
#include "psymodel.h"
|
||||
|
||||
static const uint8_t swb_size_1024_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_64[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
|
||||
12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_48[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
96
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_32[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_16[] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
|
||||
32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_1024_8[] = {
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
|
||||
32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
|
||||
};
|
||||
|
||||
static const uint8_t *swb_size_1024[] = {
|
||||
swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
|
||||
swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
|
||||
swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
|
||||
swb_size_1024_16, swb_size_1024_16, swb_size_1024_8
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_96[] = {
|
||||
4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_48[] = {
|
||||
4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_24[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_16[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t swb_size_128_8[] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
|
||||
};
|
||||
|
||||
static const uint8_t *swb_size_128[] = {
|
||||
/* the last entry on the following row is swb_size_128_64 but is a
|
||||
duplicate of swb_size_128_96 */
|
||||
swb_size_128_96, swb_size_128_96, swb_size_128_96,
|
||||
swb_size_128_48, swb_size_128_48, swb_size_128_48,
|
||||
swb_size_128_24, swb_size_128_24, swb_size_128_16,
|
||||
swb_size_128_16, swb_size_128_16, swb_size_128_8
|
||||
};
|
||||
|
||||
/** default channel configurations */
|
||||
static const uint8_t aac_chan_configs[6][5] = {
|
||||
{1, TYPE_SCE}, // 1 channel - single channel element
|
||||
{1, TYPE_CPE}, // 2 channels - channel pair
|
||||
{2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center
|
||||
{3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo
|
||||
{4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
|
||||
};
|
||||
|
||||
/**
|
||||
* Make AAC audio config object.
|
||||
* @see 1.6.2.1 "Syntax - AudioSpecificConfig"
|
||||
*/
|
||||
static void put_audio_specific_config(AVCodecContext *avctx)
|
||||
{
|
||||
PutBitContext pb;
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
|
||||
init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);
|
||||
put_bits(&pb, 5, 2); //object type - AAC-LC
|
||||
put_bits(&pb, 4, s->samplerate_index); //sample rate index
|
||||
put_bits(&pb, 4, avctx->channels);
|
||||
//GASpecificConfig
|
||||
put_bits(&pb, 1, 0); //frame length - 1024 samples
|
||||
put_bits(&pb, 1, 0); //does not depend on core coder
|
||||
put_bits(&pb, 1, 0); //is not extension
|
||||
flush_put_bits(&pb);
|
||||
}
|
||||
|
||||
static av_cold int aac_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
int i;
|
||||
const uint8_t *sizes[2];
|
||||
int lengths[2];
|
||||
|
||||
avctx->frame_size = 1024;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
|
||||
break;
|
||||
if (i == 16) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
|
||||
return -1;
|
||||
}
|
||||
if (avctx->channels > 6) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);
|
||||
return -1;
|
||||
}
|
||||
if (avctx->profile != FF_PROFILE_UNKNOWN && avctx->profile != FF_PROFILE_AAC_LOW) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported profile %d\n", avctx->profile);
|
||||
return -1;
|
||||
}
|
||||
if (1024.0 * avctx->bit_rate / avctx->sample_rate > 6144 * avctx->channels) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Too many bits per frame requested\n");
|
||||
return -1;
|
||||
}
|
||||
s->samplerate_index = i;
|
||||
|
||||
dsputil_init(&s->dsp, avctx);
|
||||
ff_mdct_init(&s->mdct1024, 11, 0, 1.0);
|
||||
ff_mdct_init(&s->mdct128, 8, 0, 1.0);
|
||||
// window init
|
||||
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
|
||||
ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
|
||||
ff_init_ff_sine_windows(10);
|
||||
ff_init_ff_sine_windows(7);
|
||||
|
||||
s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
|
||||
s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
|
||||
avctx->extradata = av_malloc(2);
|
||||
avctx->extradata_size = 2;
|
||||
put_audio_specific_config(avctx);
|
||||
|
||||
sizes[0] = swb_size_1024[i];
|
||||
sizes[1] = swb_size_128[i];
|
||||
lengths[0] = ff_aac_num_swb_1024[i];
|
||||
lengths[1] = ff_aac_num_swb_128[i];
|
||||
ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
|
||||
s->psypp = ff_psy_preprocess_init(avctx);
|
||||
s->coder = &ff_aac_coders[2];
|
||||
|
||||
s->lambda = avctx->global_quality ? avctx->global_quality : 120;
|
||||
|
||||
ff_aac_tableinit();
|
||||
|
||||
if (avctx->channels > 5)
|
||||
av_log(avctx, AV_LOG_ERROR, "This encoder does not yet enforce the restrictions on LFEs. "
|
||||
"The output will most likely be an illegal bitstream.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce, short *audio, int channel)
|
||||
{
|
||||
int i, j, k;
|
||||
const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
|
||||
const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
|
||||
const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
|
||||
|
||||
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
memcpy(s->output, sce->saved, sizeof(float)*1024);
|
||||
if (sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE) {
|
||||
memset(s->output, 0, sizeof(s->output[0]) * 448);
|
||||
for (i = 448; i < 576; i++)
|
||||
s->output[i] = sce->saved[i] * pwindow[i - 448];
|
||||
for (i = 576; i < 704; i++)
|
||||
s->output[i] = sce->saved[i];
|
||||
}
|
||||
if (sce->ics.window_sequence[0] != LONG_START_SEQUENCE) {
|
||||
for (i = 0, j = channel; i < 1024; i++, j += avctx->channels) {
|
||||
s->output[i+1024] = audio[j] * lwindow[1024 - i - 1];
|
||||
sce->saved[i] = audio[j] * lwindow[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0, j = channel; i < 448; i++, j += avctx->channels)
|
||||
s->output[i+1024] = audio[j];
|
||||
for (; i < 576; i++, j += avctx->channels)
|
||||
s->output[i+1024] = audio[j] * swindow[576 - i - 1];
|
||||
memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448);
|
||||
for (i = 0, j = channel; i < 1024; i++, j += avctx->channels)
|
||||
sce->saved[i] = audio[j];
|
||||
}
|
||||
ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output);
|
||||
} else {
|
||||
for (k = 0; k < 1024; k += 128) {
|
||||
for (i = 448 + k; i < 448 + k + 256; i++)
|
||||
s->output[i - 448 - k] = (i < 1024)
|
||||
? sce->saved[i]
|
||||
: audio[channel + (i-1024)*avctx->channels];
|
||||
s->dsp.vector_fmul (s->output, k ? swindow : pwindow, 128);
|
||||
s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128);
|
||||
ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output);
|
||||
}
|
||||
for (i = 0, j = channel; i < 1024; i++, j += avctx->channels)
|
||||
sce->saved[i] = audio[j];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode ics_info element.
|
||||
* @see Table 4.6 (syntax of ics_info)
|
||||
*/
|
||||
static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
|
||||
{
|
||||
int w;
|
||||
|
||||
put_bits(&s->pb, 1, 0); // ics_reserved bit
|
||||
put_bits(&s->pb, 2, info->window_sequence[0]);
|
||||
put_bits(&s->pb, 1, info->use_kb_window[0]);
|
||||
if (info->window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
put_bits(&s->pb, 6, info->max_sfb);
|
||||
put_bits(&s->pb, 1, 0); // no prediction
|
||||
} else {
|
||||
put_bits(&s->pb, 4, info->max_sfb);
|
||||
for (w = 1; w < 8; w++)
|
||||
put_bits(&s->pb, 1, !info->group_len[w]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode MS data.
|
||||
* @see 4.6.8.1 "Joint Coding - M/S Stereo"
|
||||
*/
|
||||
static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
|
||||
{
|
||||
int i, w;
|
||||
|
||||
put_bits(pb, 2, cpe->ms_mode);
|
||||
if (cpe->ms_mode == 1)
|
||||
for (w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w])
|
||||
for (i = 0; i < cpe->ch[0].ics.max_sfb; i++)
|
||||
put_bits(pb, 1, cpe->ms_mask[w*16 + i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce integer coefficients from scalefactors provided by the model.
|
||||
*/
|
||||
static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
|
||||
{
|
||||
int i, w, w2, g, ch;
|
||||
int start, sum, maxsfb, cmaxsfb;
|
||||
|
||||
for (ch = 0; ch < chans; ch++) {
|
||||
IndividualChannelStream *ics = &cpe->ch[ch].ics;
|
||||
start = 0;
|
||||
maxsfb = 0;
|
||||
cpe->ch[ch].pulse.num_pulse = 0;
|
||||
for (w = 0; w < ics->num_windows*16; w += 16) {
|
||||
for (g = 0; g < ics->num_swb; g++) {
|
||||
sum = 0;
|
||||
//apply M/S
|
||||
if (!ch && cpe->ms_mask[w + g]) {
|
||||
for (i = 0; i < ics->swb_sizes[g]; i++) {
|
||||
cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
|
||||
cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
|
||||
}
|
||||
}
|
||||
start += ics->swb_sizes[g];
|
||||
}
|
||||
for (cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--)
|
||||
;
|
||||
maxsfb = FFMAX(maxsfb, cmaxsfb);
|
||||
}
|
||||
ics->max_sfb = maxsfb;
|
||||
|
||||
//adjust zero bands for window groups
|
||||
for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
|
||||
for (g = 0; g < ics->max_sfb; g++) {
|
||||
i = 1;
|
||||
for (w2 = w; w2 < w + ics->group_len[w]; w2++) {
|
||||
if (!cpe->ch[ch].zeroes[w2*16 + g]) {
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cpe->ch[ch].zeroes[w*16 + g] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (chans > 1 && cpe->common_window) {
|
||||
IndividualChannelStream *ics0 = &cpe->ch[0].ics;
|
||||
IndividualChannelStream *ics1 = &cpe->ch[1].ics;
|
||||
int msc = 0;
|
||||
ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb);
|
||||
ics1->max_sfb = ics0->max_sfb;
|
||||
for (w = 0; w < ics0->num_windows*16; w += 16)
|
||||
for (i = 0; i < ics0->max_sfb; i++)
|
||||
if (cpe->ms_mask[w+i])
|
||||
msc++;
|
||||
if (msc == 0 || ics0->max_sfb == 0)
|
||||
cpe->ms_mode = 0;
|
||||
else
|
||||
cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode scalefactor band coding type.
|
||||
*/
|
||||
static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int w;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
|
||||
s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w], s->lambda);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode scalefactors.
|
||||
*/
|
||||
static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce)
|
||||
{
|
||||
int off = sce->sf_idx[0], diff;
|
||||
int i, w;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
for (i = 0; i < sce->ics.max_sfb; i++) {
|
||||
if (!sce->zeroes[w*16 + i]) {
|
||||
diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
|
||||
if (diff < 0 || diff > 120)
|
||||
av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n");
|
||||
off = sce->sf_idx[w*16 + i];
|
||||
put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode pulse data.
|
||||
*/
|
||||
static void encode_pulses(AACEncContext *s, Pulse *pulse)
|
||||
{
|
||||
int i;
|
||||
|
||||
put_bits(&s->pb, 1, !!pulse->num_pulse);
|
||||
if (!pulse->num_pulse)
|
||||
return;
|
||||
|
||||
put_bits(&s->pb, 2, pulse->num_pulse - 1);
|
||||
put_bits(&s->pb, 6, pulse->start);
|
||||
for (i = 0; i < pulse->num_pulse; i++) {
|
||||
put_bits(&s->pb, 5, pulse->pos[i]);
|
||||
put_bits(&s->pb, 4, pulse->amp[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode spectral coefficients processed by psychoacoustic model.
|
||||
*/
|
||||
static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
|
||||
{
|
||||
int start, i, w, w2;
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = 0;
|
||||
for (i = 0; i < sce->ics.max_sfb; i++) {
|
||||
if (sce->zeroes[w*16 + i]) {
|
||||
start += sce->ics.swb_sizes[i];
|
||||
continue;
|
||||
}
|
||||
for (w2 = w; w2 < w + sce->ics.group_len[w]; w2++)
|
||||
s->coder->quantize_and_encode_band(s, &s->pb, sce->coeffs + start + w2*128,
|
||||
sce->ics.swb_sizes[i],
|
||||
sce->sf_idx[w*16 + i],
|
||||
sce->band_type[w*16 + i],
|
||||
s->lambda);
|
||||
start += sce->ics.swb_sizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode one channel of audio data.
|
||||
*/
|
||||
static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s,
|
||||
SingleChannelElement *sce,
|
||||
int common_window)
|
||||
{
|
||||
put_bits(&s->pb, 8, sce->sf_idx[0]);
|
||||
if (!common_window)
|
||||
put_ics_info(s, &sce->ics);
|
||||
encode_band_info(s, sce);
|
||||
encode_scale_factors(avctx, s, sce);
|
||||
encode_pulses(s, &sce->pulse);
|
||||
put_bits(&s->pb, 1, 0); //tns
|
||||
put_bits(&s->pb, 1, 0); //ssr
|
||||
encode_spectral_coeffs(s, sce);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write some auxiliary information about the created AAC file.
|
||||
*/
|
||||
static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s,
|
||||
const char *name)
|
||||
{
|
||||
int i, namelen, padbits;
|
||||
|
||||
namelen = strlen(name) + 2;
|
||||
put_bits(&s->pb, 3, TYPE_FIL);
|
||||
put_bits(&s->pb, 4, FFMIN(namelen, 15));
|
||||
if (namelen >= 15)
|
||||
put_bits(&s->pb, 8, namelen - 16);
|
||||
put_bits(&s->pb, 4, 0); //extension type - filler
|
||||
padbits = 8 - (put_bits_count(&s->pb) & 7);
|
||||
align_put_bits(&s->pb);
|
||||
for (i = 0; i < namelen - 2; i++)
|
||||
put_bits(&s->pb, 8, name[i]);
|
||||
put_bits(&s->pb, 12 - padbits, 0);
|
||||
}
|
||||
|
||||
static int aac_encode_frame(AVCodecContext *avctx,
|
||||
uint8_t *frame, int buf_size, void *data)
|
||||
{
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
int16_t *samples = s->samples, *samples2, *la;
|
||||
ChannelElement *cpe;
|
||||
int i, j, chans, tag, start_ch;
|
||||
const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
|
||||
int chan_el_counter[4];
|
||||
FFPsyWindowInfo windows[avctx->channels];
|
||||
|
||||
if (s->last_frame)
|
||||
return 0;
|
||||
if (data) {
|
||||
if (!s->psypp) {
|
||||
memcpy(s->samples + 1024 * avctx->channels, data,
|
||||
1024 * avctx->channels * sizeof(s->samples[0]));
|
||||
} else {
|
||||
start_ch = 0;
|
||||
samples2 = s->samples + 1024 * avctx->channels;
|
||||
for (i = 0; i < chan_map[0]; i++) {
|
||||
tag = chan_map[i+1];
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch,
|
||||
samples2 + start_ch, start_ch, chans);
|
||||
start_ch += chans;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!avctx->frame_number) {
|
||||
memcpy(s->samples, s->samples + 1024 * avctx->channels,
|
||||
1024 * avctx->channels * sizeof(s->samples[0]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
start_ch = 0;
|
||||
for (i = 0; i < chan_map[0]; i++) {
|
||||
FFPsyWindowInfo* wi = windows + start_ch;
|
||||
tag = chan_map[i+1];
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
cpe = &s->cpe[i];
|
||||
samples2 = samples + start_ch;
|
||||
la = samples2 + 1024 * avctx->channels + start_ch;
|
||||
if (!data)
|
||||
la = NULL;
|
||||
for (j = 0; j < chans; j++) {
|
||||
IndividualChannelStream *ics = &cpe->ch[j].ics;
|
||||
int k;
|
||||
wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]);
|
||||
ics->window_sequence[1] = ics->window_sequence[0];
|
||||
ics->window_sequence[0] = wi[j].window_type[0];
|
||||
ics->use_kb_window[1] = ics->use_kb_window[0];
|
||||
ics->use_kb_window[0] = wi[j].window_shape;
|
||||
ics->num_windows = wi[j].num_windows;
|
||||
ics->swb_sizes = s->psy.bands [ics->num_windows == 8];
|
||||
ics->num_swb = s->psy.num_bands[ics->num_windows == 8];
|
||||
for (k = 0; k < ics->num_windows; k++)
|
||||
ics->group_len[k] = wi[j].grouping[k];
|
||||
|
||||
s->cur_channel = start_ch + j;
|
||||
apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
|
||||
}
|
||||
start_ch += chans;
|
||||
}
|
||||
do {
|
||||
int frame_bits;
|
||||
init_put_bits(&s->pb, frame, buf_size*8);
|
||||
if ((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT))
|
||||
put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
|
||||
start_ch = 0;
|
||||
memset(chan_el_counter, 0, sizeof(chan_el_counter));
|
||||
for (i = 0; i < chan_map[0]; i++) {
|
||||
FFPsyWindowInfo* wi = windows + start_ch;
|
||||
tag = chan_map[i+1];
|
||||
chans = tag == TYPE_CPE ? 2 : 1;
|
||||
cpe = &s->cpe[i];
|
||||
for (j = 0; j < chans; j++) {
|
||||
s->cur_channel = start_ch + j;
|
||||
ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]);
|
||||
s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda);
|
||||
}
|
||||
cpe->common_window = 0;
|
||||
if (chans > 1
|
||||
&& wi[0].window_type[0] == wi[1].window_type[0]
|
||||
&& wi[0].window_shape == wi[1].window_shape) {
|
||||
|
||||
cpe->common_window = 1;
|
||||
for (j = 0; j < wi[0].num_windows; j++) {
|
||||
if (wi[0].grouping[j] != wi[1].grouping[j]) {
|
||||
cpe->common_window = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
s->cur_channel = start_ch;
|
||||
if (cpe->common_window && s->coder->search_for_ms)
|
||||
s->coder->search_for_ms(s, cpe, s->lambda);
|
||||
adjust_frame_information(s, cpe, chans);
|
||||
put_bits(&s->pb, 3, tag);
|
||||
put_bits(&s->pb, 4, chan_el_counter[tag]++);
|
||||
if (chans == 2) {
|
||||
put_bits(&s->pb, 1, cpe->common_window);
|
||||
if (cpe->common_window) {
|
||||
put_ics_info(s, &cpe->ch[0].ics);
|
||||
encode_ms_info(&s->pb, cpe);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < chans; j++) {
|
||||
s->cur_channel = start_ch + j;
|
||||
encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window);
|
||||
}
|
||||
start_ch += chans;
|
||||
}
|
||||
|
||||
frame_bits = put_bits_count(&s->pb);
|
||||
if (frame_bits <= 6144 * avctx->channels - 3)
|
||||
break;
|
||||
|
||||
s->lambda *= avctx->bit_rate * 1024.0f / avctx->sample_rate / frame_bits;
|
||||
|
||||
} while (1);
|
||||
|
||||
put_bits(&s->pb, 3, TYPE_END);
|
||||
flush_put_bits(&s->pb);
|
||||
avctx->frame_bits = put_bits_count(&s->pb);
|
||||
|
||||
// rate control stuff
|
||||
if (!(avctx->flags & CODEC_FLAG_QSCALE)) {
|
||||
float ratio = avctx->bit_rate * 1024.0f / avctx->sample_rate / avctx->frame_bits;
|
||||
s->lambda *= ratio;
|
||||
s->lambda = FFMIN(s->lambda, 65536.f);
|
||||
}
|
||||
|
||||
if (!data)
|
||||
s->last_frame = 1;
|
||||
memcpy(s->samples, s->samples + 1024 * avctx->channels,
|
||||
1024 * avctx->channels * sizeof(s->samples[0]));
|
||||
return put_bits_count(&s->pb)>>3;
|
||||
}
|
||||
|
||||
static av_cold int aac_encode_end(AVCodecContext *avctx)
|
||||
{
|
||||
AACEncContext *s = avctx->priv_data;
|
||||
|
||||
ff_mdct_end(&s->mdct1024);
|
||||
ff_mdct_end(&s->mdct128);
|
||||
ff_psy_end(&s->psy);
|
||||
ff_psy_preprocess_end(s->psypp);
|
||||
av_freep(&s->samples);
|
||||
av_freep(&s->cpe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec aac_encoder = {
|
||||
"aac",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_AAC,
|
||||
sizeof(AACEncContext),
|
||||
aac_encode_init,
|
||||
aac_encode_frame,
|
||||
aac_encode_end,
|
||||
.capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
|
||||
.sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* AAC encoder
|
||||
* Copyright (C) 2008 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_H
|
||||
#define AVCODEC_AACENC_H
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "put_bits.h"
|
||||
#include "dsputil.h"
|
||||
|
||||
#include "aac.h"
|
||||
|
||||
#include "psymodel.h"
|
||||
|
||||
struct AACEncContext;
|
||||
|
||||
typedef struct AACCoefficientsEncoder {
|
||||
void (*search_for_quantizers)(AVCodecContext *avctx, struct AACEncContext *s,
|
||||
SingleChannelElement *sce, const float lambda);
|
||||
void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce,
|
||||
int win, int group_len, const float lambda);
|
||||
void (*quantize_and_encode_band)(struct AACEncContext *s, PutBitContext *pb, const float *in, int size,
|
||||
int scale_idx, int cb, const float lambda);
|
||||
void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda);
|
||||
} AACCoefficientsEncoder;
|
||||
|
||||
extern AACCoefficientsEncoder ff_aac_coders[];
|
||||
|
||||
/**
|
||||
* AAC encoder context
|
||||
*/
|
||||
typedef struct AACEncContext {
|
||||
PutBitContext pb;
|
||||
FFTContext mdct1024; ///< long (1024 samples) frame transform context
|
||||
FFTContext mdct128; ///< short (128 samples) frame transform context
|
||||
DSPContext dsp;
|
||||
DECLARE_ALIGNED(16, FFTSample, output)[2048]; ///< temporary buffer for MDCT input coefficients
|
||||
int16_t* samples; ///< saved preprocessed input
|
||||
|
||||
int samplerate_index; ///< MPEG-4 samplerate index
|
||||
|
||||
ChannelElement *cpe; ///< channel elements
|
||||
FFPsyContext psy;
|
||||
struct FFPsyPreprocessContext* psypp;
|
||||
AACCoefficientsEncoder *coder;
|
||||
int cur_channel;
|
||||
int last_frame;
|
||||
float lambda;
|
||||
DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients
|
||||
DECLARE_ALIGNED(16, float, scoefs)[1024]; ///< scaled coefficients
|
||||
} AACEncContext;
|
||||
|
||||
#endif /* AVCODEC_AACENC_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* MPEG-4 Parametric Stereo definitions and declarations
|
||||
* Copyright (c) 2010 Alex Converse <[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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_PS_H
|
||||
#define AVCODEC_PS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
#define PS_MAX_NUM_ENV 5
|
||||
#define PS_MAX_NR_IIDICC 34
|
||||
#define PS_MAX_NR_IPDOPD 17
|
||||
#define PS_MAX_SSB 91
|
||||
#define PS_MAX_AP_BANDS 50
|
||||
#define PS_QMF_TIME_SLOTS 32
|
||||
#define PS_MAX_DELAY 14
|
||||
#define PS_AP_LINKS 3
|
||||
#define PS_MAX_AP_DELAY 5
|
||||
|
||||
typedef struct {
|
||||
int start;
|
||||
int enable_iid;
|
||||
int iid_quant;
|
||||
int nr_iid_par;
|
||||
int nr_ipdopd_par;
|
||||
int enable_icc;
|
||||
int icc_mode;
|
||||
int nr_icc_par;
|
||||
int enable_ext;
|
||||
int frame_class;
|
||||
int num_env_old;
|
||||
int num_env;
|
||||
int enable_ipdopd;
|
||||
int border_position[PS_MAX_NUM_ENV+1];
|
||||
int8_t iid_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-channel Intensity Difference Parameters
|
||||
int8_t icc_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-Channel Coherence Parameters
|
||||
/* ipd/opd is iid/icc sized so that the same functions can handle both */
|
||||
int8_t ipd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Inter-channel Phase Difference Parameters
|
||||
int8_t opd_par[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC]; //<Overall Phase Difference Parameters
|
||||
int is34bands;
|
||||
int is34bands_old;
|
||||
|
||||
float in_buf[5][44][2];
|
||||
float delay[PS_MAX_SSB][PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2];
|
||||
float ap_delay[PS_MAX_AP_BANDS][PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2];
|
||||
float peak_decay_nrg[34];
|
||||
float power_smooth[34];
|
||||
float peak_decay_diff_smooth[34];
|
||||
float H11[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
float H12[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
float H21[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
float H22[2][PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC];
|
||||
int8_t opd_hist[PS_MAX_NR_IIDICC];
|
||||
int8_t ipd_hist[PS_MAX_NR_IIDICC];
|
||||
} PSContext;
|
||||
|
||||
void ff_ps_init(void);
|
||||
void ff_ps_ctx_init(PSContext *ps);
|
||||
int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb, PSContext *ps, int bits_left);
|
||||
int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float R[2][38][64], int top);
|
||||
|
||||
#endif /* AVCODEC_PS_H */
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Generate a header file for hardcoded Parametric Stereo tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <[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 <stdlib.h>
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#include "aacps_tablegen.h"
|
||||
#include "tableprint.h"
|
||||
|
||||
void write_float_3d_array (const void *p, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const float *f = p;
|
||||
for (i = 0; i < b; i++) {
|
||||
printf("{\n");
|
||||
write_float_2d_array(f, c, d);
|
||||
printf("},\n");
|
||||
f += c * d;
|
||||
}
|
||||
}
|
||||
|
||||
void write_float_4d_array (const void *p, int a, int b, int c, int d)
|
||||
{
|
||||
int i;
|
||||
const float *f = p;
|
||||
for (i = 0; i < a; i++) {
|
||||
printf("{\n");
|
||||
write_float_3d_array(f, b, c, d);
|
||||
printf("},\n");
|
||||
f += b * c * d;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ps_tableinit();
|
||||
|
||||
write_fileheader();
|
||||
|
||||
printf("static const float pd_re_smooth[8*8*8] = {\n");
|
||||
write_float_array(pd_re_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
printf("static const float pd_im_smooth[8*8*8] = {\n");
|
||||
write_float_array(pd_im_smooth, 8*8*8);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const float HA[46][8][4] = {\n");
|
||||
write_float_3d_array(HA, 46, 8, 4);
|
||||
printf("};\n");
|
||||
printf("static const float HB[46][8][4] = {\n");
|
||||
write_float_3d_array(HB, 46, 8, 4);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const float f20_0_8[8][7][2] = {\n");
|
||||
write_float_3d_array(f20_0_8, 8, 7, 2);
|
||||
printf("};\n");
|
||||
printf("static const float f34_0_12[12][7][2] = {\n");
|
||||
write_float_3d_array(f34_0_12, 12, 7, 2);
|
||||
printf("};\n");
|
||||
printf("static const float f34_1_8[8][7][2] = {\n");
|
||||
write_float_3d_array(f34_1_8, 8, 7, 2);
|
||||
printf("};\n");
|
||||
printf("static const float f34_2_4[4][7][2] = {\n");
|
||||
write_float_3d_array(f34_2_4, 4, 7, 2);
|
||||
printf("};\n");
|
||||
|
||||
printf("static const float Q_fract_allpass[2][50][3][2] = {\n");
|
||||
write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2);
|
||||
printf("};\n");
|
||||
printf("static const float phi_fract[2][50][2] = {\n");
|
||||
write_float_3d_array(phi_fract, 2, 50, 2);
|
||||
printf("};\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Header file for hardcoded Parametric Stereo tables
|
||||
*
|
||||
* Copyright (c) 2010 Alex Converse <[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
|
||||
*/
|
||||
|
||||
#ifndef AACPS_TABLEGEN_H
|
||||
#define AACPS_TABLEGEN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#define ps_tableinit()
|
||||
#include "libavcodec/aacps_tables.h"
|
||||
#else
|
||||
#include "../libavutil/common.h"
|
||||
#include "../libavutil/mathematics.h"
|
||||
#define NR_ALLPASS_BANDS20 30
|
||||
#define NR_ALLPASS_BANDS34 50
|
||||
#define PS_AP_LINKS 3
|
||||
static float pd_re_smooth[8*8*8];
|
||||
static float pd_im_smooth[8*8*8];
|
||||
static float HA[46][8][4];
|
||||
static float HB[46][8][4];
|
||||
static float f20_0_8 [ 8][7][2];
|
||||
static float f34_0_12[12][7][2];
|
||||
static float f34_1_8 [ 8][7][2];
|
||||
static float f34_2_4 [ 4][7][2];
|
||||
static float Q_fract_allpass[2][50][3][2];
|
||||
static float phi_fract[2][50][2];
|
||||
|
||||
static const float g0_Q8[] = {
|
||||
0.00746082949812f, 0.02270420949825f, 0.04546865930473f, 0.07266113929591f,
|
||||
0.09885108575264f, 0.11793710567217f, 0.125f
|
||||
};
|
||||
|
||||
static const float g0_Q12[] = {
|
||||
0.04081179924692f, 0.03812810994926f, 0.05144908135699f, 0.06399831151592f,
|
||||
0.07428313801106f, 0.08100347892914f, 0.08333333333333f
|
||||
};
|
||||
|
||||
static const float g1_Q8[] = {
|
||||
0.01565675600122f, 0.03752716391991f, 0.05417891378782f, 0.08417044116767f,
|
||||
0.10307344158036f, 0.12222452249753f, 0.125f
|
||||
};
|
||||
|
||||
static const float g2_Q4[] = {
|
||||
-0.05908211155639f, -0.04871498374946f, 0.0f, 0.07778723915851f,
|
||||
0.16486303567403f, 0.23279856662996f, 0.25f
|
||||
};
|
||||
|
||||
static void make_filters_from_proto(float (*filter)[7][2], const float *proto, int bands)
|
||||
{
|
||||
int q, n;
|
||||
for (q = 0; q < bands; q++) {
|
||||
for (n = 0; n < 7; n++) {
|
||||
double theta = 2 * M_PI * (q + 0.5) * (n - 6) / bands;
|
||||
filter[q][n][0] = proto[n] * cos(theta);
|
||||
filter[q][n][1] = proto[n] * -sin(theta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ps_tableinit(void)
|
||||
{
|
||||
static const float ipdopd_sin[] = { 0, M_SQRT1_2, 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2 };
|
||||
static const float ipdopd_cos[] = { 1, M_SQRT1_2, 0, -M_SQRT1_2, -1, -M_SQRT1_2, 0, M_SQRT1_2 };
|
||||
int pd0, pd1, pd2;
|
||||
|
||||
static const float iid_par_dequant[] = {
|
||||
//iid_par_dequant_default
|
||||
0.05623413251903, 0.12589254117942, 0.19952623149689, 0.31622776601684,
|
||||
0.44668359215096, 0.63095734448019, 0.79432823472428, 1,
|
||||
1.25892541179417, 1.58489319246111, 2.23872113856834, 3.16227766016838,
|
||||
5.01187233627272, 7.94328234724282, 17.7827941003892,
|
||||
//iid_par_dequant_fine
|
||||
0.00316227766017, 0.00562341325190, 0.01, 0.01778279410039,
|
||||
0.03162277660168, 0.05623413251903, 0.07943282347243, 0.11220184543020,
|
||||
0.15848931924611, 0.22387211385683, 0.31622776601684, 0.39810717055350,
|
||||
0.50118723362727, 0.63095734448019, 0.79432823472428, 1,
|
||||
1.25892541179417, 1.58489319246111, 1.99526231496888, 2.51188643150958,
|
||||
3.16227766016838, 4.46683592150963, 6.30957344480193, 8.91250938133745,
|
||||
12.5892541179417, 17.7827941003892, 31.6227766016838, 56.2341325190349,
|
||||
100, 177.827941003892, 316.227766016837,
|
||||
};
|
||||
static const float icc_invq[] = {
|
||||
1, 0.937, 0.84118, 0.60092, 0.36764, 0, -0.589, -1
|
||||
};
|
||||
static const float acos_icc_invq[] = {
|
||||
0, 0.35685527, 0.57133466, 0.92614472, 1.1943263, M_PI/2, 2.2006171, M_PI
|
||||
};
|
||||
int iid, icc;
|
||||
|
||||
int k, m;
|
||||
static const int8_t f_center_20[] = {
|
||||
-3, -1, 1, 3, 5, 7, 10, 14, 18, 22,
|
||||
};
|
||||
static const int8_t f_center_34[] = {
|
||||
2, 6, 10, 14, 18, 22, 26, 30,
|
||||
34,-10, -6, -2, 51, 57, 15, 21,
|
||||
27, 33, 39, 45, 54, 66, 78, 42,
|
||||
102, 66, 78, 90,102,114,126, 90,
|
||||
};
|
||||
static const float fractional_delay_links[] = { 0.43f, 0.75f, 0.347f };
|
||||
const float fractional_delay_gain = 0.39f;
|
||||
|
||||
for (pd0 = 0; pd0 < 8; pd0++) {
|
||||
float pd0_re = ipdopd_cos[pd0];
|
||||
float pd0_im = ipdopd_sin[pd0];
|
||||
for (pd1 = 0; pd1 < 8; pd1++) {
|
||||
float pd1_re = ipdopd_cos[pd1];
|
||||
float pd1_im = ipdopd_sin[pd1];
|
||||
for (pd2 = 0; pd2 < 8; pd2++) {
|
||||
float pd2_re = ipdopd_cos[pd2];
|
||||
float pd2_im = ipdopd_sin[pd2];
|
||||
float re_smooth = 0.25f * pd0_re + 0.5f * pd1_re + pd2_re;
|
||||
float im_smooth = 0.25f * pd0_im + 0.5f * pd1_im + pd2_im;
|
||||
float pd_mag = 1 / sqrt(im_smooth * im_smooth + re_smooth * re_smooth);
|
||||
pd_re_smooth[pd0*64+pd1*8+pd2] = re_smooth * pd_mag;
|
||||
pd_im_smooth[pd0*64+pd1*8+pd2] = im_smooth * pd_mag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (iid = 0; iid < 46; iid++) {
|
||||
float c = iid_par_dequant[iid]; //<Linear Inter-channel Intensity Difference
|
||||
float c1 = (float)M_SQRT2 / sqrtf(1.0f + c*c);
|
||||
float c2 = c * c1;
|
||||
for (icc = 0; icc < 8; icc++) {
|
||||
/*if (PS_BASELINE || ps->icc_mode < 3)*/ {
|
||||
float alpha = 0.5f * acos_icc_invq[icc];
|
||||
float beta = alpha * (c1 - c2) * (float)M_SQRT1_2;
|
||||
HA[iid][icc][0] = c2 * cosf(beta + alpha);
|
||||
HA[iid][icc][1] = c1 * cosf(beta - alpha);
|
||||
HA[iid][icc][2] = c2 * sinf(beta + alpha);
|
||||
HA[iid][icc][3] = c1 * sinf(beta - alpha);
|
||||
} /* else */ {
|
||||
float alpha, gamma, mu, rho;
|
||||
float alpha_c, alpha_s, gamma_c, gamma_s;
|
||||
rho = FFMAX(icc_invq[icc], 0.05f);
|
||||
alpha = 0.5f * atan2f(2.0f * c * rho, c*c - 1.0f);
|
||||
mu = c + 1.0f / c;
|
||||
mu = sqrtf(1 + (4 * rho * rho - 4)/(mu * mu));
|
||||
gamma = atanf(sqrtf((1.0f - mu)/(1.0f + mu)));
|
||||
if (alpha < 0) alpha += M_PI/2;
|
||||
alpha_c = cosf(alpha);
|
||||
alpha_s = sinf(alpha);
|
||||
gamma_c = cosf(gamma);
|
||||
gamma_s = sinf(gamma);
|
||||
HB[iid][icc][0] = M_SQRT2 * alpha_c * gamma_c;
|
||||
HB[iid][icc][1] = M_SQRT2 * alpha_s * gamma_c;
|
||||
HB[iid][icc][2] = -M_SQRT2 * alpha_s * gamma_s;
|
||||
HB[iid][icc][3] = M_SQRT2 * alpha_c * gamma_s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < NR_ALLPASS_BANDS20; k++) {
|
||||
double f_center, theta;
|
||||
if (k < FF_ARRAY_ELEMS(f_center_20))
|
||||
f_center = f_center_20[k] * 0.125;
|
||||
else
|
||||
f_center = k - 6.5f;
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
theta = -M_PI * fractional_delay_links[m] * f_center;
|
||||
Q_fract_allpass[0][k][m][0] = cos(theta);
|
||||
Q_fract_allpass[0][k][m][1] = sin(theta);
|
||||
}
|
||||
theta = -M_PI*fractional_delay_gain*f_center;
|
||||
phi_fract[0][k][0] = cos(theta);
|
||||
phi_fract[0][k][1] = sin(theta);
|
||||
}
|
||||
for (k = 0; k < NR_ALLPASS_BANDS34; k++) {
|
||||
double f_center, theta;
|
||||
if (k < FF_ARRAY_ELEMS(f_center_34))
|
||||
f_center = f_center_34[k] / 24.;
|
||||
else
|
||||
f_center = k - 26.5f;
|
||||
for (m = 0; m < PS_AP_LINKS; m++) {
|
||||
theta = -M_PI * fractional_delay_links[m] * f_center;
|
||||
Q_fract_allpass[1][k][m][0] = cos(theta);
|
||||
Q_fract_allpass[1][k][m][1] = sin(theta);
|
||||
}
|
||||
theta = -M_PI*fractional_delay_gain*f_center;
|
||||
phi_fract[1][k][0] = cos(theta);
|
||||
phi_fract[1][k][1] = sin(theta);
|
||||
}
|
||||
|
||||
make_filters_from_proto(f20_0_8, g0_Q8, 8);
|
||||
make_filters_from_proto(f34_0_12, g0_Q12, 12);
|
||||
make_filters_from_proto(f34_1_8, g1_Q8, 8);
|
||||
make_filters_from_proto(f34_2_4, g2_Q4, 4);
|
||||
}
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AACPS_TABLEGEN_H */
|
||||
@@ -1,163 +0,0 @@
|
||||
/*
|
||||
* MPEG-4 Parametric Stereo data tables
|
||||
* Copyright (c) 2010 Alex Converse <[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
|
||||
*/
|
||||
|
||||
static const uint8_t huff_iid_df1_bits[] = {
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, 14, 14,
|
||||
13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 17, 18, 17, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18,
|
||||
};
|
||||
|
||||
static const uint32_t huff_iid_df1_codes[] = {
|
||||
0x01FEB4, 0x01FEB5, 0x01FD76, 0x01FD77, 0x01FD74, 0x01FD75, 0x01FE8A,
|
||||
0x01FE8B, 0x01FE88, 0x00FE80, 0x01FEB6, 0x00FE82, 0x00FEB8, 0x007F42,
|
||||
0x007FAE, 0x003FAF, 0x001FD1, 0x001FE9, 0x000FE9, 0x0007EA, 0x0007FB,
|
||||
0x0003FB, 0x0001FB, 0x0001FF, 0x00007C, 0x00003C, 0x00001C, 0x00000C,
|
||||
0x000000, 0x000001, 0x000001, 0x000002, 0x000001, 0x00000D, 0x00001D,
|
||||
0x00003D, 0x00007D, 0x0000FC, 0x0001FC, 0x0003FC, 0x0003F4, 0x0007EB,
|
||||
0x000FEA, 0x001FEA, 0x001FD6, 0x003FD0, 0x007FAF, 0x007F43, 0x00FEB9,
|
||||
0x00FE83, 0x01FEB7, 0x00FE81, 0x01FE89, 0x01FE8E, 0x01FE8F, 0x01FE8C,
|
||||
0x01FE8D, 0x01FEB2, 0x01FEB3, 0x01FEB0, 0x01FEB1,
|
||||
};
|
||||
|
||||
static const uint8_t huff_iid_dt1_bits[] = {
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 13,
|
||||
13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, 5, 6, 7, 8,
|
||||
9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16,
|
||||
};
|
||||
|
||||
static const uint16_t huff_iid_dt1_codes[] = {
|
||||
0x004ED4, 0x004ED5, 0x004ECE, 0x004ECF, 0x004ECC, 0x004ED6, 0x004ED8,
|
||||
0x004F46, 0x004F60, 0x002718, 0x002719, 0x002764, 0x002765, 0x00276D,
|
||||
0x0027B1, 0x0013B7, 0x0013D6, 0x0009C7, 0x0009E9, 0x0009ED, 0x0004EE,
|
||||
0x0004F7, 0x000278, 0x000139, 0x00009A, 0x00009F, 0x000020, 0x000011,
|
||||
0x00000A, 0x000003, 0x000001, 0x000000, 0x00000B, 0x000012, 0x000021,
|
||||
0x00004C, 0x00009B, 0x00013A, 0x000279, 0x000270, 0x0004EF, 0x0004E2,
|
||||
0x0009EA, 0x0009D8, 0x0013D7, 0x0013D0, 0x0027B2, 0x0027A2, 0x00271A,
|
||||
0x00271B, 0x004F66, 0x004F67, 0x004F61, 0x004F47, 0x004ED9, 0x004ED7,
|
||||
0x004ECD, 0x004ED2, 0x004ED3, 0x004ED0, 0x004ED1,
|
||||
};
|
||||
|
||||
static const uint8_t huff_iid_df0_bits[] = {
|
||||
17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, 3, 4, 5,
|
||||
6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18,
|
||||
};
|
||||
|
||||
static const uint32_t huff_iid_df0_codes[] = {
|
||||
0x01FFFB, 0x01FFFC, 0x01FFFD, 0x01FFFA, 0x00FFFC, 0x007FFC, 0x001FFD,
|
||||
0x0003FE, 0x0001FE, 0x00007E, 0x00003C, 0x00001D, 0x00000D, 0x000005,
|
||||
0x000000, 0x000004, 0x00000C, 0x00001C, 0x00003D, 0x00003E, 0x0000FE,
|
||||
0x0007FE, 0x001FFC, 0x003FFC, 0x003FFD, 0x007FFD, 0x01FFFE, 0x03FFFE,
|
||||
0x03FFFF,
|
||||
};
|
||||
|
||||
static const uint8_t huff_iid_dt0_bits[] = {
|
||||
19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, 3, 5, 7,
|
||||
9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20,
|
||||
};
|
||||
|
||||
static const uint32_t huff_iid_dt0_codes[] = {
|
||||
0x07FFF9, 0x07FFFA, 0x07FFFB, 0x0FFFF8, 0x0FFFF9, 0x0FFFFA, 0x01FFFD,
|
||||
0x007FFE, 0x000FFE, 0x0003FE, 0x0000FE, 0x00003E, 0x00000E, 0x000002,
|
||||
0x000000, 0x000006, 0x00001E, 0x00007E, 0x0001FE, 0x0007FE, 0x001FFE,
|
||||
0x003FFE, 0x01FFFC, 0x07FFF8, 0x0FFFFB, 0x0FFFFC, 0x0FFFFD, 0x0FFFFE,
|
||||
0x0FFFFF,
|
||||
};
|
||||
|
||||
static const uint8_t huff_icc_df_bits[] = {
|
||||
14, 14, 12, 10, 7, 5, 3, 1, 2, 4, 6, 8, 9, 11, 13,
|
||||
};
|
||||
|
||||
static const uint16_t huff_icc_df_codes[] = {
|
||||
0x3FFF, 0x3FFE, 0x0FFE, 0x03FE, 0x007E, 0x001E, 0x0006, 0x0000,
|
||||
0x0002, 0x000E, 0x003E, 0x00FE, 0x01FE, 0x07FE, 0x1FFE,
|
||||
};
|
||||
|
||||
static const uint8_t huff_icc_dt_bits[] = {
|
||||
14, 13, 11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12, 14,
|
||||
};
|
||||
|
||||
static const uint16_t huff_icc_dt_codes[] = {
|
||||
0x3FFE, 0x1FFE, 0x07FE, 0x01FE, 0x007E, 0x001E, 0x0006, 0x0000,
|
||||
0x0002, 0x000E, 0x003E, 0x00FE, 0x03FE, 0x0FFE, 0x3FFF,
|
||||
};
|
||||
|
||||
static const uint8_t huff_ipd_df_bits[] = {
|
||||
1, 3, 4, 4, 4, 4, 4, 4,
|
||||
};
|
||||
|
||||
static const uint8_t huff_ipd_df_codes[] = {
|
||||
0x01, 0x00, 0x06, 0x04, 0x02, 0x03, 0x05, 0x07,
|
||||
};
|
||||
|
||||
static const uint8_t huff_ipd_dt_bits[] = {
|
||||
1, 3, 4, 5, 5, 4, 4, 3,
|
||||
};
|
||||
|
||||
static const uint8_t huff_ipd_dt_codes[] = {
|
||||
0x01, 0x02, 0x02, 0x03, 0x02, 0x00, 0x03, 0x03,
|
||||
};
|
||||
|
||||
static const uint8_t huff_opd_df_bits[] = {
|
||||
1, 3, 4, 4, 5, 5, 4, 3,
|
||||
};
|
||||
|
||||
static const uint8_t huff_opd_df_codes[] = {
|
||||
0x01, 0x01, 0x06, 0x04, 0x0F, 0x0E, 0x05, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t huff_opd_dt_bits[] = {
|
||||
1, 3, 4, 5, 5, 4, 4, 3,
|
||||
};
|
||||
|
||||
static const uint8_t huff_opd_dt_codes[] = {
|
||||
0x01, 0x02, 0x01, 0x07, 0x06, 0x00, 0x02, 0x03,
|
||||
};
|
||||
|
||||
static const int8_t huff_offset[] = {
|
||||
30, 30,
|
||||
14, 14,
|
||||
7, 7,
|
||||
0, 0,
|
||||
0, 0,
|
||||
};
|
||||
|
||||
///Table 8.48
|
||||
static const int8_t k_to_i_20[] = {
|
||||
1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15,
|
||||
15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19
|
||||
};
|
||||
///Table 8.49
|
||||
static const int8_t k_to_i_34[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 6, 7, 2, 1, 0, 10, 10, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 9, 14, 11, 12, 13, 14, 15, 16, 13, 16, 17, 18, 19, 20, 21,
|
||||
22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29,
|
||||
30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33,
|
||||
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33
|
||||
};
|
||||
|
||||
static const float g1_Q2[] = {
|
||||
0.0f, 0.01899487526049f, 0.0f, -0.07293139167538f,
|
||||
0.0f, 0.30596630545168f, 0.5f
|
||||
};
|
||||
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
* AAC encoder psychoacoustic model
|
||||
* Copyright (C) 2008 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
* AAC encoder psychoacoustic model
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "aactab.h"
|
||||
#include "psymodel.h"
|
||||
|
||||
/***********************************
|
||||
* TODOs:
|
||||
* thresholds linearization after their modifications for attaining given bitrate
|
||||
* try other bitrate controlling mechanism (maybe use ratecontrol.c?)
|
||||
* control quality for quality-based output
|
||||
**********************************/
|
||||
|
||||
/**
|
||||
* constants for 3GPP AAC psychoacoustic model
|
||||
* @{
|
||||
*/
|
||||
#define PSY_3GPP_SPREAD_LOW 1.5f // spreading factor for ascending threshold spreading (15 dB/Bark)
|
||||
#define PSY_3GPP_SPREAD_HI 3.0f // spreading factor for descending threshold spreading (30 dB/Bark)
|
||||
|
||||
#define PSY_3GPP_RPEMIN 0.01f
|
||||
#define PSY_3GPP_RPELEV 2.0f
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* information for single band used by 3GPP TS26.403-inspired psychoacoustic model
|
||||
*/
|
||||
typedef struct Psy3gppBand{
|
||||
float energy; ///< band energy
|
||||
float ffac; ///< form factor
|
||||
float thr; ///< energy threshold
|
||||
float min_snr; ///< minimal SNR
|
||||
float thr_quiet; ///< threshold in quiet
|
||||
}Psy3gppBand;
|
||||
|
||||
/**
|
||||
* single/pair channel context for psychoacoustic model
|
||||
*/
|
||||
typedef struct Psy3gppChannel{
|
||||
Psy3gppBand band[128]; ///< bands information
|
||||
Psy3gppBand prev_band[128]; ///< bands information from the previous frame
|
||||
|
||||
float win_energy; ///< sliding average of channel energy
|
||||
float iir_state[2]; ///< hi-pass IIR filter state
|
||||
uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence)
|
||||
enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame
|
||||
}Psy3gppChannel;
|
||||
|
||||
/**
|
||||
* psychoacoustic model frame type-dependent coefficients
|
||||
*/
|
||||
typedef struct Psy3gppCoeffs{
|
||||
float ath [64]; ///< absolute threshold of hearing per bands
|
||||
float barks [64]; ///< Bark value for each spectral band in long frame
|
||||
float spread_low[64]; ///< spreading factor for low-to-high threshold spreading in long frame
|
||||
float spread_hi [64]; ///< spreading factor for high-to-low threshold spreading in long frame
|
||||
}Psy3gppCoeffs;
|
||||
|
||||
/**
|
||||
* 3GPP TS26.403-inspired psychoacoustic model specific data
|
||||
*/
|
||||
typedef struct Psy3gppContext{
|
||||
Psy3gppCoeffs psy_coef[2];
|
||||
Psy3gppChannel *ch;
|
||||
}Psy3gppContext;
|
||||
|
||||
/**
|
||||
* Calculate Bark value for given line.
|
||||
*/
|
||||
static av_cold float calc_bark(float f)
|
||||
{
|
||||
return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f));
|
||||
}
|
||||
|
||||
#define ATH_ADD 4
|
||||
/**
|
||||
* Calculate ATH value for given frequency.
|
||||
* Borrowed from Lame.
|
||||
*/
|
||||
static av_cold float ath(float f, float add)
|
||||
{
|
||||
f /= 1000.0f;
|
||||
return 3.64 * pow(f, -0.8)
|
||||
- 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4))
|
||||
+ 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7))
|
||||
+ (0.6 + 0.04 * add) * 0.001 * f * f * f * f;
|
||||
}
|
||||
|
||||
static av_cold int psy_3gpp_init(FFPsyContext *ctx) {
|
||||
Psy3gppContext *pctx;
|
||||
float barks[1024];
|
||||
int i, j, g, start;
|
||||
float prev, minscale, minath;
|
||||
|
||||
ctx->model_priv_data = av_mallocz(sizeof(Psy3gppContext));
|
||||
pctx = (Psy3gppContext*) ctx->model_priv_data;
|
||||
|
||||
for (i = 0; i < 1024; i++)
|
||||
barks[i] = calc_bark(i * ctx->avctx->sample_rate / 2048.0);
|
||||
minath = ath(3410, ATH_ADD);
|
||||
for (j = 0; j < 2; j++) {
|
||||
Psy3gppCoeffs *coeffs = &pctx->psy_coef[j];
|
||||
i = 0;
|
||||
prev = 0.0;
|
||||
for (g = 0; g < ctx->num_bands[j]; g++) {
|
||||
i += ctx->bands[j][g];
|
||||
coeffs->barks[g] = (barks[i - 1] + prev) / 2.0;
|
||||
prev = barks[i - 1];
|
||||
}
|
||||
for (g = 0; g < ctx->num_bands[j] - 1; g++) {
|
||||
coeffs->spread_low[g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_LOW);
|
||||
coeffs->spread_hi [g] = pow(10.0, -(coeffs->barks[g+1] - coeffs->barks[g]) * PSY_3GPP_SPREAD_HI);
|
||||
}
|
||||
start = 0;
|
||||
for (g = 0; g < ctx->num_bands[j]; g++) {
|
||||
minscale = ath(ctx->avctx->sample_rate * start / 1024.0, ATH_ADD);
|
||||
for (i = 1; i < ctx->bands[j][g]; i++)
|
||||
minscale = FFMIN(minscale, ath(ctx->avctx->sample_rate * (start + i) / 1024.0 / 2.0, ATH_ADD));
|
||||
coeffs->ath[g] = minscale - minath;
|
||||
start += ctx->bands[j][g];
|
||||
}
|
||||
}
|
||||
|
||||
pctx->ch = av_mallocz(sizeof(Psy3gppChannel) * ctx->avctx->channels);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* IIR filter used in block switching decision
|
||||
*/
|
||||
static float iir_filter(int in, float state[2])
|
||||
{
|
||||
float ret;
|
||||
|
||||
ret = 0.7548f * (in - state[0]) + 0.5095f * state[1];
|
||||
state[0] = in;
|
||||
state[1] = ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* window grouping information stored as bits (0 - new group, 1 - group continues)
|
||||
*/
|
||||
static const uint8_t window_grouping[9] = {
|
||||
0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell encoder which window types to use.
|
||||
* @see 3GPP TS26.403 5.4.1 "Blockswitching"
|
||||
*/
|
||||
static FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx,
|
||||
const int16_t *audio, const int16_t *la,
|
||||
int channel, int prev_type)
|
||||
{
|
||||
int i, j;
|
||||
int br = ctx->avctx->bit_rate / ctx->avctx->channels;
|
||||
int attack_ratio = br <= 16000 ? 18 : 10;
|
||||
Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data;
|
||||
Psy3gppChannel *pch = &pctx->ch[channel];
|
||||
uint8_t grouping = 0;
|
||||
FFPsyWindowInfo wi;
|
||||
|
||||
memset(&wi, 0, sizeof(wi));
|
||||
if (la) {
|
||||
float s[8], v;
|
||||
int switch_to_eight = 0;
|
||||
float sum = 0.0, sum2 = 0.0;
|
||||
int attack_n = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (j = 0; j < 128; j++) {
|
||||
v = iir_filter(audio[(i*128+j)*ctx->avctx->channels], pch->iir_state);
|
||||
sum += v*v;
|
||||
}
|
||||
s[i] = sum;
|
||||
sum2 += sum;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s[i] > pch->win_energy * attack_ratio) {
|
||||
attack_n = i + 1;
|
||||
switch_to_eight = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pch->win_energy = pch->win_energy*7/8 + sum2/64;
|
||||
|
||||
wi.window_type[1] = prev_type;
|
||||
switch (prev_type) {
|
||||
case ONLY_LONG_SEQUENCE:
|
||||
wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE;
|
||||
break;
|
||||
case LONG_START_SEQUENCE:
|
||||
wi.window_type[0] = EIGHT_SHORT_SEQUENCE;
|
||||
grouping = pch->next_grouping;
|
||||
break;
|
||||
case LONG_STOP_SEQUENCE:
|
||||
wi.window_type[0] = ONLY_LONG_SEQUENCE;
|
||||
break;
|
||||
case EIGHT_SHORT_SEQUENCE:
|
||||
wi.window_type[0] = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE;
|
||||
grouping = switch_to_eight ? pch->next_grouping : 0;
|
||||
break;
|
||||
}
|
||||
pch->next_grouping = window_grouping[attack_n];
|
||||
} else {
|
||||
for (i = 0; i < 3; i++)
|
||||
wi.window_type[i] = prev_type;
|
||||
grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0;
|
||||
}
|
||||
|
||||
wi.window_shape = 1;
|
||||
if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
wi.num_windows = 1;
|
||||
wi.grouping[0] = 1;
|
||||
} else {
|
||||
int lastgrp = 0;
|
||||
wi.num_windows = 8;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (!((grouping >> i) & 1))
|
||||
lastgrp = i;
|
||||
wi.grouping[lastgrp]++;
|
||||
}
|
||||
}
|
||||
|
||||
return wi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate band thresholds as suggested in 3GPP TS26.403
|
||||
*/
|
||||
static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
|
||||
const float *coefs, FFPsyWindowInfo *wi)
|
||||
{
|
||||
Psy3gppContext *pctx = (Psy3gppContext*) ctx->model_priv_data;
|
||||
Psy3gppChannel *pch = &pctx->ch[channel];
|
||||
int start = 0;
|
||||
int i, w, g;
|
||||
const int num_bands = ctx->num_bands[wi->num_windows == 8];
|
||||
const uint8_t* band_sizes = ctx->bands[wi->num_windows == 8];
|
||||
Psy3gppCoeffs *coeffs = &pctx->psy_coef[wi->num_windows == 8];
|
||||
|
||||
//calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation"
|
||||
for (w = 0; w < wi->num_windows*16; w += 16) {
|
||||
for (g = 0; g < num_bands; g++) {
|
||||
Psy3gppBand *band = &pch->band[w+g];
|
||||
band->energy = 0.0f;
|
||||
for (i = 0; i < band_sizes[g]; i++)
|
||||
band->energy += coefs[start+i] * coefs[start+i];
|
||||
band->energy *= 1.0f / (512*512);
|
||||
band->thr = band->energy * 0.001258925f;
|
||||
start += band_sizes[g];
|
||||
|
||||
ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].energy = band->energy;
|
||||
}
|
||||
}
|
||||
//modify thresholds - spread, threshold in quiet - 5.4.3 "Spreaded Energy Calculation"
|
||||
for (w = 0; w < wi->num_windows*16; w += 16) {
|
||||
Psy3gppBand *band = &pch->band[w];
|
||||
for (g = 1; g < num_bands; g++)
|
||||
band[g].thr = FFMAX(band[g].thr, band[g-1].thr * coeffs->spread_low[g-1]);
|
||||
for (g = num_bands - 2; g >= 0; g--)
|
||||
band[g].thr = FFMAX(band[g].thr, band[g+1].thr * coeffs->spread_hi [g]);
|
||||
for (g = 0; g < num_bands; g++) {
|
||||
band[g].thr_quiet = FFMAX(band[g].thr, coeffs->ath[g]);
|
||||
if (wi->num_windows != 8 && wi->window_type[1] != EIGHT_SHORT_SEQUENCE)
|
||||
band[g].thr_quiet = FFMAX(PSY_3GPP_RPEMIN*band[g].thr_quiet,
|
||||
FFMIN(band[g].thr_quiet,
|
||||
PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet));
|
||||
band[g].thr = FFMAX(band[g].thr, band[g].thr_quiet * 0.25);
|
||||
|
||||
ctx->psy_bands[channel*PSY_MAX_BANDS+w+g].threshold = band[g].thr;
|
||||
}
|
||||
}
|
||||
memcpy(pch->prev_band, pch->band, sizeof(pch->band));
|
||||
}
|
||||
|
||||
static av_cold void psy_3gpp_end(FFPsyContext *apc)
|
||||
{
|
||||
Psy3gppContext *pctx = (Psy3gppContext*) apc->model_priv_data;
|
||||
av_freep(&pctx->ch);
|
||||
av_freep(&apc->model_priv_data);
|
||||
}
|
||||
|
||||
|
||||
const FFPsyModel ff_aac_psy_model =
|
||||
{
|
||||
.name = "3GPP TS 26.403-inspired model",
|
||||
.init = psy_3gpp_init,
|
||||
.window = psy_3gpp_window,
|
||||
.analyze = psy_3gpp_analyze,
|
||||
.end = psy_3gpp_end,
|
||||
};
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* AAC encoder psychoacoustic model
|
||||
* Copyright (C) 2008 Konstantin Shishkov
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACPSY_H
|
||||
#define AVCODEC_AACPSY_H
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "aac.h"
|
||||
//#include "lowpass.h"
|
||||
|
||||
enum AACPsyModelType{
|
||||
AAC_PSY_TEST, ///< a sample model to exercise encoder
|
||||
AAC_PSY_3GPP, ///< model following recommendations from 3GPP TS 26.403
|
||||
|
||||
AAC_NB_PSY_MODELS ///< total number of psychoacoustic models, since it's not a part of the ABI new models can be added freely
|
||||
};
|
||||
|
||||
/**
|
||||
* context used by psychoacoustic model
|
||||
*/
|
||||
typedef struct AACPsyContext {
|
||||
AVCodecContext *avctx; ///< encoder context
|
||||
}AACPsyContext;
|
||||
|
||||
/**
|
||||
* Cleanup model context at the end.
|
||||
*
|
||||
* @param ctx model context
|
||||
*/
|
||||
void ff_aac_psy_end(AACPsyContext *ctx);
|
||||
|
||||
#endif /* AVCODEC_AACPSY_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* AAC Spectral Band Replication function declarations
|
||||
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
|
||||
* Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* AAC Spectral Band Replication function declarations
|
||||
* @author Robert Swain ( rob opendot cl )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACSBR_H
|
||||
#define AVCODEC_AACSBR_H
|
||||
|
||||
#include "get_bits.h"
|
||||
#include "aac.h"
|
||||
#include "sbr.h"
|
||||
|
||||
/** Initialize SBR. */
|
||||
av_cold void ff_aac_sbr_init(void);
|
||||
/** Initialize one SBR context. */
|
||||
av_cold void ff_aac_sbr_ctx_init(SpectralBandReplication *sbr);
|
||||
/** Close one SBR context. */
|
||||
av_cold void ff_aac_sbr_ctx_close(SpectralBandReplication *sbr);
|
||||
/** Decode one SBR element. */
|
||||
int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
|
||||
GetBitContext *gb, int crc, int cnt, int id_aac);
|
||||
/** Apply one SBR element to one AAC element. */
|
||||
void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
|
||||
float* L, float *R);
|
||||
|
||||
#endif /* AVCODEC_AACSBR_H */
|
||||
@@ -1,614 +0,0 @@
|
||||
/*
|
||||
* AAC Spectral Band Replication decoding data
|
||||
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
|
||||
*
|
||||
* 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
|
||||
* AAC Spectral Band Replication decoding data
|
||||
* @author Robert Swain ( rob opendot cl )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACSBRDATA_H
|
||||
#define AVCODEC_AACSBRDATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
///< Huffman tables for SBR
|
||||
|
||||
static const uint8_t t_huffman_env_1_5dB_bits[121] = {
|
||||
18, 18, 18, 18, 18, 18, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 17, 18, 16, 17, 18, 17,
|
||||
16, 16, 16, 16, 15, 14, 14, 13,
|
||||
13, 12, 11, 10, 9, 8, 7, 6,
|
||||
5, 4, 3, 2, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 10, 12, 13, 14,
|
||||
14, 15, 16, 17, 16, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19,
|
||||
};
|
||||
|
||||
static const uint32_t t_huffman_env_1_5dB_codes[121] = {
|
||||
0x3ffd6, 0x3ffd7, 0x3ffd8, 0x3ffd9, 0x3ffda, 0x3ffdb, 0x7ffb8, 0x7ffb9,
|
||||
0x7ffba, 0x7ffbb, 0x7ffbc, 0x7ffbd, 0x7ffbe, 0x7ffbf, 0x7ffc0, 0x7ffc1,
|
||||
0x7ffc2, 0x7ffc3, 0x7ffc4, 0x7ffc5, 0x7ffc6, 0x7ffc7, 0x7ffc8, 0x7ffc9,
|
||||
0x7ffca, 0x7ffcb, 0x7ffcc, 0x7ffcd, 0x7ffce, 0x7ffcf, 0x7ffd0, 0x7ffd1,
|
||||
0x7ffd2, 0x7ffd3, 0x1ffe6, 0x3ffd4, 0x0fff0, 0x1ffe9, 0x3ffd5, 0x1ffe7,
|
||||
0x0fff1, 0x0ffec, 0x0ffed, 0x0ffee, 0x07ff4, 0x03ff9, 0x03ff7, 0x01ffa,
|
||||
0x01ff9, 0x00ffb, 0x007fc, 0x003fc, 0x001fd, 0x000fd, 0x0007d, 0x0003d,
|
||||
0x0001d, 0x0000d, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000c, 0x0001c,
|
||||
0x0003c, 0x0007c, 0x000fc, 0x001fc, 0x003fd, 0x00ffa, 0x01ff8, 0x03ff6,
|
||||
0x03ff8, 0x07ff5, 0x0ffef, 0x1ffe8, 0x0fff2, 0x7ffd4, 0x7ffd5, 0x7ffd6,
|
||||
0x7ffd7, 0x7ffd8, 0x7ffd9, 0x7ffda, 0x7ffdb, 0x7ffdc, 0x7ffdd, 0x7ffde,
|
||||
0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3, 0x7ffe4, 0x7ffe5, 0x7ffe6,
|
||||
0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb, 0x7ffec, 0x7ffed, 0x7ffee,
|
||||
0x7ffef, 0x7fff0, 0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6,
|
||||
0x7fff7, 0x7fff8, 0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe,
|
||||
0x7ffff,
|
||||
};
|
||||
|
||||
static const uint8_t f_huffman_env_1_5dB_bits[121] = {
|
||||
19, 19, 20, 20, 20, 20, 20, 20,
|
||||
20, 19, 20, 20, 20, 20, 19, 20,
|
||||
19, 19, 20, 18, 20, 20, 20, 19,
|
||||
20, 20, 20, 19, 20, 19, 18, 19,
|
||||
18, 18, 17, 18, 17, 17, 17, 16,
|
||||
16, 16, 15, 15, 14, 13, 13, 12,
|
||||
12, 11, 10, 9, 9, 8, 7, 6,
|
||||
5, 4, 3, 2, 2, 3, 4, 5,
|
||||
6, 8, 8, 9, 10, 11, 11, 11,
|
||||
12, 12, 13, 13, 14, 14, 16, 16,
|
||||
17, 17, 18, 18, 18, 18, 18, 18,
|
||||
18, 20, 19, 20, 20, 20, 20, 20,
|
||||
20, 19, 20, 20, 20, 20, 19, 20,
|
||||
18, 20, 20, 19, 19, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20,
|
||||
};
|
||||
|
||||
static const uint32_t f_huffman_env_1_5dB_codes[121] = {
|
||||
0x7ffe7, 0x7ffe8, 0xfffd2, 0xfffd3, 0xfffd4, 0xfffd5, 0xfffd6, 0xfffd7,
|
||||
0xfffd8, 0x7ffda, 0xfffd9, 0xfffda, 0xfffdb, 0xfffdc, 0x7ffdb, 0xfffdd,
|
||||
0x7ffdc, 0x7ffdd, 0xfffde, 0x3ffe4, 0xfffdf, 0xfffe0, 0xfffe1, 0x7ffde,
|
||||
0xfffe2, 0xfffe3, 0xfffe4, 0x7ffdf, 0xfffe5, 0x7ffe0, 0x3ffe8, 0x7ffe1,
|
||||
0x3ffe0, 0x3ffe9, 0x1ffef, 0x3ffe5, 0x1ffec, 0x1ffed, 0x1ffee, 0x0fff4,
|
||||
0x0fff3, 0x0fff0, 0x07ff7, 0x07ff6, 0x03ffa, 0x01ffa, 0x01ff9, 0x00ffa,
|
||||
0x00ff8, 0x007f9, 0x003fb, 0x001fc, 0x001fa, 0x000fb, 0x0007c, 0x0003c,
|
||||
0x0001c, 0x0000c, 0x00005, 0x00001, 0x00000, 0x00004, 0x0000d, 0x0001d,
|
||||
0x0003d, 0x000fa, 0x000fc, 0x001fb, 0x003fa, 0x007f8, 0x007fa, 0x007fb,
|
||||
0x00ff9, 0x00ffb, 0x01ff8, 0x01ffb, 0x03ff8, 0x03ff9, 0x0fff1, 0x0fff2,
|
||||
0x1ffea, 0x1ffeb, 0x3ffe1, 0x3ffe2, 0x3ffea, 0x3ffe3, 0x3ffe6, 0x3ffe7,
|
||||
0x3ffeb, 0xfffe6, 0x7ffe2, 0xfffe7, 0xfffe8, 0xfffe9, 0xfffea, 0xfffeb,
|
||||
0xfffec, 0x7ffe3, 0xfffed, 0xfffee, 0xfffef, 0xffff0, 0x7ffe4, 0xffff1,
|
||||
0x3ffec, 0xffff2, 0xffff3, 0x7ffe5, 0x7ffe6, 0xffff4, 0xffff5, 0xffff6,
|
||||
0xffff7, 0xffff8, 0xffff9, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe,
|
||||
0xfffff,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_env_bal_1_5dB_bits[49] = {
|
||||
16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 12, 11, 9, 7, 5, 3,
|
||||
1, 2, 4, 6, 8, 11, 12, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17,
|
||||
};
|
||||
|
||||
static const uint32_t t_huffman_env_bal_1_5dB_codes[49] = {
|
||||
0x0ffe4, 0x0ffe5, 0x0ffe6, 0x0ffe7, 0x0ffe8, 0x0ffe9, 0x0ffea, 0x0ffeb,
|
||||
0x0ffec, 0x0ffed, 0x0ffee, 0x0ffef, 0x0fff0, 0x0fff1, 0x0fff2, 0x0fff3,
|
||||
0x0fff4, 0x0ffe2, 0x00ffc, 0x007fc, 0x001fe, 0x0007e, 0x0001e, 0x00006,
|
||||
0x00000, 0x00002, 0x0000e, 0x0003e, 0x000fe, 0x007fd, 0x00ffd, 0x07ff0,
|
||||
0x0ffe3, 0x0fff5, 0x0fff6, 0x0fff7, 0x0fff8, 0x0fff9, 0x0fffa, 0x1fff6,
|
||||
0x1fff7, 0x1fff8, 0x1fff9, 0x1fffa, 0x1fffb, 0x1fffc, 0x1fffd, 0x1fffe,
|
||||
0x1ffff,
|
||||
};
|
||||
|
||||
static const uint8_t f_huffman_env_bal_1_5dB_bits[49] = {
|
||||
18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 16,
|
||||
17, 14, 11, 11, 8, 7, 4, 2,
|
||||
1, 3, 5, 6, 9, 11, 12, 15,
|
||||
16, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 19,
|
||||
19,
|
||||
};
|
||||
|
||||
static const uint32_t f_huffman_env_bal_1_5dB_codes[49] = {
|
||||
0x3ffe2, 0x3ffe3, 0x3ffe4, 0x3ffe5, 0x3ffe6, 0x3ffe7, 0x3ffe8, 0x3ffe9,
|
||||
0x3ffea, 0x3ffeb, 0x3ffec, 0x3ffed, 0x3ffee, 0x3ffef, 0x3fff0, 0x0fff7,
|
||||
0x1fff0, 0x03ffc, 0x007fe, 0x007fc, 0x000fe, 0x0007e, 0x0000e, 0x00002,
|
||||
0x00000, 0x00006, 0x0001e, 0x0003e, 0x001fe, 0x007fd, 0x00ffe, 0x07ffa,
|
||||
0x0fff6, 0x3fff1, 0x3fff2, 0x3fff3, 0x3fff4, 0x3fff5, 0x3fff6, 0x3fff7,
|
||||
0x3fff8, 0x3fff9, 0x3fffa, 0x3fffb, 0x3fffc, 0x3fffd, 0x3fffe, 0x7fffe,
|
||||
0x7ffff,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_env_3_0dB_bits[63] = {
|
||||
18, 18, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 17, 16, 16, 16, 14, 14, 14,
|
||||
13, 12, 11, 8, 6, 4, 2, 1,
|
||||
3, 5, 7, 9, 11, 13, 14, 14,
|
||||
15, 16, 17, 18, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19,
|
||||
};
|
||||
|
||||
static const uint32_t t_huffman_env_3_0dB_codes[63] = {
|
||||
0x3ffed, 0x3ffee, 0x7ffde, 0x7ffdf, 0x7ffe0, 0x7ffe1, 0x7ffe2, 0x7ffe3,
|
||||
0x7ffe4, 0x7ffe5, 0x7ffe6, 0x7ffe7, 0x7ffe8, 0x7ffe9, 0x7ffea, 0x7ffeb,
|
||||
0x7ffec, 0x1fff4, 0x0fff7, 0x0fff9, 0x0fff8, 0x03ffb, 0x03ffa, 0x03ff8,
|
||||
0x01ffa, 0x00ffc, 0x007fc, 0x000fe, 0x0003e, 0x0000e, 0x00002, 0x00000,
|
||||
0x00006, 0x0001e, 0x0007e, 0x001fe, 0x007fd, 0x01ffb, 0x03ff9, 0x03ffc,
|
||||
0x07ffa, 0x0fff6, 0x1fff5, 0x3ffec, 0x7ffed, 0x7ffee, 0x7ffef, 0x7fff0,
|
||||
0x7fff1, 0x7fff2, 0x7fff3, 0x7fff4, 0x7fff5, 0x7fff6, 0x7fff7, 0x7fff8,
|
||||
0x7fff9, 0x7fffa, 0x7fffb, 0x7fffc, 0x7fffd, 0x7fffe, 0x7ffff,
|
||||
};
|
||||
|
||||
static const uint8_t f_huffman_env_3_0dB_bits[63] = {
|
||||
20, 20, 20, 20, 20, 20, 20, 18,
|
||||
19, 19, 19, 19, 18, 18, 20, 19,
|
||||
17, 18, 17, 16, 16, 15, 14, 12,
|
||||
11, 10, 9, 8, 6, 4, 2, 1,
|
||||
3, 5, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 15, 16, 16, 17, 17, 18,
|
||||
18, 18, 20, 19, 19, 19, 20, 19,
|
||||
19, 20, 20, 20, 20, 20, 20,
|
||||
};
|
||||
|
||||
static const uint32_t f_huffman_env_3_0dB_codes[63] = {
|
||||
0xffff0, 0xffff1, 0xffff2, 0xffff3, 0xffff4, 0xffff5, 0xffff6, 0x3fff3,
|
||||
0x7fff5, 0x7ffee, 0x7ffef, 0x7fff6, 0x3fff4, 0x3fff2, 0xffff7, 0x7fff0,
|
||||
0x1fff5, 0x3fff0, 0x1fff4, 0x0fff7, 0x0fff6, 0x07ff8, 0x03ffb, 0x00ffd,
|
||||
0x007fd, 0x003fd, 0x001fd, 0x000fd, 0x0003e, 0x0000e, 0x00002, 0x00000,
|
||||
0x00006, 0x0001e, 0x000fc, 0x001fc, 0x003fc, 0x007fc, 0x00ffc, 0x01ffc,
|
||||
0x03ffa, 0x07ff9, 0x07ffa, 0x0fff8, 0x0fff9, 0x1fff6, 0x1fff7, 0x3fff5,
|
||||
0x3fff6, 0x3fff1, 0xffff8, 0x7fff1, 0x7fff2, 0x7fff3, 0xffff9, 0x7fff7,
|
||||
0x7fff4, 0xffffa, 0xffffb, 0xffffc, 0xffffd, 0xffffe, 0xfffff,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_env_bal_3_0dB_bits[25] = {
|
||||
13, 13, 13, 13, 13, 13, 13, 12,
|
||||
8, 7, 4, 3, 1, 2, 5, 6,
|
||||
9, 13, 13, 13, 13, 13, 13, 14,
|
||||
14,
|
||||
};
|
||||
|
||||
static const uint16_t t_huffman_env_bal_3_0dB_codes[25] = {
|
||||
0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x0ff8,
|
||||
0x00fe, 0x007e, 0x000e, 0x0006, 0x0000, 0x0002, 0x001e, 0x003e,
|
||||
0x01fe, 0x1ff9, 0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe,
|
||||
0x3fff,
|
||||
};
|
||||
|
||||
static const uint8_t f_huffman_env_bal_3_0dB_bits[25] = {
|
||||
13, 13, 13, 13, 13, 14, 14, 11,
|
||||
8, 7, 4, 2, 1, 3, 5, 6,
|
||||
9, 12, 13, 14, 14, 14, 14, 14,
|
||||
14,
|
||||
};
|
||||
|
||||
static const uint16_t f_huffman_env_bal_3_0dB_codes[25] = {
|
||||
0x1ff7, 0x1ff8, 0x1ff9, 0x1ffa, 0x1ffb, 0x3ff8, 0x3ff9, 0x07fc,
|
||||
0x00fe, 0x007e, 0x000e, 0x0002, 0x0000, 0x0006, 0x001e, 0x003e,
|
||||
0x01fe, 0x0ffa, 0x1ff6, 0x3ffa, 0x3ffb, 0x3ffc, 0x3ffd, 0x3ffe,
|
||||
0x3fff,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_noise_3_0dB_bits[63] = {
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 11, 8, 6, 4, 3, 1,
|
||||
2, 5, 8, 10, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 14, 14,
|
||||
};
|
||||
|
||||
static const uint16_t t_huffman_noise_3_0dB_codes[63] = {
|
||||
0x1fce, 0x1fcf, 0x1fd0, 0x1fd1, 0x1fd2, 0x1fd3, 0x1fd4, 0x1fd5,
|
||||
0x1fd6, 0x1fd7, 0x1fd8, 0x1fd9, 0x1fda, 0x1fdb, 0x1fdc, 0x1fdd,
|
||||
0x1fde, 0x1fdf, 0x1fe0, 0x1fe1, 0x1fe2, 0x1fe3, 0x1fe4, 0x1fe5,
|
||||
0x1fe6, 0x1fe7, 0x07f2, 0x00fd, 0x003e, 0x000e, 0x0006, 0x0000,
|
||||
0x0002, 0x001e, 0x00fc, 0x03f8, 0x1fcc, 0x1fe8, 0x1fe9, 0x1fea,
|
||||
0x1feb, 0x1fec, 0x1fcd, 0x1fed, 0x1fee, 0x1fef, 0x1ff0, 0x1ff1,
|
||||
0x1ff2, 0x1ff3, 0x1ff4, 0x1ff5, 0x1ff6, 0x1ff7, 0x1ff8, 0x1ff9,
|
||||
0x1ffa, 0x1ffb, 0x1ffc, 0x1ffd, 0x1ffe, 0x3ffe, 0x3fff,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_noise_bal_3_0dB_bits[25] = {
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 5, 2, 1, 3, 6, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
8,
|
||||
};
|
||||
|
||||
static const uint8_t t_huffman_noise_bal_3_0dB_codes[25] = {
|
||||
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
|
||||
0xf4, 0xf5, 0x1c, 0x02, 0x00, 0x06, 0x3a, 0xf6,
|
||||
0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
|
||||
0xff,
|
||||
};
|
||||
|
||||
static const int8_t sbr_offset[6][16] = {
|
||||
{-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}, // fs_sbr = 16000 Hz
|
||||
{-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}, // fs_sbr = 22050 Hz
|
||||
{-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 24000 Hz
|
||||
{-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}, // fs_sbr = 32000 Hz
|
||||
{-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}, // 44100 Hz <= fs_sbr <= 64000 Hz
|
||||
{-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}, // 64000 Hz < fs_sbr
|
||||
};
|
||||
|
||||
///< window coefficients for analysis/synthesis QMF banks
|
||||
static DECLARE_ALIGNED(16, float, sbr_qmf_window_ds)[320];
|
||||
static DECLARE_ALIGNED(16, float, sbr_qmf_window_us)[640] = {
|
||||
0.0000000000, -0.0005525286, -0.0005617692, -0.0004947518,
|
||||
-0.0004875227, -0.0004893791, -0.0005040714, -0.0005226564,
|
||||
-0.0005466565, -0.0005677802, -0.0005870930, -0.0006132747,
|
||||
-0.0006312493, -0.0006540333, -0.0006777690, -0.0006941614,
|
||||
-0.0007157736, -0.0007255043, -0.0007440941, -0.0007490598,
|
||||
-0.0007681371, -0.0007724848, -0.0007834332, -0.0007779869,
|
||||
-0.0007803664, -0.0007801449, -0.0007757977, -0.0007630793,
|
||||
-0.0007530001, -0.0007319357, -0.0007215391, -0.0006917937,
|
||||
-0.0006650415, -0.0006341594, -0.0005946118, -0.0005564576,
|
||||
-0.0005145572, -0.0004606325, -0.0004095121, -0.0003501175,
|
||||
-0.0002896981, -0.0002098337, -0.0001446380, -0.0000617334,
|
||||
0.0000134949, 0.0001094383, 0.0002043017, 0.0002949531,
|
||||
0.0004026540, 0.0005107388, 0.0006239376, 0.0007458025,
|
||||
0.0008608443, 0.0009885988, 0.0011250155, 0.0012577884,
|
||||
0.0013902494, 0.0015443219, 0.0016868083, 0.0018348265,
|
||||
0.0019841140, 0.0021461583, 0.0023017254, 0.0024625616,
|
||||
0.0026201758, 0.0027870464, 0.0029469447, 0.0031125420,
|
||||
0.0032739613, 0.0034418874, 0.0036008268, 0.0037603922,
|
||||
0.0039207432, 0.0040819753, 0.0042264269, 0.0043730719,
|
||||
0.0045209852, 0.0046606460, 0.0047932560, 0.0049137603,
|
||||
0.0050393022, 0.0051407353, 0.0052461166, 0.0053471681,
|
||||
0.0054196775, 0.0054876040, 0.0055475714, 0.0055938023,
|
||||
0.0056220643, 0.0056455196, 0.0056389199, 0.0056266114,
|
||||
0.0055917128, 0.0055404363, 0.0054753783, 0.0053838975,
|
||||
0.0052715758, 0.0051382275, 0.0049839687, 0.0048109469,
|
||||
0.0046039530, 0.0043801861, 0.0041251642, 0.0038456408,
|
||||
0.0035401246, 0.0032091885, 0.0028446757, 0.0024508540,
|
||||
0.0020274176, 0.0015784682, 0.0010902329, 0.0005832264,
|
||||
0.0000276045, -0.0005464280, -0.0011568135, -0.0018039472,
|
||||
-0.0024826723, -0.0031933778, -0.0039401124, -0.0047222596,
|
||||
-0.0055337211, -0.0063792293, -0.0072615816, -0.0081798233,
|
||||
-0.0091325329, -0.0101150215, -0.0111315548, -0.0121849995,
|
||||
0.0132718220, 0.0143904666, 0.0155405553, 0.0167324712,
|
||||
0.0179433381, 0.0191872431, 0.0204531793, 0.0217467550,
|
||||
0.0230680169, 0.0244160992, 0.0257875847, 0.0271859429,
|
||||
0.0286072173, 0.0300502657, 0.0315017608, 0.0329754081,
|
||||
0.0344620948, 0.0359697560, 0.0374812850, 0.0390053679,
|
||||
0.0405349170, 0.0420649094, 0.0436097542, 0.0451488405,
|
||||
0.0466843027, 0.0482165720, 0.0497385755, 0.0512556155,
|
||||
0.0527630746, 0.0542452768, 0.0557173648, 0.0571616450,
|
||||
0.0585915683, 0.0599837480, 0.0613455171, 0.0626857808,
|
||||
0.0639715898, 0.0652247106, 0.0664367512, 0.0676075985,
|
||||
0.0687043828, 0.0697630244, 0.0707628710, 0.0717002673,
|
||||
0.0725682583, 0.0733620255, 0.0741003642, 0.0747452558,
|
||||
0.0753137336, 0.0758008358, 0.0761992479, 0.0764992170,
|
||||
0.0767093490, 0.0768173975, 0.0768230011, 0.0767204924,
|
||||
0.0765050718, 0.0761748321, 0.0757305756, 0.0751576255,
|
||||
0.0744664394, 0.0736406005, 0.0726774642, 0.0715826364,
|
||||
0.0703533073, 0.0689664013, 0.0674525021, 0.0657690668,
|
||||
0.0639444805, 0.0619602779, 0.0598166570, 0.0575152691,
|
||||
0.0550460034, 0.0524093821, 0.0495978676, 0.0466303305,
|
||||
0.0434768782, 0.0401458278, 0.0366418116, 0.0329583930,
|
||||
0.0290824006, 0.0250307561, 0.0207997072, 0.0163701258,
|
||||
0.0117623832, 0.0069636862, 0.0019765601, -0.0032086896,
|
||||
-0.0085711749, -0.0141288827, -0.0198834129, -0.0258227288,
|
||||
-0.0319531274, -0.0382776572, -0.0447806821, -0.0514804176,
|
||||
-0.0583705326, -0.0654409853, -0.0726943300, -0.0801372934,
|
||||
-0.0877547536, -0.0955533352, -0.1035329531, -0.1116826931,
|
||||
-0.1200077984, -0.1285002850, -0.1371551761, -0.1459766491,
|
||||
-0.1549607071, -0.1640958855, -0.1733808172, -0.1828172548,
|
||||
-0.1923966745, -0.2021250176, -0.2119735853, -0.2219652696,
|
||||
-0.2320690870, -0.2423016884, -0.2526480309, -0.2631053299,
|
||||
-0.2736634040, -0.2843214189, -0.2950716717, -0.3059098575,
|
||||
-0.3168278913, -0.3278113727, -0.3388722693, -0.3499914122,
|
||||
0.3611589903, 0.3723795546, 0.3836350013, 0.3949211761,
|
||||
0.4062317676, 0.4175696896, 0.4289119920, 0.4402553754,
|
||||
0.4515996535, 0.4629308085, 0.4742453214, 0.4855253091,
|
||||
0.4967708254, 0.5079817500, 0.5191234970, 0.5302240895,
|
||||
0.5412553448, 0.5522051258, 0.5630789140, 0.5738524131,
|
||||
0.5845403235, 0.5951123086, 0.6055783538, 0.6159109932,
|
||||
0.6261242695, 0.6361980107, 0.6461269695, 0.6559016302,
|
||||
0.6655139880, 0.6749663190, 0.6842353293, 0.6933282376,
|
||||
0.7022388719, 0.7109410426, 0.7194462634, 0.7277448900,
|
||||
0.7358211758, 0.7436827863, 0.7513137456, 0.7587080760,
|
||||
0.7658674865, 0.7727780881, 0.7794287519, 0.7858353120,
|
||||
0.7919735841, 0.7978466413, 0.8034485751, 0.8087695004,
|
||||
0.8138191270, 0.8185776004, 0.8230419890, 0.8272275347,
|
||||
0.8311038457, 0.8346937361, 0.8379717337, 0.8409541392,
|
||||
0.8436238281, 0.8459818469, 0.8480315777, 0.8497805198,
|
||||
0.8511971524, 0.8523047035, 0.8531020949, 0.8535720573,
|
||||
0.8537385600,
|
||||
};
|
||||
|
||||
static const float sbr_noise_table[512][2] = {
|
||||
{-0.99948153278296, -0.59483417516607}, { 0.97113454393991, -0.67528515225647},
|
||||
{ 0.14130051758487, -0.95090983575689}, {-0.47005496701697, -0.37340549728647},
|
||||
{ 0.80705063769351, 0.29653668284408}, {-0.38981478896926, 0.89572605717087},
|
||||
{-0.01053049862020, -0.66959058036166}, {-0.91266367957293, -0.11522938140034},
|
||||
{ 0.54840422910309, 0.75221367176302}, { 0.40009252867955, -0.98929400334421},
|
||||
{-0.99867974711855, -0.88147068645358}, {-0.95531076805040, 0.90908757154593},
|
||||
{-0.45725933317144, -0.56716323646760}, {-0.72929675029275, -0.98008272727324},
|
||||
{ 0.75622801399036, 0.20950329995549}, { 0.07069442601050, -0.78247898470706},
|
||||
{ 0.74496252926055, -0.91169004445807}, {-0.96440182703856, -0.94739918296622},
|
||||
{ 0.30424629369539, -0.49438267012479}, { 0.66565033746925, 0.64652935542491},
|
||||
{ 0.91697008020594, 0.17514097332009}, {-0.70774918760427, 0.52548653416543},
|
||||
{-0.70051415345560, -0.45340028808763}, {-0.99496513054797, -0.90071908066973},
|
||||
{ 0.98164490790123, -0.77463155528697}, {-0.54671580548181, -0.02570928536004},
|
||||
{-0.01689629065389, 0.00287506445732}, {-0.86110349531986, 0.42548583726477},
|
||||
{-0.98892980586032, -0.87881132267556}, { 0.51756627678691, 0.66926784710139},
|
||||
{-0.99635026409640, -0.58107730574765}, {-0.99969370862163, 0.98369989360250},
|
||||
{ 0.55266258627194, 0.59449057465591}, { 0.34581177741673, 0.94879421061866},
|
||||
{ 0.62664209577999, -0.74402970906471}, {-0.77149701404973, -0.33883658042801},
|
||||
{-0.91592244254432, 0.03687901376713}, {-0.76285492357887, -0.91371867919124},
|
||||
{ 0.79788337195331, -0.93180971199849}, { 0.54473080610200, -0.11919206037186},
|
||||
{-0.85639281671058, 0.42429854760451}, {-0.92882402971423, 0.27871809078609},
|
||||
{-0.11708371046774, -0.99800843444966}, { 0.21356749817493, -0.90716295627033},
|
||||
{-0.76191692573909, 0.99768118356265}, { 0.98111043100884, -0.95854459734407},
|
||||
{-0.85913269895572, 0.95766566168880}, {-0.93307242253692, 0.49431757696466},
|
||||
{ 0.30485754879632, -0.70540034357529}, { 0.85289650925190, 0.46766131791044},
|
||||
{ 0.91328082618125, -0.99839597361769}, {-0.05890199924154, 0.70741827819497},
|
||||
{ 0.28398686150148, 0.34633555702188}, { 0.95258164539612, -0.54893416026939},
|
||||
{-0.78566324168507, -0.75568541079691}, {-0.95789495447877, -0.20423194696966},
|
||||
{ 0.82411158711197, 0.96654618432562}, {-0.65185446735885, -0.88734990773289},
|
||||
{-0.93643603134666, 0.99870790442385}, { 0.91427159529618, -0.98290505544444},
|
||||
{-0.70395684036886, 0.58796798221039}, { 0.00563771969365, 0.61768196727244},
|
||||
{ 0.89065051931895, 0.52783352697585}, {-0.68683707712762, 0.80806944710339},
|
||||
{ 0.72165342518718, -0.69259857349564}, {-0.62928247730667, 0.13627037407335},
|
||||
{ 0.29938434065514, -0.46051329682246}, {-0.91781958879280, -0.74012716684186},
|
||||
{ 0.99298717043688, 0.40816610075661}, { 0.82368298622748, -0.74036047190173},
|
||||
{-0.98512833386833, -0.99972330709594}, {-0.95915368242257, -0.99237800466040},
|
||||
{-0.21411126572790, -0.93424819052545}, {-0.68821476106884, -0.26892306315457},
|
||||
{ 0.91851997982317, 0.09358228901785}, {-0.96062769559127, 0.36099095133739},
|
||||
{ 0.51646184922287, -0.71373332873917}, { 0.61130721139669, 0.46950141175917},
|
||||
{ 0.47336129371299, -0.27333178296162}, { 0.90998308703519, 0.96715662938132},
|
||||
{ 0.44844799194357, 0.99211574628306}, { 0.66614891079092, 0.96590176169121},
|
||||
{ 0.74922239129237, -0.89879858826087}, {-0.99571588506485, 0.52785521494349},
|
||||
{ 0.97401082477563, -0.16855870075190}, { 0.72683747733879, -0.48060774432251},
|
||||
{ 0.95432193457128, 0.68849603408441}, {-0.72962208425191, -0.76608443420917},
|
||||
{-0.85359479233537, 0.88738125901579}, {-0.81412430338535, -0.97480768049637},
|
||||
{-0.87930772356786, 0.74748307690436}, {-0.71573331064977, -0.98570608178923},
|
||||
{ 0.83524300028228, 0.83702537075163}, {-0.48086065601423, -0.98848504923531},
|
||||
{ 0.97139128574778, 0.80093621198236}, { 0.51992825347895, 0.80247631400510},
|
||||
{-0.00848591195325, -0.76670128000486}, {-0.70294374303036, 0.55359910445577},
|
||||
{-0.95894428168140, -0.43265504344783}, { 0.97079252950321, 0.09325857238682},
|
||||
{-0.92404293670797, 0.85507704027855}, {-0.69506469500450, 0.98633412625459},
|
||||
{ 0.26559203620024, 0.73314307966524}, { 0.28038443336943, 0.14537913654427},
|
||||
{-0.74138124825523, 0.99310339807762}, {-0.01752795995444, -0.82616635284178},
|
||||
{-0.55126773094930, -0.98898543862153}, { 0.97960898850996, -0.94021446752851},
|
||||
{-0.99196309146936, 0.67019017358456}, {-0.67684928085260, 0.12631491649378},
|
||||
{ 0.09140039465500, -0.20537731453108}, {-0.71658965751996, -0.97788200391224},
|
||||
{ 0.81014640078925, 0.53722648362443}, { 0.40616991671205, -0.26469008598449},
|
||||
{-0.67680188682972, 0.94502052337695}, { 0.86849774348749, -0.18333598647899},
|
||||
{-0.99500381284851, -0.02634122068550}, { 0.84329189340667, 0.10406957462213},
|
||||
{-0.09215968531446, 0.69540012101253}, { 0.99956173327206, -0.12358542001404},
|
||||
{-0.79732779473535, -0.91582524736159}, { 0.96349973642406, 0.96640458041000},
|
||||
{-0.79942778496547, 0.64323902822857}, {-0.11566039853896, 0.28587846253726},
|
||||
{-0.39922954514662, 0.94129601616966}, { 0.99089197565987, -0.92062625581587},
|
||||
{ 0.28631285179909, -0.91035047143603}, {-0.83302725605608, -0.67330410892084},
|
||||
{ 0.95404443402072, 0.49162765398743}, {-0.06449863579434, 0.03250560813135},
|
||||
{-0.99575054486311, 0.42389784469507}, {-0.65501142790847, 0.82546114655624},
|
||||
{-0.81254441908887, -0.51627234660629}, {-0.99646369485481, 0.84490533520752},
|
||||
{ 0.00287840603348, 0.64768261158166}, { 0.70176989408455, -0.20453028573322},
|
||||
{ 0.96361882270190, 0.40706967140989}, {-0.68883758192426, 0.91338958840772},
|
||||
{-0.34875585502238, 0.71472290693300}, { 0.91980081243087, 0.66507455644919},
|
||||
{-0.99009048343881, 0.85868021604848}, { 0.68865791458395, 0.55660316809678},
|
||||
{-0.99484402129368, -0.20052559254934}, { 0.94214511408023, -0.99696425367461},
|
||||
{-0.67414626793544, 0.49548221180078}, {-0.47339353684664, -0.85904328834047},
|
||||
{ 0.14323651387360, -0.94145598222488}, {-0.29268293575672, 0.05759224927952},
|
||||
{ 0.43793861458754, -0.78904969892724}, {-0.36345126374441, 0.64874435357162},
|
||||
{-0.08750604656825, 0.97686944362527}, {-0.96495267812511, -0.53960305946511},
|
||||
{ 0.55526940659947, 0.78891523734774}, { 0.73538215752630, 0.96452072373404},
|
||||
{-0.30889773919437, -0.80664389776860}, { 0.03574995626194, -0.97325616900959},
|
||||
{ 0.98720684660488, 0.48409133691962}, {-0.81689296271203, -0.90827703628298},
|
||||
{ 0.67866860118215, 0.81284503870856}, {-0.15808569732583, 0.85279555024382},
|
||||
{ 0.80723395114371, -0.24717418514605}, { 0.47788757329038, -0.46333147839295},
|
||||
{ 0.96367554763201, 0.38486749303242}, {-0.99143875716818, -0.24945277239809},
|
||||
{ 0.83081876925833, -0.94780851414763}, {-0.58753191905341, 0.01290772389163},
|
||||
{ 0.95538108220960, -0.85557052096538}, {-0.96490920476211, -0.64020970923102},
|
||||
{-0.97327101028521, 0.12378128133110}, { 0.91400366022124, 0.57972471346930},
|
||||
{-0.99925837363824, 0.71084847864067}, {-0.86875903507313, -0.20291699203564},
|
||||
{-0.26240034795124, -0.68264554369108}, {-0.24664412953388, -0.87642273115183},
|
||||
{ 0.02416275806869, 0.27192914288905}, { 0.82068619590515, -0.85087787994476},
|
||||
{ 0.88547373760759, -0.89636802901469}, {-0.18173078152226, -0.26152145156800},
|
||||
{ 0.09355476558534, 0.54845123045604}, {-0.54668414224090, 0.95980774020221},
|
||||
{ 0.37050990604091, -0.59910140383171}, {-0.70373594262891, 0.91227665827081},
|
||||
{-0.34600785879594, -0.99441426144200}, {-0.68774481731008, -0.30238837956299},
|
||||
{-0.26843291251234, 0.83115668004362}, { 0.49072334613242, -0.45359708737775},
|
||||
{ 0.38975993093975, 0.95515358099121}, {-0.97757125224150, 0.05305894580606},
|
||||
{-0.17325552859616, -0.92770672250494}, { 0.99948035025744, 0.58285545563426},
|
||||
{-0.64946246527458, 0.68645507104960}, {-0.12016920576437, -0.57147322153312},
|
||||
{-0.58947456517751, -0.34847132454388}, {-0.41815140454465, 0.16276422358861},
|
||||
{ 0.99885650204884, 0.11136095490444}, {-0.56649614128386, -0.90494866361587},
|
||||
{ 0.94138021032330, 0.35281916733018}, {-0.75725076534641, 0.53650549640587},
|
||||
{ 0.20541973692630, -0.94435144369918}, { 0.99980371023351, 0.79835913565599},
|
||||
{ 0.29078277605775, 0.35393777921520}, {-0.62858772103030, 0.38765693387102},
|
||||
{ 0.43440904467688, -0.98546330463232}, {-0.98298583762390, 0.21021524625209},
|
||||
{ 0.19513029146934, -0.94239832251867}, {-0.95476662400101, 0.98364554179143},
|
||||
{ 0.93379635304810, -0.70881994583682}, {-0.85235410573336, -0.08342347966410},
|
||||
{-0.86425093011245, -0.45795025029466}, { 0.38879779059045, 0.97274429344593},
|
||||
{ 0.92045124735495, -0.62433652524220}, { 0.89162532251878, 0.54950955570563},
|
||||
{-0.36834336949252, 0.96458298020975}, { 0.93891760988045, -0.89968353740388},
|
||||
{ 0.99267657565094, -0.03757034316958}, {-0.94063471614176, 0.41332338538963},
|
||||
{ 0.99740224117019, -0.16830494996370}, {-0.35899413170555, -0.46633226649613},
|
||||
{ 0.05237237274947, -0.25640361602661}, { 0.36703583957424, -0.38653265641875},
|
||||
{ 0.91653180367913, -0.30587628726597}, { 0.69000803499316, 0.90952171386132},
|
||||
{-0.38658751133527, 0.99501571208985}, {-0.29250814029851, 0.37444994344615},
|
||||
{-0.60182204677608, 0.86779651036123}, {-0.97418588163217, 0.96468523666475},
|
||||
{ 0.88461574003963, 0.57508405276414}, { 0.05198933055162, 0.21269661669964},
|
||||
{-0.53499621979720, 0.97241553731237}, {-0.49429560226497, 0.98183865291903},
|
||||
{-0.98935142339139, -0.40249159006933}, {-0.98081380091130, -0.72856895534041},
|
||||
{-0.27338148835532, 0.99950922447209}, { 0.06310802338302, -0.54539587529618},
|
||||
{-0.20461677199539, -0.14209977628489}, { 0.66223843141647, 0.72528579940326},
|
||||
{-0.84764345483665, 0.02372316801261}, {-0.89039863483811, 0.88866581484602},
|
||||
{ 0.95903308477986, 0.76744927173873}, { 0.73504123909879, -0.03747203173192},
|
||||
{-0.31744434966056, -0.36834111883652}, {-0.34110827591623, 0.40211222807691},
|
||||
{ 0.47803883714199, -0.39423219786288}, { 0.98299195879514, 0.01989791390047},
|
||||
{-0.30963073129751, -0.18076720599336}, { 0.99992588229018, -0.26281872094289},
|
||||
{-0.93149731080767, -0.98313162570490}, { 0.99923472302773, -0.80142993767554},
|
||||
{-0.26024169633417, -0.75999759855752}, {-0.35712514743563, 0.19298963768574},
|
||||
{-0.99899084509530, 0.74645156992493}, { 0.86557171579452, 0.55593866696299},
|
||||
{ 0.33408042438752, 0.86185953874709}, { 0.99010736374716, 0.04602397576623},
|
||||
{-0.66694269691195, -0.91643611810148}, { 0.64016792079480, 0.15649530836856},
|
||||
{ 0.99570534804836, 0.45844586038111}, {-0.63431466947340, 0.21079116459234},
|
||||
{-0.07706847005931, -0.89581437101329}, { 0.98590090577724, 0.88241721133981},
|
||||
{ 0.80099335254678, -0.36851896710853}, { 0.78368131392666, 0.45506999802597},
|
||||
{ 0.08707806671691, 0.80938994918745}, {-0.86811883080712, 0.39347308654705},
|
||||
{-0.39466529740375, -0.66809432114456}, { 0.97875325649683, -0.72467840967746},
|
||||
{-0.95038560288864, 0.89563219587625}, { 0.17005239424212, 0.54683053962658},
|
||||
{-0.76910792026848, -0.96226617549298}, { 0.99743281016846, 0.42697157037567},
|
||||
{ 0.95437383549973, 0.97002324109952}, { 0.99578905365569, -0.54106826257356},
|
||||
{ 0.28058259829990, -0.85361420634036}, { 0.85256524470573, -0.64567607735589},
|
||||
{-0.50608540105128, -0.65846015480300}, {-0.97210735183243, -0.23095213067791},
|
||||
{ 0.95424048234441, -0.99240147091219}, {-0.96926570524023, 0.73775654896574},
|
||||
{ 0.30872163214726, 0.41514960556126}, {-0.24523839572639, 0.63206633394807},
|
||||
{-0.33813265086024, -0.38661779441897}, {-0.05826828420146, -0.06940774188029},
|
||||
{-0.22898461455054, 0.97054853316316}, {-0.18509915019881, 0.47565762892084},
|
||||
{-0.10488238045009, -0.87769947402394}, {-0.71886586182037, 0.78030982480538},
|
||||
{ 0.99793873738654, 0.90041310491497}, { 0.57563307626120, -0.91034337352097},
|
||||
{ 0.28909646383717, 0.96307783970534}, { 0.42188998312520, 0.48148651230437},
|
||||
{ 0.93335049681047, -0.43537023883588}, {-0.97087374418267, 0.86636445711364},
|
||||
{ 0.36722871286923, 0.65291654172961}, {-0.81093025665696, 0.08778370229363},
|
||||
{-0.26240603062237, -0.92774095379098}, { 0.83996497984604, 0.55839849139647},
|
||||
{-0.99909615720225, -0.96024605713970}, { 0.74649464155061, 0.12144893606462},
|
||||
{-0.74774595569805, -0.26898062008959}, { 0.95781667469567, -0.79047927052628},
|
||||
{ 0.95472308713099, -0.08588776019550}, { 0.48708332746299, 0.99999041579432},
|
||||
{ 0.46332038247497, 0.10964126185063}, {-0.76497004940162, 0.89210929242238},
|
||||
{ 0.57397389364339, 0.35289703373760}, { 0.75374316974495, 0.96705214651335},
|
||||
{-0.59174397685714, -0.89405370422752}, { 0.75087906691890, -0.29612672982396},
|
||||
{-0.98607857336230, 0.25034911730023}, {-0.40761056640505, -0.90045573444695},
|
||||
{ 0.66929266740477, 0.98629493401748}, {-0.97463695257310, -0.00190223301301},
|
||||
{ 0.90145509409859, 0.99781390365446}, {-0.87259289048043, 0.99233587353666},
|
||||
{-0.91529461447692, -0.15698707534206}, {-0.03305738840705, -0.37205262859764},
|
||||
{ 0.07223051368337, -0.88805001733626}, { 0.99498012188353, 0.97094358113387},
|
||||
{-0.74904939500519, 0.99985483641521}, { 0.04585228574211, 0.99812337444082},
|
||||
{-0.89054954257993, -0.31791913188064}, {-0.83782144651251, 0.97637632547466},
|
||||
{ 0.33454804933804, -0.86231516800408}, {-0.99707579362824, 0.93237990079441},
|
||||
{-0.22827527843994, 0.18874759397997}, { 0.67248046289143, -0.03646211390569},
|
||||
{-0.05146538187944, -0.92599700120679}, { 0.99947295749905, 0.93625229707912},
|
||||
{ 0.66951124390363, 0.98905825623893}, {-0.99602956559179, -0.44654715757688},
|
||||
{ 0.82104905483590, 0.99540741724928}, { 0.99186510988782, 0.72023001312947},
|
||||
{-0.65284592392918, 0.52186723253637}, { 0.93885443798188, -0.74895312615259},
|
||||
{ 0.96735248738388, 0.90891816978629}, {-0.22225968841114, 0.57124029781228},
|
||||
{-0.44132783753414, -0.92688840659280}, {-0.85694974219574, 0.88844532719844},
|
||||
{ 0.91783042091762, -0.46356892383970}, { 0.72556974415690, -0.99899555770747},
|
||||
{-0.99711581834508, 0.58211560180426}, { 0.77638976371966, 0.94321834873819},
|
||||
{ 0.07717324253925, 0.58638399856595}, {-0.56049829194163, 0.82522301569036},
|
||||
{ 0.98398893639988, 0.39467440420569}, { 0.47546946844938, 0.68613044836811},
|
||||
{ 0.65675089314631, 0.18331637134880}, { 0.03273375457980, -0.74933109564108},
|
||||
{-0.38684144784738, 0.51337349030406}, {-0.97346267944545, -0.96549364384098},
|
||||
{-0.53282156061942, -0.91423265091354}, { 0.99817310731176, 0.61133572482148},
|
||||
{-0.50254500772635, -0.88829338134294}, { 0.01995873238855, 0.85223515096765},
|
||||
{ 0.99930381973804, 0.94578896296649}, { 0.82907767600783, -0.06323442598128},
|
||||
{-0.58660709669728, 0.96840773806582}, {-0.17573736667267, -0.48166920859485},
|
||||
{ 0.83434292401346, -0.13023450646997}, { 0.05946491307025, 0.20511047074866},
|
||||
{ 0.81505484574602, -0.94685947861369}, {-0.44976380954860, 0.40894572671545},
|
||||
{-0.89746474625671, 0.99846578838537}, { 0.39677256130792, -0.74854668609359},
|
||||
{-0.07588948563079, 0.74096214084170}, { 0.76343198951445, 0.41746629422634},
|
||||
{-0.74490104699626, 0.94725911744610}, { 0.64880119792759, 0.41336660830571},
|
||||
{ 0.62319537462542, -0.93098313552599}, { 0.42215817594807, -0.07712787385208},
|
||||
{ 0.02704554141885, -0.05417518053666}, { 0.80001773566818, 0.91542195141039},
|
||||
{-0.79351832348816, -0.36208897989136}, { 0.63872359151636, 0.08128252493444},
|
||||
{ 0.52890520960295, 0.60048872455592}, { 0.74238552914587, 0.04491915291044},
|
||||
{ 0.99096131449250, -0.19451182854402}, {-0.80412329643109, -0.88513818199457},
|
||||
{-0.64612616129736, 0.72198674804544}, { 0.11657770663191, -0.83662833815041},
|
||||
{-0.95053182488101, -0.96939905138082}, {-0.62228872928622, 0.82767262846661},
|
||||
{ 0.03004475787316, -0.99738896333384}, {-0.97987214341034, 0.36526129686425},
|
||||
{-0.99986980746200, -0.36021610299715}, { 0.89110648599879, -0.97894250343044},
|
||||
{ 0.10407960510582, 0.77357793811619}, { 0.95964737821728, -0.35435818285502},
|
||||
{ 0.50843233159162, 0.96107691266205}, { 0.17006334670615, -0.76854025314829},
|
||||
{ 0.25872675063360, 0.99893303933816}, {-0.01115998681937, 0.98496019742444},
|
||||
{-0.79598702973261, 0.97138411318894}, {-0.99264708948101, -0.99542822402536},
|
||||
{-0.99829663752818, 0.01877138824311}, {-0.70801016548184, 0.33680685948117},
|
||||
{-0.70467057786826, 0.93272777501857}, { 0.99846021905254, -0.98725746254433},
|
||||
{-0.63364968534650, -0.16473594423746}, {-0.16258217500792, -0.95939125400802},
|
||||
{-0.43645594360633, -0.94805030113284}, {-0.99848471702976, 0.96245166923809},
|
||||
{-0.16796458968998, -0.98987511890470}, {-0.87979225745213, -0.71725725041680},
|
||||
{ 0.44183099021786, -0.93568974498761}, { 0.93310180125532, -0.99913308068246},
|
||||
{-0.93941931782002, -0.56409379640356}, {-0.88590003188677, 0.47624600491382},
|
||||
{ 0.99971463703691, -0.83889954253462}, {-0.75376385639978, 0.00814643438625},
|
||||
{ 0.93887685615875, -0.11284528204636}, { 0.85126435782309, 0.52349251543547},
|
||||
{ 0.39701421446381, 0.81779634174316}, {-0.37024464187437, -0.87071656222959},
|
||||
{-0.36024828242896, 0.34655735648287}, {-0.93388812549209, -0.84476541096429},
|
||||
{-0.65298804552119, -0.18439575450921}, { 0.11960319006843, 0.99899346780168},
|
||||
{ 0.94292565553160, 0.83163906518293}, { 0.75081145286948, -0.35533223142265},
|
||||
{ 0.56721979748394, -0.24076836414499}, { 0.46857766746029, -0.30140233457198},
|
||||
{ 0.97312313923635, -0.99548191630031}, {-0.38299976567017, 0.98516909715427},
|
||||
{ 0.41025800019463, 0.02116736935734}, { 0.09638062008048, 0.04411984381457},
|
||||
{-0.85283249275397, 0.91475563922421}, { 0.88866808958124, -0.99735267083226},
|
||||
{-0.48202429536989, -0.96805608884164}, { 0.27572582416567, 0.58634753335832},
|
||||
{-0.65889129659168, 0.58835634138583}, { 0.98838086953732, 0.99994349600236},
|
||||
{-0.20651349620689, 0.54593044066355}, {-0.62126416356920, -0.59893681700392},
|
||||
{ 0.20320105410437, -0.86879180355289}, {-0.97790548600584, 0.96290806999242},
|
||||
{ 0.11112534735126, 0.21484763313301}, {-0.41368337314182, 0.28216837680365},
|
||||
{ 0.24133038992960, 0.51294362630238}, {-0.66393410674885, -0.08249679629081},
|
||||
{-0.53697829178752, -0.97649903936228}, {-0.97224737889348, 0.22081333579837},
|
||||
{ 0.87392477144549, -0.12796173740361}, { 0.19050361015753, 0.01602615387195},
|
||||
{-0.46353441212724, -0.95249041539006}, {-0.07064096339021, -0.94479803205886},
|
||||
{-0.92444085484466, -0.10457590187436}, {-0.83822593578728, -0.01695043208885},
|
||||
{ 0.75214681811150, -0.99955681042665}, {-0.42102998829339, 0.99720941999394},
|
||||
{-0.72094786237696, -0.35008961934255}, { 0.78843311019251, 0.52851398958271},
|
||||
{ 0.97394027897442, -0.26695944086561}, { 0.99206463477946, -0.57010120849429},
|
||||
{ 0.76789609461795, -0.76519356730966}, {-0.82002421836409, -0.73530179553767},
|
||||
{ 0.81924990025724, 0.99698425250579}, {-0.26719850873357, 0.68903369776193},
|
||||
{-0.43311260380975, 0.85321815947490}, { 0.99194979673836, 0.91876249766422},
|
||||
{-0.80692001248487, -0.32627540663214}, { 0.43080003649976, -0.21919095636638},
|
||||
{ 0.67709491937357, -0.95478075822906}, { 0.56151770568316, -0.70693811747778},
|
||||
{ 0.10831862810749, -0.08628837174592}, { 0.91229417540436, -0.65987351408410},
|
||||
{-0.48972893932274, 0.56289246362686}, {-0.89033658689697, -0.71656563987082},
|
||||
{ 0.65269447475094, 0.65916004833932}, { 0.67439478141121, -0.81684380846796},
|
||||
{-0.47770832416973, -0.16789556203025}, {-0.99715979260878, -0.93565784007648},
|
||||
{-0.90889593602546, 0.62034397054380}, {-0.06618622548177, -0.23812217221359},
|
||||
{ 0.99430266919728, 0.18812555317553}, { 0.97686402381843, -0.28664534366620},
|
||||
{ 0.94813650221268, -0.97506640027128}, {-0.95434497492853, -0.79607978501983},
|
||||
{-0.49104783137150, 0.32895214359663}, { 0.99881175120751, 0.88993983831354},
|
||||
{ 0.50449166760303, -0.85995072408434}, { 0.47162891065108, -0.18680204049569},
|
||||
{-0.62081581361840, 0.75000676218956}, {-0.43867015250812, 0.99998069244322},
|
||||
{ 0.98630563232075, -0.53578899600662}, {-0.61510362277374, -0.89515019899997},
|
||||
{-0.03841517601843, -0.69888815681179}, {-0.30102157304644, -0.07667808922205},
|
||||
{ 0.41881284182683, 0.02188098922282}, {-0.86135454941237, 0.98947480909359},
|
||||
{ 0.67226861393788, -0.13494389011014}, {-0.70737398842068, -0.76547349325992},
|
||||
{ 0.94044946687963, 0.09026201157416}, {-0.82386352534327, 0.08924768823676},
|
||||
{-0.32070666698656, 0.50143421908753}, { 0.57593163224487, -0.98966422921509},
|
||||
{-0.36326018419965, 0.07440243123228}, { 0.99979044674350, -0.14130287347405},
|
||||
{-0.92366023326932, -0.97979298068180}, {-0.44607178518598, -0.54233252016394},
|
||||
{ 0.44226800932956, 0.71326756742752}, { 0.03671907158312, 0.63606389366675},
|
||||
{ 0.52175424682195, -0.85396826735705}, {-0.94701139690956, -0.01826348194255},
|
||||
{-0.98759606946049, 0.82288714303073}, { 0.87434794743625, 0.89399495655433},
|
||||
{-0.93412041758744, 0.41374052024363}, { 0.96063943315511, 0.93116709541280},
|
||||
{ 0.97534253457837, 0.86150930812689}, { 0.99642466504163, 0.70190043427512},
|
||||
{-0.94705089665984, -0.29580042814306}, { 0.91599807087376, -0.98147830385781},
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_AACSBRDATA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* AAC data declarations
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC data declarations
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACTAB_H
|
||||
#define AVCODEC_AACTAB_H
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
#include "aac.h"
|
||||
#include "aac_tablegen_decl.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* NOTE:
|
||||
* Tables in this file are used by the AAC decoder and will be used by the AAC
|
||||
* encoder.
|
||||
*/
|
||||
|
||||
/* @name window coefficients
|
||||
* @{
|
||||
*/
|
||||
DECLARE_ALIGNED(16, extern float, ff_aac_kbd_long_1024)[1024];
|
||||
DECLARE_ALIGNED(16, extern float, ff_aac_kbd_short_128)[128];
|
||||
// @}
|
||||
|
||||
/* @name number of scalefactor window bands for long and short transform windows respectively
|
||||
* @{
|
||||
*/
|
||||
extern const uint8_t ff_aac_num_swb_1024[];
|
||||
extern const uint8_t ff_aac_num_swb_128 [];
|
||||
// @}
|
||||
|
||||
extern const uint8_t ff_aac_pred_sfb_max [];
|
||||
|
||||
extern const uint32_t ff_aac_scalefactor_code[121];
|
||||
extern const uint8_t ff_aac_scalefactor_bits[121];
|
||||
|
||||
extern const uint16_t * const ff_aac_spectral_codes[11];
|
||||
extern const uint8_t * const ff_aac_spectral_bits [11];
|
||||
extern const uint16_t ff_aac_spectral_sizes[11];
|
||||
|
||||
extern const float *ff_aac_codebook_vectors[];
|
||||
extern const float *ff_aac_codebook_vector_vals[];
|
||||
extern const uint16_t *ff_aac_codebook_vector_idx[];
|
||||
|
||||
extern const uint16_t * const ff_swb_offset_1024[13];
|
||||
extern const uint16_t * const ff_swb_offset_128 [13];
|
||||
|
||||
extern const uint8_t ff_tns_max_bands_1024[13];
|
||||
extern const uint8_t ff_tns_max_bands_128 [13];
|
||||
|
||||
#endif /* AVCODEC_AACTAB_H */
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* AAN (Arai Agui Aakajima) (I)DCT tables
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const uint16_t ff_aanscales[64] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867 , 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520 , 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
|
||||
const uint16_t ff_inv_aanscales[64] = {
|
||||
4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846,
|
||||
2953, 2129, 2260, 2511, 2953, 3759, 5457, 10703,
|
||||
3135, 2260, 2399, 2666, 3135, 3990, 5793, 11363,
|
||||
3483, 2511, 2666, 2962, 3483, 4433, 6436, 12625,
|
||||
4096, 2953, 3135, 3483, 4096, 5213, 7568, 14846,
|
||||
5213, 3759, 3990, 4433, 5213, 6635, 9633, 18895,
|
||||
7568, 5457, 5793, 6436, 7568, 9633, 13985, 27432,
|
||||
14846, 10703, 11363, 12625, 14846, 18895, 27432, 53809,
|
||||
};
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* AAN (Arai Agui Nakajima) (I)DCT tables
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AANDCTTAB_H
|
||||
#define AVCODEC_AANDCTTAB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint16_t ff_aanscales[64];
|
||||
extern const uint16_t ff_inv_aanscales[64];
|
||||
|
||||
#endif /* AVCODEC_AANDCTTAB_H */
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* Autodesk RLE Video Decoder by Konstantin Shishkov
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "msrledec.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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aasc_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
AascContext *s = avctx->priv_data;
|
||||
int compr, i, stride;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
compr = AV_RL32(buf);
|
||||
buf += 4;
|
||||
buf_size -= 4;
|
||||
switch(compr){
|
||||
case 0:
|
||||
stride = (avctx->width * 3 + 3) & ~3;
|
||||
for(i = avctx->height - 1; i >= 0; i--){
|
||||
memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width*3);
|
||||
buf += stride;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, buf - 4, buf_size + 4);
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*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",
|
||||
AVMEDIA_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"),
|
||||
};
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* Common code between the AC-3 encoder and decoder
|
||||
* Copyright (c) 2000 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
|
||||
* Common code between the AC-3 encoder and decoder.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "ac3.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
|
||||
/**
|
||||
* Starting frequency coefficient bin for each critical band.
|
||||
*/
|
||||
static const uint8_t band_start_tab[51] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
|
||||
34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
|
||||
79, 85, 97, 109, 121, 133, 157, 181, 205, 229, 253
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps each frequency coefficient bin to the critical band that contains it.
|
||||
*/
|
||||
static const uint8_t bin_to_band_tab[253] = {
|
||||
0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30,
|
||||
31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34,
|
||||
35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36,
|
||||
37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38,
|
||||
39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40,
|
||||
41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
|
||||
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
|
||||
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
|
||||
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
|
||||
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
|
||||
45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
|
||||
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
|
||||
46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
|
||||
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
|
||||
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
|
||||
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
|
||||
49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49
|
||||
};
|
||||
|
||||
#else /* CONFIG_HARDCODED_TABLES */
|
||||
static uint8_t band_start_tab[51];
|
||||
static uint8_t bin_to_band_tab[253];
|
||||
#endif
|
||||
|
||||
static inline int calc_lowcomp1(int a, int b0, int b1, int c)
|
||||
{
|
||||
if ((b0 + 256) == b1) {
|
||||
a = c;
|
||||
} else if (b0 > b1) {
|
||||
a = FFMAX(a - 64, 0);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
static inline int calc_lowcomp(int a, int b0, int b1, int bin)
|
||||
{
|
||||
if (bin < 7) {
|
||||
return calc_lowcomp1(a, b0, b1, 384);
|
||||
} else if (bin < 20) {
|
||||
return calc_lowcomp1(a, b0, b1, 320);
|
||||
} else {
|
||||
return FFMAX(a - 128, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd,
|
||||
int16_t *band_psd)
|
||||
{
|
||||
int bin, band;
|
||||
|
||||
/* exponent mapping to PSD */
|
||||
for (bin = start; bin < end; bin++) {
|
||||
psd[bin]=(3072 - (exp[bin] << 7));
|
||||
}
|
||||
|
||||
/* PSD integration */
|
||||
bin = start;
|
||||
band = bin_to_band_tab[start];
|
||||
do {
|
||||
int v = psd[bin++];
|
||||
int band_end = FFMIN(band_start_tab[band+1], end);
|
||||
for (; bin < band_end; bin++) {
|
||||
int max = FFMAX(v, psd[bin]);
|
||||
/* logadd */
|
||||
int adr = FFMIN(max - ((v + psd[bin] + 1) >> 1), 255);
|
||||
v = max + ff_ac3_log_add_tab[adr];
|
||||
}
|
||||
band_psd[band++] = v;
|
||||
} while (end > band_start_tab[band]);
|
||||
}
|
||||
|
||||
int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd,
|
||||
int start, int end, int fast_gain, int is_lfe,
|
||||
int dba_mode, int dba_nsegs, uint8_t *dba_offsets,
|
||||
uint8_t *dba_lengths, uint8_t *dba_values,
|
||||
int16_t *mask)
|
||||
{
|
||||
int16_t excite[50]; /* excitation */
|
||||
int band;
|
||||
int band_start, band_end, begin, end1;
|
||||
int lowcomp, fastleak, slowleak;
|
||||
|
||||
/* excitation function */
|
||||
band_start = bin_to_band_tab[start];
|
||||
band_end = bin_to_band_tab[end-1] + 1;
|
||||
|
||||
if (band_start == 0) {
|
||||
lowcomp = 0;
|
||||
lowcomp = calc_lowcomp1(lowcomp, band_psd[0], band_psd[1], 384);
|
||||
excite[0] = band_psd[0] - fast_gain - lowcomp;
|
||||
lowcomp = calc_lowcomp1(lowcomp, band_psd[1], band_psd[2], 384);
|
||||
excite[1] = band_psd[1] - fast_gain - lowcomp;
|
||||
begin = 7;
|
||||
for (band = 2; band < 7; band++) {
|
||||
if (!(is_lfe && band == 6))
|
||||
lowcomp = calc_lowcomp1(lowcomp, band_psd[band], band_psd[band+1], 384);
|
||||
fastleak = band_psd[band] - fast_gain;
|
||||
slowleak = band_psd[band] - s->slow_gain;
|
||||
excite[band] = fastleak - lowcomp;
|
||||
if (!(is_lfe && band == 6)) {
|
||||
if (band_psd[band] <= band_psd[band+1]) {
|
||||
begin = band + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end1 = FFMIN(band_end, 22);
|
||||
for (band = begin; band < end1; band++) {
|
||||
if (!(is_lfe && band == 6))
|
||||
lowcomp = calc_lowcomp(lowcomp, band_psd[band], band_psd[band+1], band);
|
||||
fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain);
|
||||
slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain);
|
||||
excite[band] = FFMAX(fastleak - lowcomp, slowleak);
|
||||
}
|
||||
begin = 22;
|
||||
} else {
|
||||
/* coupling channel */
|
||||
begin = band_start;
|
||||
fastleak = (s->cpl_fast_leak << 8) + 768;
|
||||
slowleak = (s->cpl_slow_leak << 8) + 768;
|
||||
}
|
||||
|
||||
for (band = begin; band < band_end; band++) {
|
||||
fastleak = FFMAX(fastleak - s->fast_decay, band_psd[band] - fast_gain);
|
||||
slowleak = FFMAX(slowleak - s->slow_decay, band_psd[band] - s->slow_gain);
|
||||
excite[band] = FFMAX(fastleak, slowleak);
|
||||
}
|
||||
|
||||
/* compute masking curve */
|
||||
|
||||
for (band = band_start; band < band_end; band++) {
|
||||
int tmp = s->db_per_bit - band_psd[band];
|
||||
if (tmp > 0) {
|
||||
excite[band] += tmp >> 2;
|
||||
}
|
||||
mask[band] = FFMAX(ff_ac3_hearing_threshold_tab[band >> s->sr_shift][s->sr_code], excite[band]);
|
||||
}
|
||||
|
||||
/* delta bit allocation */
|
||||
|
||||
if (dba_mode == DBA_REUSE || dba_mode == DBA_NEW) {
|
||||
int i, seg, delta;
|
||||
if (dba_nsegs >= 8)
|
||||
return -1;
|
||||
band = 0;
|
||||
for (seg = 0; seg < dba_nsegs; seg++) {
|
||||
band += dba_offsets[seg];
|
||||
if (band >= 50 || dba_lengths[seg] > 50-band)
|
||||
return -1;
|
||||
if (dba_values[seg] >= 4) {
|
||||
delta = (dba_values[seg] - 3) << 7;
|
||||
} else {
|
||||
delta = (dba_values[seg] - 4) << 7;
|
||||
}
|
||||
for (i = 0; i < dba_lengths[seg]; i++) {
|
||||
mask[band++] += delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
|
||||
int snr_offset, int floor,
|
||||
const uint8_t *bap_tab, uint8_t *bap)
|
||||
{
|
||||
int bin, band;
|
||||
|
||||
/* special case, if snr offset is -960, set all bap's to zero */
|
||||
if (snr_offset == -960) {
|
||||
memset(bap, 0, 256);
|
||||
return;
|
||||
}
|
||||
|
||||
bin = start;
|
||||
band = bin_to_band_tab[start];
|
||||
do {
|
||||
int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
|
||||
int band_end = FFMIN(band_start_tab[band+1], end);
|
||||
for (; bin < band_end; bin++) {
|
||||
int address = av_clip((psd[bin] - m) >> 5, 0, 63);
|
||||
bap[bin] = bap_tab[address];
|
||||
}
|
||||
} while (end > band_start_tab[band++]);
|
||||
}
|
||||
|
||||
/* AC-3 bit allocation. The algorithm is the one described in the AC-3
|
||||
spec. */
|
||||
void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
|
||||
int8_t *exp, int start, int end,
|
||||
int snr_offset, int fast_gain, int is_lfe,
|
||||
int dba_mode, int dba_nsegs,
|
||||
uint8_t *dba_offsets, uint8_t *dba_lengths,
|
||||
uint8_t *dba_values)
|
||||
{
|
||||
int16_t psd[256]; /* scaled exponents */
|
||||
int16_t band_psd[50]; /* interpolated exponents */
|
||||
int16_t mask[50]; /* masking value */
|
||||
|
||||
ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, band_psd);
|
||||
|
||||
ff_ac3_bit_alloc_calc_mask(s, band_psd, start, end, fast_gain, is_lfe,
|
||||
dba_mode, dba_nsegs, dba_offsets, dba_lengths,
|
||||
dba_values, mask);
|
||||
|
||||
ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snr_offset, s->floor,
|
||||
ff_ac3_bap_tab, bap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes some tables.
|
||||
* note: This function must remain thread safe because it is called by the
|
||||
* AVParser init code.
|
||||
*/
|
||||
av_cold void ac3_common_init(void)
|
||||
{
|
||||
#if !CONFIG_HARDCODED_TABLES
|
||||
/* compute bndtab and masktab from bandsz */
|
||||
int bin = 0, band;
|
||||
for (band = 0; band < 50; band++) {
|
||||
int band_end = bin + ff_ac3_critical_band_size_tab[band];
|
||||
band_start_tab[band] = bin;
|
||||
while (bin < band_end)
|
||||
bin_to_band_tab[bin++] = band;
|
||||
}
|
||||
band_start_tab[50] = bin;
|
||||
#endif /* !CONFIG_HARDCODED_TABLES */
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Common code between the AC-3 encoder and decoder
|
||||
* Copyright (c) 2000, 2001, 2002 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
|
||||
* Common code between the AC-3 encoder and decoder.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AC3_H
|
||||
#define AVCODEC_AC3_H
|
||||
|
||||
#include "ac3tab.h"
|
||||
|
||||
#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */
|
||||
#define AC3_MAX_CHANNELS 6 /* including LFE channel */
|
||||
|
||||
#define NB_BLOCKS 6 /* number of PCM blocks inside an AC-3 frame */
|
||||
#define AC3_FRAME_SIZE (NB_BLOCKS * 256)
|
||||
|
||||
/* exponent encoding strategy */
|
||||
#define EXP_REUSE 0
|
||||
#define EXP_NEW 1
|
||||
|
||||
#define EXP_D15 1
|
||||
#define EXP_D25 2
|
||||
#define EXP_D45 3
|
||||
|
||||
/** Delta bit allocation strategy */
|
||||
typedef enum {
|
||||
DBA_REUSE = 0,
|
||||
DBA_NEW,
|
||||
DBA_NONE,
|
||||
DBA_RESERVED
|
||||
} AC3DeltaStrategy;
|
||||
|
||||
/** Channel mode (audio coding mode) */
|
||||
typedef enum {
|
||||
AC3_CHMODE_DUALMONO = 0,
|
||||
AC3_CHMODE_MONO,
|
||||
AC3_CHMODE_STEREO,
|
||||
AC3_CHMODE_3F,
|
||||
AC3_CHMODE_2F1R,
|
||||
AC3_CHMODE_3F1R,
|
||||
AC3_CHMODE_2F2R,
|
||||
AC3_CHMODE_3F2R
|
||||
} AC3ChannelMode;
|
||||
|
||||
typedef struct AC3BitAllocParameters {
|
||||
int sr_code;
|
||||
int sr_shift;
|
||||
int slow_gain, slow_decay, fast_decay, db_per_bit, floor;
|
||||
int cpl_fast_leak, cpl_slow_leak;
|
||||
} AC3BitAllocParameters;
|
||||
|
||||
/**
|
||||
* @struct AC3HeaderInfo
|
||||
* Coded AC-3 header values up to the lfeon element, plus derived values.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @defgroup coded Coded elements
|
||||
* @{
|
||||
*/
|
||||
uint16_t sync_word;
|
||||
uint16_t crc1;
|
||||
uint8_t sr_code;
|
||||
uint8_t bitstream_id;
|
||||
uint8_t channel_mode;
|
||||
uint8_t lfe_on;
|
||||
uint8_t frame_type;
|
||||
int substreamid; ///< substream identification
|
||||
int center_mix_level; ///< Center mix level index
|
||||
int surround_mix_level; ///< Surround mix level index
|
||||
uint16_t channel_map;
|
||||
int num_blocks; ///< number of audio blocks
|
||||
/** @} */
|
||||
|
||||
/** @defgroup derived Derived values
|
||||
* @{
|
||||
*/
|
||||
uint8_t sr_shift;
|
||||
uint16_t sample_rate;
|
||||
uint32_t bit_rate;
|
||||
uint8_t channels;
|
||||
uint16_t frame_size;
|
||||
int64_t channel_layout;
|
||||
/** @} */
|
||||
} AC3HeaderInfo;
|
||||
|
||||
typedef enum {
|
||||
EAC3_FRAME_TYPE_INDEPENDENT = 0,
|
||||
EAC3_FRAME_TYPE_DEPENDENT,
|
||||
EAC3_FRAME_TYPE_AC3_CONVERT,
|
||||
EAC3_FRAME_TYPE_RESERVED
|
||||
} EAC3FrameType;
|
||||
|
||||
void ac3_common_init(void);
|
||||
|
||||
/**
|
||||
* Calculates the log power-spectral density of the input signal.
|
||||
* This gives a rough estimate of signal power in the frequency domain by using
|
||||
* the spectral envelope (exponents). The psd is also separately grouped
|
||||
* into critical bands for use in the calculating the masking curve.
|
||||
* 128 units in psd = -6 dB. The dbknee parameter in AC3BitAllocParameters
|
||||
* determines the reference level.
|
||||
*
|
||||
* @param[in] exp frequency coefficient exponents
|
||||
* @param[in] start starting bin location
|
||||
* @param[in] end ending bin location
|
||||
* @param[out] psd signal power for each frequency bin
|
||||
* @param[out] band_psd signal power for each critical band
|
||||
*/
|
||||
void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd,
|
||||
int16_t *band_psd);
|
||||
|
||||
/**
|
||||
* Calculates the masking curve.
|
||||
* First, the excitation is calculated using parameters in s and the signal
|
||||
* power in each critical band. The excitation is compared with a predefined
|
||||
* hearing threshold table to produce the masking curve. If delta bit
|
||||
* allocation information is provided, it is used for adjusting the masking
|
||||
* curve, usually to give a closer match to a better psychoacoustic model.
|
||||
*
|
||||
* @param[in] s adjustable bit allocation parameters
|
||||
* @param[in] band_psd signal power for each critical band
|
||||
* @param[in] start starting bin location
|
||||
* @param[in] end ending bin location
|
||||
* @param[in] fast_gain fast gain (estimated signal-to-mask ratio)
|
||||
* @param[in] is_lfe whether or not the channel being processed is the LFE
|
||||
* @param[in] dba_mode delta bit allocation mode (none, reuse, or new)
|
||||
* @param[in] dba_nsegs number of delta segments
|
||||
* @param[in] dba_offsets location offsets for each segment
|
||||
* @param[in] dba_lengths length of each segment
|
||||
* @param[in] dba_values delta bit allocation for each segment
|
||||
* @param[out] mask calculated masking curve
|
||||
* @return returns 0 for success, non-zero for error
|
||||
*/
|
||||
int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd,
|
||||
int start, int end, int fast_gain, int is_lfe,
|
||||
int dba_mode, int dba_nsegs, uint8_t *dba_offsets,
|
||||
uint8_t *dba_lengths, uint8_t *dba_values,
|
||||
int16_t *mask);
|
||||
|
||||
/**
|
||||
* Calculates bit allocation pointers.
|
||||
* The SNR is the difference between the masking curve and the signal. AC-3
|
||||
* uses this value for each frequency bin to allocate bits. The snroffset
|
||||
* parameter is a global adjustment to the SNR for all bins.
|
||||
*
|
||||
* @param[in] mask masking curve
|
||||
* @param[in] psd signal power for each frequency bin
|
||||
* @param[in] start starting bin location
|
||||
* @param[in] end ending bin location
|
||||
* @param[in] snr_offset SNR adjustment
|
||||
* @param[in] floor noise floor
|
||||
* @param[in] bap_tab look-up table for bit allocation pointers
|
||||
* @param[out] bap bit allocation pointers
|
||||
*/
|
||||
void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
|
||||
int snr_offset, int floor,
|
||||
const uint8_t *bap_tab, uint8_t *bap);
|
||||
|
||||
void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
|
||||
int8_t *exp, int start, int end,
|
||||
int snr_offset, int fast_gain, int is_lfe,
|
||||
int dba_mode, int dba_nsegs,
|
||||
uint8_t *dba_offsets, uint8_t *dba_lengths,
|
||||
uint8_t *dba_values);
|
||||
|
||||
#endif /* AVCODEC_AC3_H */
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
* AC-3 parser
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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 "parser.h"
|
||||
#include "ac3_parser.h"
|
||||
#include "aac_ac3_parser.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
|
||||
#define AC3_HEADER_SIZE 7
|
||||
|
||||
|
||||
static const uint8_t eac3_blocks[4] = {
|
||||
1, 2, 3, 6
|
||||
};
|
||||
|
||||
|
||||
int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
|
||||
{
|
||||
int frame_size_code;
|
||||
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
|
||||
hdr->sync_word = get_bits(gbc, 16);
|
||||
if(hdr->sync_word != 0x0B77)
|
||||
return AAC_AC3_PARSE_ERROR_SYNC;
|
||||
|
||||
/* read ahead to bsid to distinguish between AC-3 and E-AC-3 */
|
||||
hdr->bitstream_id = show_bits_long(gbc, 29) & 0x1F;
|
||||
if(hdr->bitstream_id > 16)
|
||||
return AAC_AC3_PARSE_ERROR_BSID;
|
||||
|
||||
hdr->num_blocks = 6;
|
||||
|
||||
/* set default mix levels */
|
||||
hdr->center_mix_level = 1; // -4.5dB
|
||||
hdr->surround_mix_level = 1; // -6.0dB
|
||||
|
||||
if(hdr->bitstream_id <= 10) {
|
||||
/* Normal AC-3 */
|
||||
hdr->crc1 = get_bits(gbc, 16);
|
||||
hdr->sr_code = get_bits(gbc, 2);
|
||||
if(hdr->sr_code == 3)
|
||||
return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
|
||||
|
||||
frame_size_code = get_bits(gbc, 6);
|
||||
if(frame_size_code > 37)
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
|
||||
|
||||
skip_bits(gbc, 5); // skip bsid, already got it
|
||||
|
||||
skip_bits(gbc, 3); // skip bitstream mode
|
||||
hdr->channel_mode = get_bits(gbc, 3);
|
||||
|
||||
if(hdr->channel_mode == AC3_CHMODE_STEREO) {
|
||||
skip_bits(gbc, 2); // skip dsurmod
|
||||
} else {
|
||||
if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO)
|
||||
hdr->center_mix_level = get_bits(gbc, 2);
|
||||
if(hdr->channel_mode & 4)
|
||||
hdr->surround_mix_level = get_bits(gbc, 2);
|
||||
}
|
||||
hdr->lfe_on = get_bits1(gbc);
|
||||
|
||||
hdr->sr_shift = FFMAX(hdr->bitstream_id, 8) - 8;
|
||||
hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code] >> hdr->sr_shift;
|
||||
hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift;
|
||||
hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
|
||||
hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2;
|
||||
hdr->frame_type = EAC3_FRAME_TYPE_AC3_CONVERT; //EAC3_FRAME_TYPE_INDEPENDENT;
|
||||
hdr->substreamid = 0;
|
||||
} else {
|
||||
/* Enhanced AC-3 */
|
||||
hdr->crc1 = 0;
|
||||
hdr->frame_type = get_bits(gbc, 2);
|
||||
if(hdr->frame_type == EAC3_FRAME_TYPE_RESERVED)
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
|
||||
|
||||
hdr->substreamid = get_bits(gbc, 3);
|
||||
|
||||
hdr->frame_size = (get_bits(gbc, 11) + 1) << 1;
|
||||
if(hdr->frame_size < AC3_HEADER_SIZE)
|
||||
return AAC_AC3_PARSE_ERROR_FRAME_SIZE;
|
||||
|
||||
hdr->sr_code = get_bits(gbc, 2);
|
||||
if (hdr->sr_code == 3) {
|
||||
int sr_code2 = get_bits(gbc, 2);
|
||||
if(sr_code2 == 3)
|
||||
return AAC_AC3_PARSE_ERROR_SAMPLE_RATE;
|
||||
hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2;
|
||||
hdr->sr_shift = 1;
|
||||
} else {
|
||||
hdr->num_blocks = eac3_blocks[get_bits(gbc, 2)];
|
||||
hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code];
|
||||
hdr->sr_shift = 0;
|
||||
}
|
||||
|
||||
hdr->channel_mode = get_bits(gbc, 3);
|
||||
hdr->lfe_on = get_bits1(gbc);
|
||||
|
||||
hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate /
|
||||
(hdr->num_blocks * 256.0));
|
||||
hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on;
|
||||
}
|
||||
hdr->channel_layout = ff_ac3_channel_layout_tab[hdr->channel_mode];
|
||||
if (hdr->lfe_on)
|
||||
hdr->channel_layout |= CH_LOW_FREQUENCY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr){
|
||||
int ret, i;
|
||||
ret = ff_ac3_parse_header(gbc, hdr);
|
||||
if(!ret){
|
||||
if(hdr->bitstream_id>10){
|
||||
/* Enhanced AC-3 */
|
||||
skip_bits(gbc, 5); // skip bitstream id
|
||||
|
||||
/* skip dialog normalization and compression gain */
|
||||
for (i = 0; i < (hdr->channel_mode ? 1 : 2); i++) {
|
||||
skip_bits(gbc, 5); // skip dialog normalization
|
||||
if (get_bits1(gbc)) {
|
||||
skip_bits(gbc, 8); //skip Compression gain word
|
||||
}
|
||||
}
|
||||
/* dependent stream channel map */
|
||||
if (hdr->frame_type == EAC3_FRAME_TYPE_DEPENDENT && get_bits1(gbc)) {
|
||||
hdr->channel_map = get_bits(gbc, 16); //custom channel map
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//default channel map based on acmod and lfeon
|
||||
hdr->channel_map = ff_eac3_default_chmap[hdr->channel_mode];
|
||||
if(hdr->lfe_on)
|
||||
hdr->channel_map |= AC3_CHMAP_LFE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
|
||||
int *need_next_header, int *new_frame_start)
|
||||
{
|
||||
int err;
|
||||
union {
|
||||
uint64_t u64;
|
||||
uint8_t u8[8];
|
||||
} tmp = { be2me_64(state) };
|
||||
AC3HeaderInfo hdr;
|
||||
GetBitContext gbc;
|
||||
|
||||
init_get_bits(&gbc, tmp.u8+8-AC3_HEADER_SIZE, 54);
|
||||
err = ff_ac3_parse_header(&gbc, &hdr);
|
||||
|
||||
if(err < 0)
|
||||
return 0;
|
||||
|
||||
hdr_info->sample_rate = hdr.sample_rate;
|
||||
hdr_info->bit_rate = hdr.bit_rate;
|
||||
hdr_info->channels = hdr.channels;
|
||||
hdr_info->channel_layout = hdr.channel_layout;
|
||||
hdr_info->samples = hdr.num_blocks * 256;
|
||||
if(hdr.bitstream_id>10)
|
||||
hdr_info->codec_id = CODEC_ID_EAC3;
|
||||
else if (hdr_info->codec_id == CODEC_ID_NONE)
|
||||
hdr_info->codec_id = CODEC_ID_AC3;
|
||||
|
||||
*need_next_header = (hdr.frame_type != EAC3_FRAME_TYPE_AC3_CONVERT);
|
||||
*new_frame_start = (hdr.frame_type != EAC3_FRAME_TYPE_DEPENDENT);
|
||||
return hdr.frame_size;
|
||||
}
|
||||
|
||||
static av_cold int ac3_parse_init(AVCodecParserContext *s1)
|
||||
{
|
||||
AACAC3ParseContext *s = s1->priv_data;
|
||||
s->header_size = AC3_HEADER_SIZE;
|
||||
s->sync = ac3_sync;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVCodecParser ac3_parser = {
|
||||
{ CODEC_ID_AC3, CODEC_ID_EAC3 },
|
||||
sizeof(AACAC3ParseContext),
|
||||
ac3_parse_init,
|
||||
ff_aac_ac3_parse,
|
||||
ff_parse_close,
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* AC-3 parser prototypes
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AC3_PARSER_H
|
||||
#define AVCODEC_AC3_PARSER_H
|
||||
|
||||
#include "ac3.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
/**
|
||||
* Parses AC-3 frame header.
|
||||
* Parses the header up to the lfeon element, which is the first 52 or 54 bits
|
||||
* depending on the audio coding mode.
|
||||
* @param gbc[in] BitContext containing the first 54 bits of the frame.
|
||||
* @param hdr[out] Pointer to struct where header info is written.
|
||||
* @return Returns 0 on success, -1 if there is a sync word mismatch,
|
||||
* -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate)
|
||||
* element is invalid, or -4 if the frmsizecod (bit rate) element is invalid.
|
||||
*/
|
||||
int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr);
|
||||
|
||||
/**
|
||||
* Parses AC-3 frame header and sets channel_map
|
||||
* Parses the header up to the lfeon (channel_map in E-AC-3)
|
||||
* element, which is the first 52, 54 or 104 bits depending
|
||||
* on the audio coding mode.
|
||||
* @param gbc[in] BitContext containing the first 54 bits of the frame.
|
||||
* @param hdr[out] Pointer to struct where header info is written.
|
||||
* @return value returned by ff_ac3_parse_header
|
||||
*/
|
||||
int ff_ac3_parse_header_full(GetBitContext *gbc, AC3HeaderInfo *hdr);
|
||||
|
||||
#endif /* AVCODEC_AC3_PARSER_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* Common code between the AC-3 and E-AC-3 decoders
|
||||
* Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* Common code between the AC-3 and E-AC-3 decoders.
|
||||
*
|
||||
* Summary of MDCT Coefficient Grouping:
|
||||
* The individual MDCT coefficient indices are often referred to in the
|
||||
* (E-)AC-3 specification as frequency bins. These bins are grouped together
|
||||
* into subbands of 12 coefficients each. The subbands are grouped together
|
||||
* into bands as defined in the bitstream by the band structures, which
|
||||
* determine the number of bands and the size of each band. The full spectrum
|
||||
* of 256 frequency bins is divided into 1 DC bin + 21 subbands = 253 bins.
|
||||
* This system of grouping coefficients is used for channel bandwidth, stereo
|
||||
* rematrixing, channel coupling, enhanced coupling, and spectral extension.
|
||||
*
|
||||
* +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
|
||||
* |1| |12| | [12|12|12|12] | | | | | | | | | | | | |3|
|
||||
* +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
|
||||
* ~~~ ~~~~ ~~~~~~~~~~~~~ ~~~
|
||||
* | | | |
|
||||
* | | | 3 unused frequency bins--+
|
||||
* | | |
|
||||
* | | +--1 band containing 4 subbands
|
||||
* | |
|
||||
* | +--1 subband of 12 frequency bins
|
||||
* |
|
||||
* +--DC frequency bin
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AC3DEC_H
|
||||
#define AVCODEC_AC3DEC_H
|
||||
|
||||
#include "libavutil/lfg.h"
|
||||
#include "ac3.h"
|
||||
#include "get_bits.h"
|
||||
#include "dsputil.h"
|
||||
#include "fft.h"
|
||||
|
||||
/* override ac3.h to include coupling channel */
|
||||
#undef AC3_MAX_CHANNELS
|
||||
#define AC3_MAX_CHANNELS 7
|
||||
#define CPL_CH 0
|
||||
|
||||
#define AC3_OUTPUT_LFEON 8
|
||||
|
||||
#define AC3_MAX_COEFS 256
|
||||
#define AC3_BLOCK_SIZE 256
|
||||
#define MAX_BLOCKS 6
|
||||
#define SPX_MAX_BANDS 17
|
||||
|
||||
typedef struct {
|
||||
AVCodecContext *avctx; ///< parent context
|
||||
GetBitContext gbc; ///< bitstream reader
|
||||
uint8_t *input_buffer; ///< temp buffer to prevent overread
|
||||
|
||||
///@defgroup bsi bit stream information
|
||||
///@{
|
||||
int frame_type; ///< frame type (strmtyp)
|
||||
int substreamid; ///< substream identification
|
||||
int frame_size; ///< current frame size, in bytes
|
||||
int bit_rate; ///< stream bit rate, in bits-per-second
|
||||
int sample_rate; ///< sample frequency, in Hz
|
||||
int num_blocks; ///< number of audio blocks
|
||||
int channel_mode; ///< channel mode (acmod)
|
||||
int channel_layout; ///< channel layout
|
||||
int lfe_on; ///< lfe channel in use
|
||||
int channel_map; ///< custom channel map
|
||||
int center_mix_level; ///< Center mix level index
|
||||
int surround_mix_level; ///< Surround mix level index
|
||||
int eac3; ///< indicates if current frame is E-AC-3
|
||||
///@}
|
||||
|
||||
///@defgroup audfrm frame syntax parameters
|
||||
int snr_offset_strategy; ///< SNR offset strategy (snroffststr)
|
||||
int block_switch_syntax; ///< block switch syntax enabled (blkswe)
|
||||
int dither_flag_syntax; ///< dither flag syntax enabled (dithflage)
|
||||
int bit_allocation_syntax; ///< bit allocation model syntax enabled (bamode)
|
||||
int fast_gain_syntax; ///< fast gain codes enabled (frmfgaincode)
|
||||
int dba_syntax; ///< delta bit allocation syntax enabled (dbaflde)
|
||||
int skip_syntax; ///< skip field syntax enabled (skipflde)
|
||||
///@}
|
||||
|
||||
///@defgroup cpl standard coupling
|
||||
int cpl_in_use[MAX_BLOCKS]; ///< coupling in use (cplinu)
|
||||
int cpl_strategy_exists[MAX_BLOCKS]; ///< coupling strategy exists (cplstre)
|
||||
int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
|
||||
int phase_flags_in_use; ///< phase flags in use (phsflginu)
|
||||
int phase_flags[18]; ///< phase flags (phsflg)
|
||||
int num_cpl_bands; ///< number of coupling bands (ncplbnd)
|
||||
uint8_t cpl_band_sizes[18]; ///< number of coeffs in each coupling band
|
||||
int firstchincpl; ///< first channel in coupling
|
||||
int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos)
|
||||
int cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates (cplco)
|
||||
///@}
|
||||
|
||||
///@defgroup spx spectral extension
|
||||
///@{
|
||||
int spx_in_use; ///< spectral extension in use (spxinu)
|
||||
uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx)
|
||||
int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod)
|
||||
int spx_src_start_freq; ///< spx start frequency bin
|
||||
int spx_dst_end_freq; ///< spx end frequency bin
|
||||
int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant)
|
||||
///< the copy region ends at the start of the spx region.
|
||||
int num_spx_bands; ///< number of spx bands (nspxbnds)
|
||||
uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band
|
||||
uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos)
|
||||
float spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact)
|
||||
float spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact)
|
||||
///@}
|
||||
|
||||
///@defgroup aht adaptive hybrid transform
|
||||
int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu)
|
||||
int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][MAX_BLOCKS]; ///< pre-IDCT mantissas
|
||||
///@}
|
||||
|
||||
///@defgroup channel channel
|
||||
int fbw_channels; ///< number of full-bandwidth channels
|
||||
int channels; ///< number of total channels
|
||||
int lfe_ch; ///< index of LFE channel
|
||||
float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients
|
||||
int downmixed; ///< indicates if coeffs are currently downmixed
|
||||
int output_mode; ///< output channel configuration
|
||||
int out_channels; ///< number of output channels
|
||||
///@}
|
||||
|
||||
///@defgroup dynrng dynamic range
|
||||
float dynamic_range[2]; ///< dynamic range
|
||||
///@}
|
||||
|
||||
///@defgroup bandwidth bandwidth
|
||||
int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant)
|
||||
int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant)
|
||||
///@}
|
||||
|
||||
///@defgroup rematrixing rematrixing
|
||||
int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd)
|
||||
int rematrixing_flags[4]; ///< rematrixing flags (rematflg)
|
||||
///@}
|
||||
|
||||
///@defgroup exponents exponents
|
||||
int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp)
|
||||
int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents
|
||||
int exp_strategy[MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr)
|
||||
///@}
|
||||
|
||||
///@defgroup bitalloc bit allocation
|
||||
AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters
|
||||
int first_cpl_leak; ///< first coupling leak state (firstcplleak)
|
||||
int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst)
|
||||
int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values/SMR's (fgain)
|
||||
uint8_t bap[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers
|
||||
int16_t psd[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents
|
||||
int16_t band_psd[AC3_MAX_CHANNELS][50]; ///< interpolated exponents
|
||||
int16_t mask[AC3_MAX_CHANNELS][50]; ///< masking curve values
|
||||
int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode
|
||||
int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments
|
||||
uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets
|
||||
uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths
|
||||
uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment
|
||||
///@}
|
||||
|
||||
///@defgroup dithering zero-mantissa dithering
|
||||
int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg)
|
||||
AVLFG dith_state; ///< for dither generation
|
||||
///@}
|
||||
|
||||
///@defgroup imdct IMDCT
|
||||
int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw)
|
||||
FFTContext imdct_512; ///< for 512 sample IMDCT
|
||||
FFTContext imdct_256; ///< for 256 sample IMDCT
|
||||
///@}
|
||||
|
||||
///@defgroup opt optimization
|
||||
DSPContext dsp; ///< for optimization
|
||||
float add_bias; ///< offset for float_to_int16 conversion
|
||||
float mul_bias; ///< scaling for float_to_int16 conversion
|
||||
///@}
|
||||
|
||||
///@defgroup arrays aligned arrays
|
||||
DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///> fixed-point transform coefficients
|
||||
DECLARE_ALIGNED(16, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients
|
||||
DECLARE_ALIGNED(16, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block
|
||||
DECLARE_ALIGNED(16, float, window)[AC3_BLOCK_SIZE]; ///< window coefficients
|
||||
DECLARE_ALIGNED(16, float, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing
|
||||
DECLARE_ALIGNED(16, float, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
|
||||
///@}
|
||||
} AC3DecodeContext;
|
||||
|
||||
/**
|
||||
* Parse the E-AC-3 frame header.
|
||||
* This parses both the bit stream info and audio frame header.
|
||||
*/
|
||||
int ff_eac3_parse_header(AC3DecodeContext *s);
|
||||
|
||||
/**
|
||||
* Decode mantissas in a single channel for the entire frame.
|
||||
* This is used when AHT mode is enabled.
|
||||
*/
|
||||
void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch);
|
||||
|
||||
void ff_ac3_downmix_c(float (*samples)[256], float (*matrix)[2],
|
||||
int out_ch, int in_ch, int len);
|
||||
|
||||
/**
|
||||
* Apply spectral extension to each channel by copying lower frequency
|
||||
* coefficients to higher frequency bins and applying side information to
|
||||
* approximate the original high frequency signal.
|
||||
*/
|
||||
void ff_eac3_apply_spectral_extension(AC3DecodeContext *s);
|
||||
|
||||
#endif /* AVCODEC_AC3DEC_H */
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* AC-3 and E-AC-3 decoder tables
|
||||
* Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* Tables taken directly from the AC-3 spec.
|
||||
*/
|
||||
|
||||
#include "ac3dec_data.h"
|
||||
#include "ac3.h"
|
||||
|
||||
/**
|
||||
* Table used to ungroup 3 values stored in 5 bits.
|
||||
* Used by bap=1 mantissas and GAQ.
|
||||
* ff_ac3_ungroup_3_in_5_bits_tab[i] = { i/9, (i%9)/3, (i%9)%3 }
|
||||
*/
|
||||
const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3] = {
|
||||
{ 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 2 }, { 0, 1, 0 },
|
||||
{ 0, 1, 1 }, { 0, 1, 2 }, { 0, 2, 0 }, { 0, 2, 1 },
|
||||
{ 0, 2, 2 }, { 1, 0, 0 }, { 1, 0, 1 }, { 1, 0, 2 },
|
||||
{ 1, 1, 0 }, { 1, 1, 1 }, { 1, 1, 2 }, { 1, 2, 0 },
|
||||
{ 1, 2, 1 }, { 1, 2, 2 }, { 2, 0, 0 }, { 2, 0, 1 },
|
||||
{ 2, 0, 2 }, { 2, 1, 0 }, { 2, 1, 1 }, { 2, 1, 2 },
|
||||
{ 2, 2, 0 }, { 2, 2, 1 }, { 2, 2, 2 }, { 3, 0, 0 },
|
||||
{ 3, 0, 1 }, { 3, 0, 2 }, { 3, 1, 0 }, { 3, 1, 1 }
|
||||
};
|
||||
|
||||
/**
|
||||
* Table of bin locations for rematrixing bands
|
||||
* reference: Section 7.5.2 Rematrixing : Frequency Band Definitions
|
||||
*/
|
||||
const uint8_t ff_ac3_rematrix_band_tab[5] = { 13, 25, 37, 61, 253 };
|
||||
|
||||
const uint8_t ff_eac3_hebap_tab[64] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 8,
|
||||
8, 8, 9, 9, 9, 10, 10, 10, 10, 11,
|
||||
11, 11, 11, 12, 12, 12, 12, 13, 13, 13,
|
||||
13, 14, 14, 14, 14, 15, 15, 15, 15, 16,
|
||||
16, 16, 16, 17, 17, 17, 17, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19,
|
||||
};
|
||||
|
||||
/**
|
||||
* Table E2.16 Default Coupling Banding Structure
|
||||
*/
|
||||
const uint8_t ff_eac3_default_cpl_band_struct[18] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 };
|
||||
|
||||
/**
|
||||
* Table E2.15 Default Spectral Extension Banding Structure
|
||||
*/
|
||||
const uint8_t ff_eac3_default_spx_band_struct[17] =
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* AC-3 and E-AC-3 decoder tables
|
||||
* Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AC3DEC_DATA_H
|
||||
#define AVCODEC_AC3DEC_DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
extern const uint8_t ff_ac3_ungroup_3_in_5_bits_tab[32][3];
|
||||
extern const uint8_t ff_ac3_rematrix_band_tab[5];
|
||||
|
||||
extern const uint8_t ff_eac3_hebap_tab[64];
|
||||
extern const uint8_t ff_eac3_default_cpl_band_struct[18];
|
||||
extern const uint8_t ff_eac3_default_spx_band_struct[17];
|
||||
|
||||
#endif /* AVCODEC_AC3DEC_DATA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,305 +0,0 @@
|
||||
/*
|
||||
* AC-3 tables
|
||||
* 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
|
||||
* tables taken directly from the AC-3 spec.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "ac3tab.h"
|
||||
|
||||
/**
|
||||
* Possible frame sizes.
|
||||
* from ATSC A/52 Table 5.18 Frame Size Code Table.
|
||||
*/
|
||||
const uint16_t ff_ac3_frame_size_tab[38][3] = {
|
||||
{ 64, 69, 96 },
|
||||
{ 64, 70, 96 },
|
||||
{ 80, 87, 120 },
|
||||
{ 80, 88, 120 },
|
||||
{ 96, 104, 144 },
|
||||
{ 96, 105, 144 },
|
||||
{ 112, 121, 168 },
|
||||
{ 112, 122, 168 },
|
||||
{ 128, 139, 192 },
|
||||
{ 128, 140, 192 },
|
||||
{ 160, 174, 240 },
|
||||
{ 160, 175, 240 },
|
||||
{ 192, 208, 288 },
|
||||
{ 192, 209, 288 },
|
||||
{ 224, 243, 336 },
|
||||
{ 224, 244, 336 },
|
||||
{ 256, 278, 384 },
|
||||
{ 256, 279, 384 },
|
||||
{ 320, 348, 480 },
|
||||
{ 320, 349, 480 },
|
||||
{ 384, 417, 576 },
|
||||
{ 384, 418, 576 },
|
||||
{ 448, 487, 672 },
|
||||
{ 448, 488, 672 },
|
||||
{ 512, 557, 768 },
|
||||
{ 512, 558, 768 },
|
||||
{ 640, 696, 960 },
|
||||
{ 640, 697, 960 },
|
||||
{ 768, 835, 1152 },
|
||||
{ 768, 836, 1152 },
|
||||
{ 896, 975, 1344 },
|
||||
{ 896, 976, 1344 },
|
||||
{ 1024, 1114, 1536 },
|
||||
{ 1024, 1115, 1536 },
|
||||
{ 1152, 1253, 1728 },
|
||||
{ 1152, 1254, 1728 },
|
||||
{ 1280, 1393, 1920 },
|
||||
{ 1280, 1394, 1920 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps audio coding mode (acmod) to number of full-bandwidth channels.
|
||||
* from ATSC A/52 Table 5.8 Audio Coding Mode
|
||||
*/
|
||||
const uint8_t ff_ac3_channels_tab[8] = {
|
||||
2, 1, 2, 3, 3, 4, 4, 5
|
||||
};
|
||||
|
||||
/**
|
||||
* Maps audio coding mode (acmod) to channel layout mask.
|
||||
*/
|
||||
const uint16_t ff_ac3_channel_layout_tab[8] = {
|
||||
CH_LAYOUT_STEREO,
|
||||
CH_LAYOUT_MONO,
|
||||
CH_LAYOUT_STEREO,
|
||||
CH_LAYOUT_SURROUND,
|
||||
CH_LAYOUT_2_1,
|
||||
CH_LAYOUT_4POINT0,
|
||||
CH_LAYOUT_2_2,
|
||||
CH_LAYOUT_5POINT0
|
||||
};
|
||||
|
||||
#define COMMON_CHANNEL_MAP \
|
||||
{ { 0, 1, }, { 0, 1, 2, } },\
|
||||
{ { 0, }, { 0, 1, } },\
|
||||
{ { 0, 1, }, { 0, 1, 2, } },\
|
||||
{ { 0, 2, 1, }, { 0, 2, 1, 3, } },\
|
||||
{ { 0, 1, 2, }, { 0, 1, 3, 2, } },\
|
||||
{ { 0, 2, 1, 3, }, { 0, 2, 1, 4, 3, } },
|
||||
|
||||
/**
|
||||
* Table to remap channels from SMPTE order to AC-3 order.
|
||||
* [channel_mode][lfe][ch]
|
||||
*/
|
||||
const uint8_t ff_ac3_enc_channel_map[8][2][6] = {
|
||||
COMMON_CHANNEL_MAP
|
||||
{ { 0, 1, 2, 3, }, { 0, 1, 3, 4, 2, } },
|
||||
{ { 0, 2, 1, 3, 4, }, { 0, 2, 1, 4, 5, 3 } },
|
||||
};
|
||||
|
||||
/**
|
||||
* Table to remap channels from from AC-3 order to SMPTE order.
|
||||
* [channel_mode][lfe][ch]
|
||||
*/
|
||||
const uint8_t ff_ac3_dec_channel_map[8][2][6] = {
|
||||
COMMON_CHANNEL_MAP
|
||||
{ { 0, 1, 2, 3, }, { 0, 1, 4, 2, 3, } },
|
||||
{ { 0, 2, 1, 3, 4, }, { 0, 2, 1, 5, 3, 4 } },
|
||||
};
|
||||
|
||||
/* possible frequencies */
|
||||
const uint16_t ff_ac3_sample_rate_tab[3] = { 48000, 44100, 32000 };
|
||||
|
||||
/* possible bitrates */
|
||||
const uint16_t ff_ac3_bitrate_tab[19] = {
|
||||
32, 40, 48, 56, 64, 80, 96, 112, 128,
|
||||
160, 192, 224, 256, 320, 384, 448, 512, 576, 640
|
||||
};
|
||||
|
||||
/* AC-3 MDCT window */
|
||||
|
||||
/* MDCT window */
|
||||
const int16_t ff_ac3_window[256] = {
|
||||
4, 7, 12, 16, 21, 28, 34, 42,
|
||||
51, 61, 72, 84, 97, 111, 127, 145,
|
||||
164, 184, 207, 231, 257, 285, 315, 347,
|
||||
382, 419, 458, 500, 544, 591, 641, 694,
|
||||
750, 810, 872, 937, 1007, 1079, 1155, 1235,
|
||||
1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016,
|
||||
2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076,
|
||||
3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444,
|
||||
4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127,
|
||||
6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112,
|
||||
8380, 8652, 8927, 9207, 9491, 9778,10069,10363,
|
||||
10660,10960,11264,11570,11879,12190,12504,12820,
|
||||
13138,13458,13780,14103,14427,14753,15079,15407,
|
||||
15735,16063,16392,16720,17049,17377,17705,18032,
|
||||
18358,18683,19007,19330,19651,19970,20287,20602,
|
||||
20914,21225,21532,21837,22139,22438,22733,23025,
|
||||
23314,23599,23880,24157,24430,24699,24964,25225,
|
||||
25481,25732,25979,26221,26459,26691,26919,27142,
|
||||
27359,27572,27780,27983,28180,28373,28560,28742,
|
||||
28919,29091,29258,29420,29577,29729,29876,30018,
|
||||
30155,30288,30415,30538,30657,30771,30880,30985,
|
||||
31086,31182,31274,31363,31447,31528,31605,31678,
|
||||
31747,31814,31877,31936,31993,32046,32097,32145,
|
||||
32190,32232,32272,32310,32345,32378,32409,32438,
|
||||
32465,32490,32513,32535,32556,32574,32592,32608,
|
||||
32623,32636,32649,32661,32671,32681,32690,32698,
|
||||
32705,32712,32718,32724,32729,32733,32737,32741,
|
||||
32744,32747,32750,32752,32754,32756,32757,32759,
|
||||
32760,32761,32762,32763,32764,32764,32765,32765,
|
||||
32766,32766,32766,32766,32767,32767,32767,32767,
|
||||
32767,32767,32767,32767,32767,32767,32767,32767,
|
||||
32767,32767,32767,32767,32767,32767,32767,32767,
|
||||
};
|
||||
|
||||
const uint8_t ff_ac3_log_add_tab[260]= {
|
||||
0x40,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,
|
||||
0x36,0x35,0x34,0x34,0x33,0x32,0x31,0x30,0x2f,0x2f,
|
||||
0x2e,0x2d,0x2c,0x2c,0x2b,0x2a,0x29,0x29,0x28,0x27,
|
||||
0x26,0x26,0x25,0x24,0x24,0x23,0x23,0x22,0x21,0x21,
|
||||
0x20,0x20,0x1f,0x1e,0x1e,0x1d,0x1d,0x1c,0x1c,0x1b,
|
||||
0x1b,0x1a,0x1a,0x19,0x19,0x18,0x18,0x17,0x17,0x16,
|
||||
0x16,0x15,0x15,0x15,0x14,0x14,0x13,0x13,0x13,0x12,
|
||||
0x12,0x12,0x11,0x11,0x11,0x10,0x10,0x10,0x0f,0x0f,
|
||||
0x0f,0x0e,0x0e,0x0e,0x0d,0x0d,0x0d,0x0d,0x0c,0x0c,
|
||||
0x0c,0x0c,0x0b,0x0b,0x0b,0x0b,0x0a,0x0a,0x0a,0x0a,
|
||||
0x0a,0x09,0x09,0x09,0x09,0x09,0x08,0x08,0x08,0x08,
|
||||
0x08,0x08,0x07,0x07,0x07,0x07,0x07,0x07,0x06,0x06,
|
||||
0x06,0x06,0x06,0x06,0x06,0x06,0x05,0x05,0x05,0x05,
|
||||
0x05,0x05,0x05,0x05,0x04,0x04,0x04,0x04,0x04,0x04,
|
||||
0x04,0x04,0x04,0x04,0x04,0x03,0x03,0x03,0x03,0x03,
|
||||
0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x02,
|
||||
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,
|
||||
0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
|
||||
const uint16_t ff_ac3_hearing_threshold_tab[50][3]= {
|
||||
{ 0x04d0,0x04f0,0x0580 },
|
||||
{ 0x04d0,0x04f0,0x0580 },
|
||||
{ 0x0440,0x0460,0x04b0 },
|
||||
{ 0x0400,0x0410,0x0450 },
|
||||
{ 0x03e0,0x03e0,0x0420 },
|
||||
{ 0x03c0,0x03d0,0x03f0 },
|
||||
{ 0x03b0,0x03c0,0x03e0 },
|
||||
{ 0x03b0,0x03b0,0x03d0 },
|
||||
{ 0x03a0,0x03b0,0x03c0 },
|
||||
{ 0x03a0,0x03a0,0x03b0 },
|
||||
{ 0x03a0,0x03a0,0x03b0 },
|
||||
{ 0x03a0,0x03a0,0x03b0 },
|
||||
{ 0x03a0,0x03a0,0x03a0 },
|
||||
{ 0x0390,0x03a0,0x03a0 },
|
||||
{ 0x0390,0x0390,0x03a0 },
|
||||
{ 0x0390,0x0390,0x03a0 },
|
||||
{ 0x0380,0x0390,0x03a0 },
|
||||
{ 0x0380,0x0380,0x03a0 },
|
||||
{ 0x0370,0x0380,0x03a0 },
|
||||
{ 0x0370,0x0380,0x03a0 },
|
||||
{ 0x0360,0x0370,0x0390 },
|
||||
{ 0x0360,0x0370,0x0390 },
|
||||
{ 0x0350,0x0360,0x0390 },
|
||||
{ 0x0350,0x0360,0x0390 },
|
||||
{ 0x0340,0x0350,0x0380 },
|
||||
{ 0x0340,0x0350,0x0380 },
|
||||
{ 0x0330,0x0340,0x0380 },
|
||||
{ 0x0320,0x0340,0x0370 },
|
||||
{ 0x0310,0x0320,0x0360 },
|
||||
{ 0x0300,0x0310,0x0350 },
|
||||
{ 0x02f0,0x0300,0x0340 },
|
||||
{ 0x02f0,0x02f0,0x0330 },
|
||||
{ 0x02f0,0x02f0,0x0320 },
|
||||
{ 0x02f0,0x02f0,0x0310 },
|
||||
{ 0x0300,0x02f0,0x0300 },
|
||||
{ 0x0310,0x0300,0x02f0 },
|
||||
{ 0x0340,0x0320,0x02f0 },
|
||||
{ 0x0390,0x0350,0x02f0 },
|
||||
{ 0x03e0,0x0390,0x0300 },
|
||||
{ 0x0420,0x03e0,0x0310 },
|
||||
{ 0x0460,0x0420,0x0330 },
|
||||
{ 0x0490,0x0450,0x0350 },
|
||||
{ 0x04a0,0x04a0,0x03c0 },
|
||||
{ 0x0460,0x0490,0x0410 },
|
||||
{ 0x0440,0x0460,0x0470 },
|
||||
{ 0x0440,0x0440,0x04a0 },
|
||||
{ 0x0520,0x0480,0x0460 },
|
||||
{ 0x0800,0x0630,0x0440 },
|
||||
{ 0x0840,0x0840,0x0450 },
|
||||
{ 0x0840,0x0840,0x04e0 },
|
||||
};
|
||||
|
||||
const uint8_t ff_ac3_bap_tab[64]= {
|
||||
0, 1, 1, 1, 1, 1, 2, 2, 3, 3,
|
||||
3, 4, 4, 5, 5, 6, 6, 6, 6, 7,
|
||||
7, 7, 7, 8, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
|
||||
12, 12, 12, 13, 13, 13, 13, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15,
|
||||
};
|
||||
|
||||
const uint8_t ff_ac3_slow_decay_tab[4]={
|
||||
0x0f, 0x11, 0x13, 0x15,
|
||||
};
|
||||
|
||||
const uint8_t ff_ac3_fast_decay_tab[4]={
|
||||
0x3f, 0x53, 0x67, 0x7b,
|
||||
};
|
||||
|
||||
const uint16_t ff_ac3_slow_gain_tab[4]= {
|
||||
0x540, 0x4d8, 0x478, 0x410,
|
||||
};
|
||||
|
||||
const uint16_t ff_ac3_db_per_bit_tab[4]= {
|
||||
0x000, 0x700, 0x900, 0xb00,
|
||||
};
|
||||
|
||||
const int16_t ff_ac3_floor_tab[8]= {
|
||||
0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800,
|
||||
};
|
||||
|
||||
const uint16_t ff_ac3_fast_gain_tab[8]= {
|
||||
0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400,
|
||||
};
|
||||
|
||||
const uint8_t ff_ac3_critical_band_size_tab[50]={
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
|
||||
3, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
|
||||
};
|
||||
/**
|
||||
* Default channel map for a dependent substream defined by acmod
|
||||
*/
|
||||
const uint16_t ff_eac3_default_chmap[8] = {
|
||||
AC3_CHMAP_L | AC3_CHMAP_R, // FIXME Ch1+Ch2
|
||||
AC3_CHMAP_C,
|
||||
AC3_CHMAP_L | AC3_CHMAP_R,
|
||||
AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R,
|
||||
AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_C_SUR,
|
||||
AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_C_SUR,
|
||||
AC3_CHMAP_L | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR,
|
||||
AC3_CHMAP_L | AC3_CHMAP_C | AC3_CHMAP_R | AC3_CHMAP_L_SUR | AC3_CHMAP_R_SUR
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* AC-3 tables
|
||||
* Copyright (c) 2000, 2001, 2002 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AC3TAB_H
|
||||
#define AVCODEC_AC3TAB_H
|
||||
|
||||
#include "libavutil/common.h"
|
||||
|
||||
extern const uint16_t ff_ac3_frame_size_tab[38][3];
|
||||
extern const uint8_t ff_ac3_channels_tab[8];
|
||||
extern const uint16_t ff_ac3_channel_layout_tab[8];
|
||||
extern const uint8_t ff_ac3_enc_channel_map[8][2][6];
|
||||
extern const uint8_t ff_ac3_dec_channel_map[8][2][6];
|
||||
extern const uint16_t ff_ac3_sample_rate_tab[3];
|
||||
extern const uint16_t ff_ac3_bitrate_tab[19];
|
||||
extern const int16_t ff_ac3_window[256];
|
||||
extern const uint8_t ff_ac3_log_add_tab[260];
|
||||
extern const uint16_t ff_ac3_hearing_threshold_tab[50][3];
|
||||
extern const uint8_t ff_ac3_bap_tab[64];
|
||||
extern const uint8_t ff_ac3_slow_decay_tab[4];
|
||||
extern const uint8_t ff_ac3_fast_decay_tab[4];
|
||||
extern const uint16_t ff_ac3_slow_gain_tab[4];
|
||||
extern const uint16_t ff_ac3_db_per_bit_tab[4];
|
||||
extern const int16_t ff_ac3_floor_tab[8];
|
||||
extern const uint16_t ff_ac3_fast_gain_tab[8];
|
||||
extern const uint8_t ff_ac3_critical_band_size_tab[50];
|
||||
extern const uint16_t ff_eac3_default_chmap[8];
|
||||
|
||||
/** Custom channel map locations bitmask
|
||||
* Other channels described in documentation:
|
||||
* Lc/Rc pair, Lrs/Rrs pair, Ts, Lsd/Rsd pair,
|
||||
* Lw/Rw pair, Lvh/Rvh pair, Cvh, Reserved, LFE2
|
||||
*/
|
||||
enum CustomChannelMapLocation{
|
||||
AC3_CHMAP_L= 1<<(15-0),
|
||||
AC3_CHMAP_C= 1<<(15-1),
|
||||
AC3_CHMAP_R= 1<<(15-2),
|
||||
AC3_CHMAP_L_SUR= 1<<(15-3),
|
||||
AC3_CHMAP_R_SUR = 1<<(15-4),
|
||||
AC3_CHMAP_C_SUR= 1<<(15-7),
|
||||
AC3_CHMAP_LFE = 1<<(15-15)
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_AC3TAB_H */
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* 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(frac_pos >= 0 && frac_pos < 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];
|
||||
}
|
||||
if (av_clip_int16(v >> 15) != (v >> 15))
|
||||
av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n");
|
||||
out[n] = v >> 15;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_acelp_interpolatef(float *out, const float *in,
|
||||
const float *filter_coeffs, int precision,
|
||||
int frac_pos, int filter_length, int length)
|
||||
{
|
||||
int n, i;
|
||||
|
||||
for (n = 0; n < length; n++) {
|
||||
int idx = 0;
|
||||
float v = 0;
|
||||
|
||||
for (i = 0; i < filter_length;) {
|
||||
v += in[n + i] * filter_coeffs[idx + frac_pos];
|
||||
idx += precision;
|
||||
i++;
|
||||
v += in[n - i] * filter_coeffs[idx - frac_pos];
|
||||
}
|
||||
out[n] = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
tmp += (hpf_f[1]* -7667LL) >> 13;
|
||||
tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]);
|
||||
|
||||
/* With "+0x800" rounding, clipping is needed
|
||||
for ALGTHM and SPEECH tests. */
|
||||
out[i] = av_clip_int16((tmp + 0x800) >> 12);
|
||||
|
||||
hpf_f[1] = hpf_f[0];
|
||||
hpf_f[0] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_acelp_apply_order_2_transfer_function(float *out, const float *in,
|
||||
const float zero_coeffs[2],
|
||||
const float pole_coeffs[2],
|
||||
float gain, float mem[2], int n)
|
||||
{
|
||||
int i;
|
||||
float tmp;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
tmp = gain * in[i] - pole_coeffs[0] * mem[0] - pole_coeffs[1] * mem[1];
|
||||
out[i] = tmp + zero_coeffs[0] * mem[0] + zero_coeffs[1] * mem[1];
|
||||
|
||||
mem[1] = mem[0];
|
||||
mem[0] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_tilt_compensation(float *mem, float tilt, float *samples, int size)
|
||||
{
|
||||
float new_tilt_mem = samples[size - 1];
|
||||
int i;
|
||||
|
||||
for (i = size - 1; i > 0; i--)
|
||||
samples[i] -= tilt * samples[i - 1];
|
||||
|
||||
samples[0] -= tilt * *mem;
|
||||
*mem = new_tilt_mem;
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ACELP_FILTERS_H
|
||||
#define AVCODEC_ACELP_FILTERS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* low-pass Finite Impulse Response filter coefficients.
|
||||
*
|
||||
* Hamming windowed sinc filter with cutoff freq 3/40 of the sampling freq,
|
||||
* the coefficients are scaled by 2^15.
|
||||
* This array only contains the right half of the filter.
|
||||
* This filter is likely identical to the one used in G.729, though this
|
||||
* could not be determined from the original comments with certainity.
|
||||
*/
|
||||
extern const int16_t ff_acelp_interp_filter[61];
|
||||
|
||||
/**
|
||||
* Generic FIR interpolation routine.
|
||||
* @param out [out] buffer for interpolated data
|
||||
* @param in input data
|
||||
* @param filter_coeffs interpolation filter coefficients (0.15)
|
||||
* @param precision sub sample factor, that is the precision of the position
|
||||
* @param frac_pos fractional part of position [0..precision-1]
|
||||
* @param filter_length filter length
|
||||
* @param length length of output
|
||||
*
|
||||
* filter_coeffs contains coefficients of the right half of the symmetric
|
||||
* interpolation filter. filter_coeffs[0] should the central (unpaired) coefficient.
|
||||
* See ff_acelp_interp_filter for an example.
|
||||
*
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Floating point version of ff_acelp_interpolate()
|
||||
*/
|
||||
void ff_acelp_interpolatef(float *out, const float *in,
|
||||
const float *filter_coeffs, int precision,
|
||||
int frac_pos, int filter_length, int length);
|
||||
|
||||
|
||||
/**
|
||||
* high-pass filtering and upscaling (4.2.5 of G.729).
|
||||
* @param out [out] output buffer for filtered speech data
|
||||
* @param hpf_f [in/out] past filtered data from previous (2 items long)
|
||||
* frames (-0x20000000 <= (14.13) < 0x20000000)
|
||||
* @param in speech data to process
|
||||
* @param length input data size
|
||||
*
|
||||
* out[i] = 0.93980581 * in[i] - 1.8795834 * in[i-1] + 0.93980581 * in[i-2] +
|
||||
* 1.9330735 * out[i-1] - 0.93589199 * out[i-2]
|
||||
*
|
||||
* The filter has a cut-off frequency of 1/80 of the sampling freq
|
||||
*
|
||||
* @note Two items before the top of the out buffer must contain two items from the
|
||||
* tail of the previous subframe.
|
||||
*
|
||||
* @remark It is safe to pass the same array in in and out parameters.
|
||||
*
|
||||
* @remark AMR uses mostly the same filter (cut-off frequency 60Hz, same formula,
|
||||
* but constants differs in 5th sign after comma). Fortunately in
|
||||
* fixed-point all coefficients are the same as in G.729. Thus this
|
||||
* routine can be used for the fixed-point AMR decoder, too.
|
||||
*/
|
||||
void ff_acelp_high_pass_filter(int16_t* out, int hpf_f[2],
|
||||
const int16_t* in, int length);
|
||||
|
||||
/**
|
||||
* Apply an order 2 rational transfer function in-place.
|
||||
*
|
||||
* @param out output buffer for filtered speech samples
|
||||
* @param in input buffer containing speech data (may be the same as out)
|
||||
* @param zero_coeffs z^-1 and z^-2 coefficients of the numerator
|
||||
* @param pole_coeffs z^-1 and z^-2 coefficients of the denominator
|
||||
* @param gain scale factor for final output
|
||||
* @param mem intermediate values used by filter (should be 0 initially)
|
||||
* @param n number of samples
|
||||
*/
|
||||
void ff_acelp_apply_order_2_transfer_function(float *out, const float *in,
|
||||
const float zero_coeffs[2],
|
||||
const float pole_coeffs[2],
|
||||
float gain,
|
||||
float mem[2], int n);
|
||||
|
||||
/**
|
||||
* Apply tilt compensation filter, 1 - tilt * z-1.
|
||||
*
|
||||
* @param mem pointer to the filter's state (one single float)
|
||||
* @param tilt tilt factor
|
||||
* @param samples array where the filter is applied
|
||||
* @param size the size of the samples array
|
||||
*/
|
||||
void ff_tilt_compensation(float *mem, float tilt, float *samples, int size);
|
||||
|
||||
|
||||
#endif /* AVCODEC_ACELP_FILTERS_H */
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* 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 "dsputil.h"
|
||||
#include "acelp_pitch_delay.h"
|
||||
#include "celp_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(
|
||||
DSPContext *dsp,
|
||||
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(dsp->scalarproduct_int16(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(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0));
|
||||
return mr_energy >> 12;
|
||||
#endif
|
||||
}
|
||||
|
||||
float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
|
||||
float *prediction_error, float energy_mean,
|
||||
const float *pred_table)
|
||||
{
|
||||
// Equations 66-69:
|
||||
// ^g_c = ^gamma_gc * 100.05 (predicted dB + mean dB - dB of fixed vector)
|
||||
// Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
|
||||
float val = fixed_gain_factor *
|
||||
exp2f(M_LOG2_10 * 0.05 *
|
||||
(ff_dot_productf(pred_table, prediction_error, 4) +
|
||||
energy_mean)) /
|
||||
sqrtf(fixed_mean_energy);
|
||||
|
||||
// update quantified prediction error energy history
|
||||
memmove(&prediction_error[0], &prediction_error[1],
|
||||
3 * sizeof(prediction_error[0]));
|
||||
prediction_error[3] = 20.0 * log10f(fixed_gain_factor);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
|
||||
const int prev_lag_int, const int subframe,
|
||||
int third_as_first, int resolution)
|
||||
{
|
||||
/* Note n * 10923 >> 15 is floor(x/3) for 0 <= n <= 32767 */
|
||||
if (subframe == 0 || (subframe == 2 && third_as_first)) {
|
||||
|
||||
if (pitch_index < 197)
|
||||
pitch_index += 59;
|
||||
else
|
||||
pitch_index = 3 * pitch_index - 335;
|
||||
|
||||
} else {
|
||||
if (resolution == 4) {
|
||||
int search_range_min = av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
|
||||
PITCH_DELAY_MAX - 9);
|
||||
|
||||
// decoding with 4-bit resolution
|
||||
if (pitch_index < 4) {
|
||||
// integer only precision for [search_range_min, search_range_min+3]
|
||||
pitch_index = 3 * (pitch_index + search_range_min) + 1;
|
||||
} else if (pitch_index < 12) {
|
||||
// 1/3 fractional precision for [search_range_min+3 1/3, search_range_min+5 2/3]
|
||||
pitch_index += 3 * search_range_min + 7;
|
||||
} else {
|
||||
// integer only precision for [search_range_min+6, search_range_min+9]
|
||||
pitch_index = 3 * (pitch_index + search_range_min - 6) + 1;
|
||||
}
|
||||
} else {
|
||||
// decoding with 5 or 6 bit resolution, 1/3 fractional precision
|
||||
pitch_index--;
|
||||
|
||||
if (resolution == 5) {
|
||||
pitch_index += 3 * av_clip(prev_lag_int - 10, PITCH_DELAY_MIN,
|
||||
PITCH_DELAY_MAX - 19);
|
||||
} else
|
||||
pitch_index += 3 * av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
|
||||
PITCH_DELAY_MAX - 9);
|
||||
}
|
||||
}
|
||||
*lag_int = pitch_index * 10923 >> 15;
|
||||
*lag_frac = pitch_index - 3 * *lag_int - 1;
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ACELP_PITCH_DELAY_H
|
||||
#define AVCODEC_ACELP_PITCH_DELAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "dsputil.h"
|
||||
|
||||
#define PITCH_DELAY_MIN 20
|
||||
#define PITCH_DELAY_MAX 143
|
||||
|
||||
/**
|
||||
* \brief Decode pitch delay of the first subframe encoded by 8 bits with 1/3
|
||||
* resolution.
|
||||
* \param ac_index adaptive codebook index (8 bits)
|
||||
*
|
||||
* \return pitch delay in 1/3 units
|
||||
*
|
||||
* Pitch delay is coded:
|
||||
* with 1/3 resolution, 19 < pitch_delay < 85
|
||||
* integers only, 85 <= pitch_delay <= 143
|
||||
*/
|
||||
int ff_acelp_decode_8bit_to_1st_delay3(int ac_index);
|
||||
|
||||
/**
|
||||
* \brief Decode pitch delay of the second subframe encoded by 5 or 6 bits
|
||||
* with 1/3 precision.
|
||||
* \param ac_index adaptive codebook index (5 or 6 bits)
|
||||
* \param pitch_delay_min lower bound (integer) of pitch delay interval
|
||||
* for second subframe
|
||||
*
|
||||
* \return pitch delay in 1/3 units
|
||||
*
|
||||
* Pitch delay is coded:
|
||||
* with 1/3 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
|
||||
*
|
||||
* \remark The routine is used in G.729 @8k, AMR @10.2k, AMR @7.95k,
|
||||
* AMR @7.4k for the second subframe.
|
||||
*/
|
||||
int ff_acelp_decode_5_6_bit_to_2nd_delay3(
|
||||
int ac_index,
|
||||
int pitch_delay_min);
|
||||
|
||||
/**
|
||||
* \brief Decode pitch delay with 1/3 precision.
|
||||
* \param ac_index adaptive codebook index (4 bits)
|
||||
* \param pitch_delay_min lower bound (integer) of pitch delay interval for
|
||||
* second subframe
|
||||
*
|
||||
* \return pitch delay in 1/3 units
|
||||
*
|
||||
* Pitch delay is coded:
|
||||
* integers only, -6 < pitch_delay - int(prev_pitch_delay) <= -2
|
||||
* with 1/3 resolution, -2 < pitch_delay - int(prev_pitch_delay) < 1
|
||||
* integers only, 1 <= pitch_delay - int(prev_pitch_delay) < 5
|
||||
*
|
||||
* \remark The routine is used in G.729 @6.4k, AMR @6.7k, AMR @5.9k,
|
||||
* AMR @5.15k, AMR @4.75k for the second subframe.
|
||||
*/
|
||||
int ff_acelp_decode_4bit_to_2nd_delay3(
|
||||
int ac_index,
|
||||
int pitch_delay_min);
|
||||
|
||||
/**
|
||||
* \brief Decode pitch delay of the first subframe encoded by 9 bits
|
||||
* with 1/6 precision.
|
||||
* \param ac_index adaptive codebook index (9 bits)
|
||||
* \param pitch_delay_min lower bound (integer) of pitch delay interval for
|
||||
* second subframe
|
||||
*
|
||||
* \return pitch delay in 1/6 units
|
||||
*
|
||||
* Pitch delay is coded:
|
||||
* with 1/6 resolution, 17 < pitch_delay < 95
|
||||
* integers only, 95 <= pitch_delay <= 143
|
||||
*
|
||||
* \remark The routine is used in AMR @12.2k for the first and third subframes.
|
||||
*/
|
||||
int ff_acelp_decode_9bit_to_1st_delay6(int ac_index);
|
||||
|
||||
/**
|
||||
* \brief Decode pitch delay of the second subframe encoded by 6 bits
|
||||
* with 1/6 precision.
|
||||
* \param ac_index adaptive codebook index (6 bits)
|
||||
* \param pitch_delay_min lower bound (integer) of pitch delay interval for
|
||||
* second subframe
|
||||
*
|
||||
* \return pitch delay in 1/6 units
|
||||
*
|
||||
* Pitch delay is coded:
|
||||
* with 1/6 resolution, -6 < pitch_delay - int(prev_pitch_delay) < 5
|
||||
*
|
||||
* \remark The routine is used in AMR @12.2k for the second and fourth subframes.
|
||||
*/
|
||||
int ff_acelp_decode_6bit_to_2nd_delay6(
|
||||
int ac_index,
|
||||
int pitch_delay_min);
|
||||
|
||||
/**
|
||||
* \brief Update past quantized energies
|
||||
* \param quant_energy [in/out] past quantized energies (5.10)
|
||||
* \param gain_corr_factor gain correction factor
|
||||
* \param log2_ma_pred_order log2() of MA prediction order
|
||||
* \param erasure frame erasure flag
|
||||
*
|
||||
* If frame erasure flag is not equal to zero, memory is updated with
|
||||
* averaged energy, attenuated by 4dB:
|
||||
* max(avg(quant_energy[i])-4, -14), i=0,ma_pred_order
|
||||
*
|
||||
* In normal mode memory is updated with
|
||||
* Er - Ep = 20 * log10(gain_corr_factor)
|
||||
*
|
||||
* \remark The routine is used in G.729 and AMR (all modes).
|
||||
*/
|
||||
void ff_acelp_update_past_gain(
|
||||
int16_t* quant_energy,
|
||||
int gain_corr_factor,
|
||||
int log2_ma_pred_order,
|
||||
int erasure);
|
||||
|
||||
/**
|
||||
* \brief Decode the adaptive codebook gain and add
|
||||
* correction (4.1.5 and 3.9.1 of G.729).
|
||||
* \param dsp initialized dsputil context
|
||||
* \param gain_corr_factor gain correction factor (2.13)
|
||||
* \param fc_v fixed-codebook vector (2.13)
|
||||
* \param mr_energy mean innovation energy and fixed-point correction (7.13)
|
||||
* \param quant_energy [in/out] past quantized energies (5.10)
|
||||
* \param subframe_size length of subframe
|
||||
* \param ma_pred_order MA prediction order
|
||||
*
|
||||
* \return quantized fixed-codebook gain (14.1)
|
||||
*
|
||||
* The routine implements equations 69, 66 and 71 of the G.729 specification (3.9.1)
|
||||
*
|
||||
* Em - mean innovation energy (dB, constant, depends on decoding algorithm)
|
||||
* Ep - mean-removed predicted energy (dB)
|
||||
* Er - mean-removed innovation energy (dB)
|
||||
* Ei - mean energy of the fixed-codebook contribution (dB)
|
||||
* N - subframe_size
|
||||
* M - MA (Moving Average) prediction order
|
||||
* gc - fixed-codebook gain
|
||||
* gc_p - predicted fixed-codebook gain
|
||||
*
|
||||
* Fixed codebook gain is computed using predicted gain gc_p and
|
||||
* correction factor gain_corr_factor as shown below:
|
||||
*
|
||||
* gc = gc_p * gain_corr_factor
|
||||
*
|
||||
* The predicted fixed codebook gain gc_p is found by predicting
|
||||
* the energy of the fixed-codebook contribution from the energy
|
||||
* of previous fixed-codebook contributions.
|
||||
*
|
||||
* mean = 1/N * sum(i,0,N){ fc_v[i] * fc_v[i] }
|
||||
*
|
||||
* Ei = 10log(mean)
|
||||
*
|
||||
* Er = 10log(1/N * gc^2 * mean) - Em = 20log(gc) + Ei - Em
|
||||
*
|
||||
* Replacing Er with Ep and gc with gc_p we will receive:
|
||||
*
|
||||
* Ep = 10log(1/N * gc_p^2 * mean) - Em = 20log(gc_p) + Ei - Em
|
||||
*
|
||||
* and from above:
|
||||
*
|
||||
* gc_p = 10^((Ep - Ei + Em) / 20)
|
||||
*
|
||||
* Ep is predicted using past energies and prediction coefficients:
|
||||
*
|
||||
* Ep = sum(i,0,M){ ma_prediction_coeff[i] * quant_energy[i] }
|
||||
*
|
||||
* gc_p in fixed-point arithmetic is calculated as following:
|
||||
*
|
||||
* mean = 1/N * sum(i,0,N){ (fc_v[i] / 2^13) * (fc_v[i] / 2^13) } =
|
||||
* = 1/N * sum(i,0,N) { fc_v[i] * fc_v[i] } / 2^26
|
||||
*
|
||||
* Ei = 10log(mean) = -10log(N) - 10log(2^26) +
|
||||
* + 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
|
||||
*
|
||||
* Ep - Ei + Em = Ep + Em + 10log(N) + 10log(2^26) -
|
||||
* - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] }) =
|
||||
* = Ep + mr_energy - 10log(sum(i,0,N) { fc_v[i] * fc_v[i] })
|
||||
*
|
||||
* gc_p = 10 ^ ((Ep - Ei + Em) / 20) =
|
||||
* = 2 ^ (3.3219 * (Ep - Ei + Em) / 20) = 2 ^ (0.166 * (Ep - Ei + Em))
|
||||
*
|
||||
* where
|
||||
*
|
||||
* mr_energy = Em + 10log(N) + 10log(2^26)
|
||||
*
|
||||
* \remark The routine is used in G.729 and AMR (all modes).
|
||||
*/
|
||||
int16_t ff_acelp_decode_gain_code(
|
||||
DSPContext *dsp,
|
||||
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 max_pred_order);
|
||||
|
||||
/**
|
||||
* Calculate fixed gain (part of section 6.1.3 of AMR spec)
|
||||
*
|
||||
* @param fixed_gain_factor gain correction factor
|
||||
* @param fixed_energy decoded algebraic codebook vector energy
|
||||
* @param prediction_error vector of the quantified predictor errors of
|
||||
* the four previous subframes. It is updated by this function.
|
||||
* @param energy_mean desired mean innovation energy
|
||||
* @param pred_table table of four moving average coefficients
|
||||
*/
|
||||
float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
|
||||
float *prediction_error, float energy_mean,
|
||||
const float *pred_table);
|
||||
|
||||
|
||||
/**
|
||||
* Decode the adaptive codebook index to the integer and fractional parts
|
||||
* of the pitch lag for one subframe at 1/3 fractional precision.
|
||||
*
|
||||
* The choice of pitch lag is described in 3GPP TS 26.090 section 5.6.1.
|
||||
*
|
||||
* @param lag_int integer part of pitch lag of the current subframe
|
||||
* @param lag_frac fractional part of pitch lag of the current subframe
|
||||
* @param pitch_index parsed adaptive codebook (pitch) index
|
||||
* @param prev_lag_int integer part of pitch lag for the previous subframe
|
||||
* @param subframe current subframe number
|
||||
* @param third_as_first treat the third frame the same way as the first
|
||||
*/
|
||||
void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
|
||||
const int prev_lag_int, const int subframe,
|
||||
int third_as_first, int resolution);
|
||||
|
||||
#endif /* AVCODEC_ACELP_PITCH_DELAY_H */
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* 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"
|
||||
#include "celp_math.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
|
||||
|
||||
const float ff_pow_0_7[10] = {
|
||||
0.700000, 0.490000, 0.343000, 0.240100, 0.168070,
|
||||
0.117649, 0.082354, 0.057648, 0.040354, 0.028248
|
||||
};
|
||||
|
||||
const float ff_pow_0_75[10] = {
|
||||
0.750000, 0.562500, 0.421875, 0.316406, 0.237305,
|
||||
0.177979, 0.133484, 0.100113, 0.075085, 0.056314
|
||||
};
|
||||
|
||||
const float ff_pow_0_55[10] = {
|
||||
0.550000, 0.302500, 0.166375, 0.091506, 0.050328,
|
||||
0.027681, 0.015224, 0.008373, 0.004605, 0.002533
|
||||
};
|
||||
|
||||
const float ff_b60_sinc[61] = {
|
||||
0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 ,
|
||||
0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 ,
|
||||
-0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 ,
|
||||
0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 ,
|
||||
-0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 ,
|
||||
0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 ,
|
||||
-0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 ,
|
||||
0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 ,
|
||||
-0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834,
|
||||
0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 ,
|
||||
0.
|
||||
};
|
||||
|
||||
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_decode_10_pulses_35bits(const int16_t *fixed_index,
|
||||
AMRFixed *fixed_sparse,
|
||||
const uint8_t *gray_decode,
|
||||
int half_pulse_count, int bits)
|
||||
{
|
||||
int i;
|
||||
int mask = (1 << bits) - 1;
|
||||
|
||||
fixed_sparse->no_repeat_mask = 0;
|
||||
fixed_sparse->n = 2 * half_pulse_count;
|
||||
for (i = 0; i < half_pulse_count; i++) {
|
||||
const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i;
|
||||
const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i;
|
||||
const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0;
|
||||
fixed_sparse->x[2*i+1] = pos1;
|
||||
fixed_sparse->x[2*i ] = pos2;
|
||||
fixed_sparse->y[2*i+1] = sign;
|
||||
fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
|
||||
float weight_coeff_a, float weight_coeff_b, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<length; i++)
|
||||
out[i] = weight_coeff_a * in_a[i]
|
||||
+ weight_coeff_b * in_b[i];
|
||||
}
|
||||
|
||||
void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
|
||||
int size, float alpha, float *gain_mem)
|
||||
{
|
||||
int i;
|
||||
float postfilter_energ = ff_dot_productf(in, in, size);
|
||||
float gain_scale_factor = 1.0;
|
||||
float mem = *gain_mem;
|
||||
|
||||
if (postfilter_energ)
|
||||
gain_scale_factor = sqrt(speech_energ / postfilter_energ);
|
||||
|
||||
gain_scale_factor *= 1.0 - alpha;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
mem = alpha * mem + gain_scale_factor;
|
||||
out[i] = in[i] * mem;
|
||||
}
|
||||
|
||||
*gain_mem = mem;
|
||||
}
|
||||
|
||||
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
|
||||
float sum_of_squares, const int n)
|
||||
{
|
||||
int i;
|
||||
float scalefactor = ff_dot_productf(in, in, n);
|
||||
if (scalefactor)
|
||||
scalefactor = sqrt(sum_of_squares / scalefactor);
|
||||
for (i = 0; i < n; i++)
|
||||
out[i] = in[i] * scalefactor;
|
||||
}
|
||||
|
||||
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < in->n; i++) {
|
||||
int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
|
||||
float y = in->y[i] * scale;
|
||||
|
||||
do {
|
||||
out[x] += y;
|
||||
y *= in->pitch_fac;
|
||||
x += in->pitch_lag;
|
||||
} while (x < size && repeats);
|
||||
}
|
||||
}
|
||||
|
||||
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i < in->n; i++) {
|
||||
int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
|
||||
|
||||
do {
|
||||
out[x] = 0.0;
|
||||
x += in->pitch_lag;
|
||||
} while (x < size && repeats);
|
||||
}
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ACELP_VECTORS_H
|
||||
#define AVCODEC_ACELP_VECTORS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Sparse representation for the algebraic codebook (fixed) vector */
|
||||
typedef struct {
|
||||
int n;
|
||||
int x[10];
|
||||
float y[10];
|
||||
int no_repeat_mask;
|
||||
int pitch_lag;
|
||||
float pitch_fac;
|
||||
} AMRFixed;
|
||||
|
||||
/**
|
||||
* Track|Pulse| Positions
|
||||
* -------------------------------------------------------------------------
|
||||
* 1 | 0 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75
|
||||
* -------------------------------------------------------------------------
|
||||
* 2 | 1 | 1, 6, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61, 66, 71, 76
|
||||
* -------------------------------------------------------------------------
|
||||
* 3 | 2 | 2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* Table contains only first the pulse indexes.
|
||||
*
|
||||
* Used in G.729 @8k, G.729 @4.4k, AMR @7.95k, AMR @7.40k
|
||||
*/
|
||||
extern const uint8_t ff_fc_4pulses_8bits_tracks_13[16];
|
||||
|
||||
/**
|
||||
* Track|Pulse| Positions
|
||||
* -------------------------------------------------------------------------
|
||||
* 4 | 3 | 3, 8, 13, 18, 23, 28, 33, 38, 43, 48, 53, 58, 63, 68, 73, 78
|
||||
* | | 4, 9, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 69, 74, 79
|
||||
* -------------------------------------------------------------------------
|
||||
*
|
||||
* @remark Track in the table should be read top-to-bottom, left-to-right.
|
||||
*
|
||||
* Used in G.729 @8k, G.729 @4.4k, AMR @7.95k, AMR @7.40k
|
||||
*/
|
||||
extern const uint8_t ff_fc_4pulses_8bits_track_4[32];
|
||||
|
||||
/**
|
||||
* Track|Pulse| Positions
|
||||
* -----------------------------------------
|
||||
* 1 | 0 | 1, 6, 11, 16, 21, 26, 31, 36
|
||||
* | | 3, 8, 13, 18, 23, 28, 33, 38
|
||||
* -----------------------------------------
|
||||
*
|
||||
* @remark Track in the table should be read top-to-bottom, left-to-right.
|
||||
*
|
||||
* @note (EE) Reference G.729D code also uses gray decoding for each
|
||||
* pulse index before looking up the value in the table.
|
||||
*
|
||||
* Used in G.729 @6.4k (with gray coding), AMR @5.9k (without gray coding)
|
||||
*/
|
||||
extern const uint8_t ff_fc_2pulses_9bits_track1[16];
|
||||
extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16];
|
||||
|
||||
/**
|
||||
* Track|Pulse| Positions
|
||||
* -----------------------------------------
|
||||
* 2 | 1 | 0, 7, 14, 20, 27, 34, 1, 21
|
||||
* | | 2, 9, 15, 22, 29, 35, 6, 26
|
||||
* | | 4,10, 17, 24, 30, 37, 11, 31
|
||||
* | | 5,12, 19, 25, 32, 39, 16, 36
|
||||
* -----------------------------------------
|
||||
*
|
||||
* @remark Track in the table should be read top-to-bottom, left-to-right.
|
||||
*
|
||||
* @note (EE.1) This table (from the reference code) does not comply with
|
||||
* the specification.
|
||||
* The specification contains the following table:
|
||||
*
|
||||
* Track|Pulse| Positions
|
||||
* -----------------------------------------
|
||||
* 2 | 1 | 0, 5, 10, 15, 20, 25, 30, 35
|
||||
* | | 1, 6, 11, 16, 21, 26, 31, 36
|
||||
* | | 2, 7, 12, 17, 22, 27, 32, 37
|
||||
* | | 4, 9, 14, 19, 24, 29, 34, 39
|
||||
*
|
||||
* -----------------------------------------
|
||||
*
|
||||
* @note (EE.2) Reference G.729D code also uses gray decoding for each
|
||||
* pulse index before looking up the value in the table.
|
||||
*
|
||||
* Used in G.729 @6.4k (with gray coding)
|
||||
*/
|
||||
extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32];
|
||||
|
||||
/**
|
||||
* b60 hamming windowed sinc function coefficients
|
||||
*/
|
||||
extern const float ff_b60_sinc[61];
|
||||
|
||||
/**
|
||||
* Table of pow(0.7,n)
|
||||
*/
|
||||
extern const float ff_pow_0_7[10];
|
||||
|
||||
/**
|
||||
* Table of pow(0.75,n)
|
||||
*/
|
||||
extern const float ff_pow_0_75[10];
|
||||
|
||||
/**
|
||||
* Table of pow(0.55,n)
|
||||
*/
|
||||
extern const float ff_pow_0_55[10];
|
||||
|
||||
/**
|
||||
* Decode fixed-codebook vector (3.8 and D.5.8 of G.729, 5.7.1 of AMR).
|
||||
* @param fc_v [out] decoded fixed codebook vector (2.13)
|
||||
* @param tab1 table used for first pulse_count pulses
|
||||
* @param tab2 table used for last pulse
|
||||
* @param pulse_indexes fixed codebook indexes
|
||||
* @param pulse_signs signs of the excitation pulses (0 bit value
|
||||
* means negative sign)
|
||||
* @param bits number of bits per one pulse index
|
||||
* @param pulse_count number of pulses decoded using first table
|
||||
* @param bits length of one pulse index in bits
|
||||
*
|
||||
* Used in G.729 @8k, G.729 @4.4k, G.729 @6.4k, AMR @7.95k, AMR @7.40k
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Decode the algebraic codebook index to pulse positions and signs and
|
||||
* construct the algebraic codebook vector for MODE_12k2.
|
||||
*
|
||||
* @note: The positions and signs are explicitly coded in MODE_12k2.
|
||||
*
|
||||
* @param fixed_index positions of the ten pulses
|
||||
* @param fixed_sparse pointer to the algebraic codebook vector
|
||||
* @param gray_decode gray decoding table
|
||||
* @param half_pulse_count number of couples of pulses
|
||||
* @param bits length of one pulse index in bits
|
||||
*/
|
||||
void ff_decode_10_pulses_35bits(const int16_t *fixed_index,
|
||||
AMRFixed *fixed_sparse,
|
||||
const uint8_t *gray_decode,
|
||||
int half_pulse_count, int bits);
|
||||
|
||||
|
||||
/**
|
||||
* weighted sum of two vectors with rounding.
|
||||
* @param out [out] result of addition
|
||||
* @param in_a first vector
|
||||
* @param in_b second vector
|
||||
* @param weight_coeff_a first vector weight coefficient
|
||||
* @param weight_coeff_a second vector weight coefficient
|
||||
* @param rounder this value will be added to the sum of the two vectors
|
||||
* @param shift result will be shifted to right by this value
|
||||
* @param length vectors length
|
||||
*
|
||||
* @note It is safe to pass the same buffer for out and in_a or in_b.
|
||||
*
|
||||
* out[i] = (in_a[i]*weight_a + in_b[i]*weight_b + rounder) >> shift
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* float implementation of weighted sum of two vectors.
|
||||
* @param out [out] result of addition
|
||||
* @param in_a first vector
|
||||
* @param in_b second vector
|
||||
* @param weight_coeff_a first vector weight coefficient
|
||||
* @param weight_coeff_a second vector weight coefficient
|
||||
* @param length vectors length
|
||||
*
|
||||
* @note It is safe to pass the same buffer for out and in_a or in_b.
|
||||
*/
|
||||
void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b,
|
||||
float weight_coeff_a, float weight_coeff_b,
|
||||
int length);
|
||||
|
||||
/**
|
||||
* Adaptive gain control (as used in AMR postfiltering)
|
||||
*
|
||||
* @param out output buffer for filtered speech data
|
||||
* @param in the input speech buffer (may be the same as out)
|
||||
* @param speech_energ input energy
|
||||
* @param size the input buffer size
|
||||
* @param alpha exponential filter factor
|
||||
* @param gain_mem a pointer to the filter memory (single float of size)
|
||||
*/
|
||||
void ff_adaptive_gain_control(float *out, const float *in, float speech_energ,
|
||||
int size, float alpha, float *gain_mem);
|
||||
|
||||
/**
|
||||
* Set the sum of squares of a signal by scaling
|
||||
*
|
||||
* @param out output samples
|
||||
* @param in input samples
|
||||
* @param sum_of_squares new sum of squares
|
||||
* @param n number of samples
|
||||
*
|
||||
* @note If the input is zero (or its energy underflows), the output is zero.
|
||||
* This is the behavior of AGC in the AMR reference decoder. The QCELP
|
||||
* reference decoder seems to have undefined behavior.
|
||||
*
|
||||
* TIA/EIA/IS-733 2.4.8.3-2/3/4/5, 2.4.8.6
|
||||
* 3GPP TS 26.090 6.1 (6)
|
||||
*/
|
||||
void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in,
|
||||
float sum_of_squares, const int n);
|
||||
|
||||
/**
|
||||
* Add fixed vector to an array from a sparse representation
|
||||
*
|
||||
* @param out fixed vector with pitch sharpening
|
||||
* @param in sparse fixed vector
|
||||
* @param scale number to multiply the fixed vector by
|
||||
* @param size the output vector size
|
||||
*/
|
||||
void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size);
|
||||
|
||||
/**
|
||||
* Clear array values set by set_fixed_vector
|
||||
*
|
||||
* @param out fixed vector to be cleared
|
||||
* @param in sparse fixed vector
|
||||
* @param size the output vector size
|
||||
*/
|
||||
void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size);
|
||||
|
||||
#endif /* AVCODEC_ACELP_VECTORS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* 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/
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ADX_H
|
||||
#define AVCODEC_ADX_H
|
||||
|
||||
typedef struct {
|
||||
int s1,s2;
|
||||
} PREV;
|
||||
|
||||
typedef struct {
|
||||
PREV prev[2];
|
||||
int header_parsed;
|
||||
unsigned char dec_temp[18*2];
|
||||
int in_temp;
|
||||
} ADXContext;
|
||||
|
||||
#define BASEVOL 0x4000
|
||||
#define SCALE1 0x7298
|
||||
#define SCALE2 0x3350
|
||||
|
||||
#endif /* AVCODEC_ADX_H */
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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 "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "adx.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* 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,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf0 = avpkt->data;
|
||||
int buf_size = avpkt->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",
|
||||
AVMEDIA_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 ADPCM"),
|
||||
};
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* 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 "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "adx.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* 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",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_ADPCM_ADX,
|
||||
sizeof(ADXContext),
|
||||
adx_encode_init,
|
||||
adx_encode_frame,
|
||||
adx_encode_close,
|
||||
NULL,
|
||||
.sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
|
||||
};
|
||||
@@ -1,712 +0,0 @@
|
||||
/*
|
||||
* 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 (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 "get_bits.h"
|
||||
#include "bytestream.h"
|
||||
#include "unary.h"
|
||||
#include "mathops.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];
|
||||
|
||||
int32_t *wasted_bits_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 */
|
||||
|
||||
int wasted_bits;
|
||||
} 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);
|
||||
|
||||
alac->wasted_bits_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 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] =
|
||||
sign_extend((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 = sign_extend(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 = sign_extend(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 void decorrelate_stereo_24(int32_t *buffer[MAX_CHANNELS],
|
||||
int32_t *buffer_out,
|
||||
int32_t *wasted_bits_buffer[MAX_CHANNELS],
|
||||
int wasted_bits,
|
||||
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;
|
||||
|
||||
if (wasted_bits) {
|
||||
b = (b << wasted_bits) | wasted_bits_buffer[0][i];
|
||||
a = (a << wasted_bits) | wasted_bits_buffer[1][i];
|
||||
}
|
||||
|
||||
buffer_out[i * numchannels] = b << 8;
|
||||
buffer_out[i * numchannels + 1] = a << 8;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < numsamples; i++) {
|
||||
int32_t left, right;
|
||||
|
||||
left = buffer[0][i];
|
||||
right = buffer[1][i];
|
||||
|
||||
if (wasted_bits) {
|
||||
left = (left << wasted_bits) | wasted_bits_buffer[0][i];
|
||||
right = (right << wasted_bits) | wasted_bits_buffer[1][i];
|
||||
}
|
||||
|
||||
buffer_out[i * numchannels] = left << 8;
|
||||
buffer_out[i * numchannels + 1] = right << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int alac_decode_frame(AVCodecContext *avctx,
|
||||
void *outbuffer, int *outputsize,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *inbuffer = avpkt->data;
|
||||
int input_buffer_size = avpkt->size;
|
||||
ALACContext *alac = avctx->priv_data;
|
||||
|
||||
int channels;
|
||||
unsigned int outputsamples;
|
||||
int hassize;
|
||||
unsigned int readsamplesize;
|
||||
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);
|
||||
|
||||
alac->wasted_bits = get_bits(&alac->gb, 2) << 3;
|
||||
|
||||
/* 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;
|
||||
|
||||
switch (alac->setinfo_sample_size) {
|
||||
case 16: avctx->sample_fmt = SAMPLE_FMT_S16;
|
||||
alac->bytespersample = channels << 1;
|
||||
break;
|
||||
case 24: avctx->sample_fmt = SAMPLE_FMT_S32;
|
||||
alac->bytespersample = channels << 2;
|
||||
break;
|
||||
default: av_log(avctx, AV_LOG_ERROR, "Sample depth %d is not supported.\n",
|
||||
alac->setinfo_sample_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 - (alac->wasted_bits) + 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 (alac->wasted_bits) {
|
||||
int i, ch;
|
||||
for (i = 0; i < outputsamples; i++) {
|
||||
for (ch = 0; ch < channels; ch++)
|
||||
alac->wasted_bits_buffer[ch][i] = get_bits(&alac->gb, alac->wasted_bits);
|
||||
}
|
||||
}
|
||||
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;
|
||||
if (alac->setinfo_sample_size <= 16) {
|
||||
for (i = 0; i < outputsamples; i++)
|
||||
for (chan = 0; chan < channels; chan++) {
|
||||
int32_t audiobits;
|
||||
|
||||
audiobits = get_sbits_long(&alac->gb, alac->setinfo_sample_size);
|
||||
|
||||
alac->outputsamples_buffer[chan][i] = audiobits;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < outputsamples; i++) {
|
||||
for (chan = 0; chan < channels; chan++) {
|
||||
alac->outputsamples_buffer[chan][i] = get_bits(&alac->gb,
|
||||
alac->setinfo_sample_size);
|
||||
alac->outputsamples_buffer[chan][i] = sign_extend(alac->outputsamples_buffer[chan][i],
|
||||
alac->setinfo_sample_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
alac->wasted_bits = 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*)outbuffer)[i] = alac->outputsamples_buffer[0][i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
if (channels == 2) {
|
||||
decorrelate_stereo_24(alac->outputsamples_buffer,
|
||||
outbuffer,
|
||||
alac->wasted_bits_buffer,
|
||||
alac->wasted_bits,
|
||||
alac->numchannels,
|
||||
outputsamples,
|
||||
interlacing_shift,
|
||||
interlacing_leftweight);
|
||||
} else {
|
||||
int i;
|
||||
for (i = 0; i < outputsamples; i++)
|
||||
((int32_t *)outbuffer)[i] = alac->outputsamples_buffer[0][i] << 8;
|
||||
}
|
||||
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;
|
||||
|
||||
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_freep(&alac->predicterror_buffer[chan]);
|
||||
av_freep(&alac->outputsamples_buffer[chan]);
|
||||
av_freep(&alac->wasted_bits_buffer[chan]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec alac_decoder = {
|
||||
"alac",
|
||||
AVMEDIA_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)"),
|
||||
};
|
||||
@@ -1,532 +0,0 @@
|
||||
/**
|
||||
* ALAC audio encoder
|
||||
* Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "put_bits.h"
|
||||
#include "dsputil.h"
|
||||
#include "lpc.h"
|
||||
#include "mathops.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_bits32(&s->pbctx, 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;
|
||||
|
||||
if (s->compression_level == 1) {
|
||||
s->lpc[ch].lpc_order = 6;
|
||||
s->lpc[ch].lpc_quant = 6;
|
||||
s->lpc[ch].lpc_coeff[0] = 160;
|
||||
s->lpc[ch].lpc_coeff[1] = -190;
|
||||
s->lpc[ch].lpc_coeff[2] = 170;
|
||||
s->lpc[ch].lpc_coeff[3] = -130;
|
||||
s->lpc[ch].lpc_coeff[4] = 80;
|
||||
s->lpc[ch].lpc_coeff[5] = -25;
|
||||
} else {
|
||||
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] = sign_extend(samples[lpc.lpc_order+1] - sum,
|
||||
s->write_sample_size);
|
||||
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;
|
||||
|
||||
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_coded_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 = 2;
|
||||
else
|
||||
s->compression_level = av_clip(avctx->compression_level, 0, 2);
|
||||
|
||||
// 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 = 8 + (avctx->frame_size*avctx->channels*avctx->bits_per_coded_sample>>3);
|
||||
|
||||
s->write_sample_size = avctx->bits_per_coded_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_coded_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_coded_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",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_ALAC,
|
||||
sizeof(AlacEncodeContext),
|
||||
alac_encode_init,
|
||||
alac_encode_frame,
|
||||
alac_encode_close,
|
||||
.capabilities = CODEC_CAP_SMALL_LAST_FRAME,
|
||||
.sample_fmts = (const enum SampleFormat[]){ SAMPLE_FMT_S16, SAMPLE_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ALAC (Apple Lossless Audio Codec)"),
|
||||
};
|
||||
@@ -1,385 +0,0 @@
|
||||
/*
|
||||
* Provides registration of all codecs, parsers and bitstream filters for libavcodec.
|
||||
* Copyright (c) 2002 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
|
||||
* Provides registration of all codecs, parsers and bitstream filters for libavcodec.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
#define REGISTER_HWACCEL(X,x) { \
|
||||
extern AVHWAccel x##_hwaccel; \
|
||||
if(CONFIG_##X##_HWACCEL) av_register_hwaccel(&x##_hwaccel); }
|
||||
|
||||
#define REGISTER_ENCODER(X,x) { \
|
||||
extern AVCodec x##_encoder; \
|
||||
if(CONFIG_##X##_ENCODER) avcodec_register(&x##_encoder); }
|
||||
#define REGISTER_DECODER(X,x) { \
|
||||
extern AVCodec x##_decoder; \
|
||||
if(CONFIG_##X##_DECODER) avcodec_register(&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(CONFIG_##X##_PARSER) av_register_codec_parser(&x##_parser); }
|
||||
#define REGISTER_BSF(X,x) { \
|
||||
extern AVBitStreamFilter x##_bsf; \
|
||||
if(CONFIG_##X##_BSF) av_register_bitstream_filter(&x##_bsf); }
|
||||
|
||||
void avcodec_register_all(void)
|
||||
{
|
||||
static int initialized;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = 1;
|
||||
|
||||
/* hardware accelerators */
|
||||
REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
|
||||
REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
|
||||
REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
|
||||
REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
|
||||
REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
|
||||
REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2);
|
||||
REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi);
|
||||
REGISTER_HWACCEL (WMV3_DXVA2, wmv3_dxva2);
|
||||
REGISTER_HWACCEL (WMV3_VAAPI, wmv3_vaapi);
|
||||
|
||||
/* video codecs */
|
||||
REGISTER_DECODER (AASC, aasc);
|
||||
REGISTER_DECODER (AMV, amv);
|
||||
REGISTER_DECODER (ANM, anm);
|
||||
REGISTER_ENCDEC (ASV1, asv1);
|
||||
REGISTER_ENCDEC (ASV2, asv2);
|
||||
REGISTER_DECODER (AURA, aura);
|
||||
REGISTER_DECODER (AURA2, aura2);
|
||||
REGISTER_DECODER (AVS, avs);
|
||||
REGISTER_DECODER (BETHSOFTVID, bethsoftvid);
|
||||
REGISTER_DECODER (BFI, bfi);
|
||||
REGISTER_DECODER (BINK, bink);
|
||||
REGISTER_ENCDEC (BMP, bmp);
|
||||
REGISTER_DECODER (C93, c93);
|
||||
REGISTER_DECODER (CAVS, cavs);
|
||||
REGISTER_DECODER (CDGRAPHICS, cdgraphics);
|
||||
REGISTER_DECODER (CINEPAK, cinepak);
|
||||
REGISTER_DECODER (CLJR, cljr);
|
||||
REGISTER_DECODER (CSCD, cscd);
|
||||
REGISTER_DECODER (CYUV, cyuv);
|
||||
REGISTER_ENCDEC (DNXHD, dnxhd);
|
||||
REGISTER_DECODER (DPX, dpx);
|
||||
REGISTER_DECODER (DSICINVIDEO, dsicinvideo);
|
||||
REGISTER_ENCDEC (DVVIDEO, dvvideo);
|
||||
REGISTER_DECODER (DXA, dxa);
|
||||
REGISTER_DECODER (EACMV, eacmv);
|
||||
REGISTER_DECODER (EAMAD, eamad);
|
||||
REGISTER_DECODER (EATGQ, eatgq);
|
||||
REGISTER_DECODER (EATGV, eatgv);
|
||||
REGISTER_DECODER (EATQI, eatqi);
|
||||
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_DECODER (FRWU, frwu);
|
||||
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_DECODER (H264_VDPAU, h264_vdpau);
|
||||
REGISTER_ENCDEC (HUFFYUV, huffyuv);
|
||||
REGISTER_DECODER (IDCIN, idcin);
|
||||
REGISTER_DECODER (IFF_BYTERUN1, iff_byterun1);
|
||||
REGISTER_DECODER (IFF_ILBM, iff_ilbm);
|
||||
REGISTER_DECODER (INDEO2, indeo2);
|
||||
REGISTER_DECODER (INDEO3, indeo3);
|
||||
REGISTER_DECODER (INDEO5, indeo5);
|
||||
REGISTER_DECODER (INTERPLAY_VIDEO, interplay_video);
|
||||
REGISTER_ENCDEC (JPEGLS, jpegls);
|
||||
REGISTER_DECODER (KGV1, kgv1);
|
||||
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 (MPEG4_VDPAU, mpeg4_vdpau);
|
||||
REGISTER_DECODER (MPEGVIDEO, mpegvideo);
|
||||
REGISTER_DECODER (MPEG_VDPAU, mpeg_vdpau);
|
||||
REGISTER_DECODER (MPEG1_VDPAU, mpeg1_vdpau);
|
||||
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_ENCDEC (PAM, pam);
|
||||
REGISTER_ENCDEC (PBM, pbm);
|
||||
REGISTER_ENCDEC (PCX, pcx);
|
||||
REGISTER_ENCDEC (PGM, pgm);
|
||||
REGISTER_ENCDEC (PGMYUV, pgmyuv);
|
||||
REGISTER_ENCDEC (PNG, png);
|
||||
REGISTER_ENCDEC (PPM, ppm);
|
||||
REGISTER_DECODER (PTX, ptx);
|
||||
REGISTER_DECODER (QDRAW, qdraw);
|
||||
REGISTER_DECODER (QPEG, qpeg);
|
||||
REGISTER_ENCDEC (QTRLE, qtrle);
|
||||
REGISTER_DECODER (R210, r210);
|
||||
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_DECODER (RV30, rv30);
|
||||
REGISTER_DECODER (RV40, rv40);
|
||||
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 (TMV, tmv);
|
||||
REGISTER_DECODER (TRUEMOTION1, truemotion1);
|
||||
REGISTER_DECODER (TRUEMOTION2, truemotion2);
|
||||
REGISTER_DECODER (TSCC, tscc);
|
||||
REGISTER_DECODER (TXD, txd);
|
||||
REGISTER_DECODER (ULTI, ulti);
|
||||
REGISTER_ENCDEC (V210, v210);
|
||||
REGISTER_DECODER (V210X, v210x);
|
||||
REGISTER_DECODER (VB, vb);
|
||||
REGISTER_DECODER (VC1, vc1);
|
||||
REGISTER_DECODER (VC1_VDPAU, vc1_vdpau);
|
||||
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 (WMV3_VDPAU, wmv3_vdpau);
|
||||
REGISTER_DECODER (WNV1, wnv1);
|
||||
REGISTER_DECODER (XAN_WC3, xan_wc3);
|
||||
REGISTER_DECODER (XL, xl);
|
||||
REGISTER_DECODER (YOP, yop);
|
||||
REGISTER_ENCDEC (ZLIB, zlib);
|
||||
REGISTER_ENCDEC (ZMBV, zmbv);
|
||||
|
||||
/* audio codecs */
|
||||
REGISTER_ENCDEC (AAC, aac);
|
||||
REGISTER_ENCDEC (AC3, ac3);
|
||||
REGISTER_ENCDEC (ALAC, alac);
|
||||
REGISTER_DECODER (ALS, als);
|
||||
REGISTER_DECODER (AMRNB, amrnb);
|
||||
REGISTER_DECODER (APE, ape);
|
||||
REGISTER_DECODER (ATRAC1, atrac1);
|
||||
REGISTER_DECODER (ATRAC3, atrac3);
|
||||
REGISTER_DECODER (BINKAUDIO_DCT, binkaudio_dct);
|
||||
REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
|
||||
REGISTER_DECODER (COOK, cook);
|
||||
REGISTER_DECODER (DCA, dca);
|
||||
REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
|
||||
REGISTER_DECODER (EAC3, eac3);
|
||||
REGISTER_ENCDEC (FLAC, flac);
|
||||
REGISTER_DECODER (IMC, imc);
|
||||
REGISTER_DECODER (MACE3, mace3);
|
||||
REGISTER_DECODER (MACE6, mace6);
|
||||
REGISTER_DECODER (MLP, mlp);
|
||||
REGISTER_DECODER (MP1, mp1);
|
||||
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_ENCDEC (NELLYMOSER, nellymoser);
|
||||
REGISTER_DECODER (QCELP, qcelp);
|
||||
REGISTER_DECODER (QDM2, qdm2);
|
||||
REGISTER_DECODER (RA_144, ra_144);
|
||||
REGISTER_DECODER (RA_288, ra_288);
|
||||
REGISTER_DECODER (SHORTEN, shorten);
|
||||
REGISTER_DECODER (SIPR, sipr);
|
||||
REGISTER_DECODER (SMACKAUD, smackaud);
|
||||
REGISTER_ENCDEC (SONIC, sonic);
|
||||
REGISTER_ENCODER (SONIC_LS, sonic_ls);
|
||||
REGISTER_DECODER (TRUEHD, truehd);
|
||||
REGISTER_DECODER (TRUESPEECH, truespeech);
|
||||
REGISTER_DECODER (TTA, tta);
|
||||
REGISTER_DECODER (TWINVQ, twinvq);
|
||||
REGISTER_DECODER (VMDAUDIO, vmdaudio);
|
||||
REGISTER_DECODER (VORBIS, vorbis);
|
||||
REGISTER_DECODER (WAVPACK, wavpack);
|
||||
REGISTER_DECODER (WMAPRO, wmapro);
|
||||
REGISTER_ENCDEC (WMAV1, wmav1);
|
||||
REGISTER_ENCDEC (WMAV2, wmav2);
|
||||
REGISTER_DECODER (WMAVOICE, wmavoice);
|
||||
REGISTER_DECODER (WS_SND1, ws_snd1);
|
||||
|
||||
/* PCM codecs */
|
||||
REGISTER_ENCDEC (PCM_ALAW, pcm_alaw);
|
||||
REGISTER_DECODER (PCM_BLURAY, pcm_bluray);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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_DECODER (ADPCM_IMA_ISS, adpcm_ima_iss);
|
||||
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);
|
||||
|
||||
/* subtitles */
|
||||
REGISTER_ENCDEC (DVBSUB, dvbsub);
|
||||
REGISTER_ENCDEC (DVDSUB, dvdsub);
|
||||
REGISTER_DECODER (PGSSUB, pgssub);
|
||||
REGISTER_ENCDEC (XSUB, xsub);
|
||||
|
||||
/* external libraries */
|
||||
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 (LIBOPENCORE_AMRNB, libopencore_amrnb);
|
||||
REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
|
||||
REGISTER_DECODER (LIBOPENJPEG, libopenjpeg);
|
||||
REGISTER_ENCDEC (LIBSCHROEDINGER, libschroedinger);
|
||||
REGISTER_DECODER (LIBSPEEX, libspeex);
|
||||
REGISTER_ENCODER (LIBTHEORA, libtheora);
|
||||
REGISTER_ENCODER (LIBVORBIS, libvorbis);
|
||||
REGISTER_ENCDEC (LIBVPX, libvpx);
|
||||
REGISTER_ENCODER (LIBX264, libx264);
|
||||
REGISTER_ENCODER (LIBXVID, libxvid);
|
||||
|
||||
/* parsers */
|
||||
REGISTER_PARSER (AAC, aac);
|
||||
REGISTER_PARSER (AC3, ac3);
|
||||
REGISTER_PARSER (CAVSVIDEO, cavsvideo);
|
||||
REGISTER_PARSER (DCA, dca);
|
||||
REGISTER_PARSER (DIRAC, dirac);
|
||||
REGISTER_PARSER (DNXHD, dnxhd);
|
||||
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);
|
||||
|
||||
/* bitstream filters */
|
||||
REGISTER_BSF (AAC_ADTSTOASC, aac_adtstoasc);
|
||||
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);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Deluxe Paint Animation decoder
|
||||
* Copyright (c) 2009 Peter Ross
|
||||
*
|
||||
* 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
|
||||
* Deluxe Paint Animation decoder
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
typedef struct AnmContext {
|
||||
AVFrame frame;
|
||||
int x; ///< x coordinate position
|
||||
} AnmContext;
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
AnmContext *s = avctx->priv_data;
|
||||
const uint8_t *buf;
|
||||
int i;
|
||||
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
|
||||
if (avctx->extradata_size != 16*8 + 4*256)
|
||||
return -1;
|
||||
|
||||
s->frame.reference = 1;
|
||||
if (avctx->get_buffer(avctx, &s->frame) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = avctx->extradata + 16*8;
|
||||
for (i = 0; i < 256; i++)
|
||||
((uint32_t*)s->frame.data[1])[i] = bytestream_get_le32(&buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform decode operation
|
||||
* @param dst, dst_end Destination image buffer
|
||||
* @param buf, buf_end Source buffer (optional, see below)
|
||||
* @param pixel Fill color (optional, see below)
|
||||
* @param count Pixel count
|
||||
* @param x Pointer to x-axis counter
|
||||
* @param width Image width
|
||||
* @param linesize Destination image buffer linesize
|
||||
* @return non-zero if destination buffer is exhausted
|
||||
*
|
||||
* a copy operation is achieved when 'buf' is set
|
||||
* a fill operation is acheived when 'buf' is null and pixel is >= 0
|
||||
* a skip operation is acheived when 'buf' is null and pixel is < 0
|
||||
*/
|
||||
static inline int op(uint8_t **dst, const uint8_t *dst_end,
|
||||
const uint8_t **buf, const uint8_t *buf_end,
|
||||
int pixel, int count,
|
||||
int *x, int width, int linesize)
|
||||
{
|
||||
int remaining = width - *x;
|
||||
while(count > 0) {
|
||||
int striplen = FFMIN(count, remaining);
|
||||
if (buf) {
|
||||
striplen = FFMIN(striplen, buf_end - *buf);
|
||||
memcpy(*dst, *buf, striplen);
|
||||
*buf += striplen;
|
||||
} else if (pixel >= 0)
|
||||
memset(*dst, pixel, striplen);
|
||||
*dst += striplen;
|
||||
remaining -= striplen;
|
||||
count -= striplen;
|
||||
if (remaining <= 0) {
|
||||
*dst += linesize - width;
|
||||
remaining = width;
|
||||
}
|
||||
if (linesize > 0) {
|
||||
if (*dst >= dst_end) goto exhausted;
|
||||
} else {
|
||||
if (*dst <= dst_end) goto exhausted;
|
||||
}
|
||||
}
|
||||
*x = width - remaining;
|
||||
return 0;
|
||||
|
||||
exhausted:
|
||||
*x = width - remaining;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
AnmContext *s = avctx->priv_data;
|
||||
const uint8_t *buf = avpkt->data;
|
||||
const int buf_size = avpkt->size;
|
||||
const uint8_t *buf_end = buf + buf_size;
|
||||
uint8_t *dst, *dst_end;
|
||||
int count;
|
||||
|
||||
if(avctx->reget_buffer(avctx, &s->frame) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
dst = s->frame.data[0];
|
||||
dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;
|
||||
|
||||
if (buf[0] != 0x42) {
|
||||
av_log_ask_for_sample(avctx, "unknown record type\n");
|
||||
return buf_size;
|
||||
}
|
||||
if (buf[1]) {
|
||||
av_log_ask_for_sample(avctx, "padding bytes not supported\n");
|
||||
return buf_size;
|
||||
}
|
||||
buf += 4;
|
||||
|
||||
s->x = 0;
|
||||
do {
|
||||
/* if statements are ordered by probability */
|
||||
#define OP(buf, pixel, count) \
|
||||
op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])
|
||||
|
||||
int type = bytestream_get_byte(&buf);
|
||||
count = type & 0x7F;
|
||||
type >>= 7;
|
||||
if (count) {
|
||||
if (OP(type ? NULL : &buf, -1, count)) break;
|
||||
} else if (!type) {
|
||||
int pixel;
|
||||
count = bytestream_get_byte(&buf); /* count==0 gives nop */
|
||||
pixel = bytestream_get_byte(&buf);
|
||||
if (OP(NULL, pixel, count)) break;
|
||||
} else {
|
||||
int pixel;
|
||||
type = bytestream_get_le16(&buf);
|
||||
count = type & 0x3FFF;
|
||||
type >>= 14;
|
||||
if (!count) {
|
||||
if (type == 0)
|
||||
break; // stop
|
||||
if (type == 2) {
|
||||
av_log_ask_for_sample(avctx, "unknown opcode");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pixel = type == 3 ? bytestream_get_byte(&buf) : -1;
|
||||
if (type == 1) count += 0x4000;
|
||||
if (OP(type == 2 ? &buf : NULL, pixel, count)) break;
|
||||
}
|
||||
} while (buf + 1 < buf_end);
|
||||
|
||||
*data_size = sizeof(AVFrame);
|
||||
*(AVFrame*)data = s->frame;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
AnmContext *s = avctx->priv_data;
|
||||
if (s->frame.data[0])
|
||||
avctx->release_buffer(avctx, &s->frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec anm_decoder = {
|
||||
"anm",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_ANM,
|
||||
sizeof(AnmContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"),
|
||||
};
|
||||
@@ -1,891 +0,0 @@
|
||||
/*
|
||||
* Monkey's Audio lossless audio decoder
|
||||
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
|
||||
* based upon libdemac from Dave Chapman.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#define ALT_BITSTREAM_READER_LE
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "get_bits.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* 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_coded_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;
|
||||
avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO;
|
||||
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]);
|
||||
|
||||
av_freep(&s->data);
|
||||
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 ctx decoder context
|
||||
* @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 ctx decoder context
|
||||
* @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 ctx decoder context
|
||||
* @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 ctx decoder context
|
||||
* @param counts probability range start position
|
||||
* @param counts_diff 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)
|
||||
{
|
||||
int lim = rice->k ? (1 << (rice->k + 4)) : 0;
|
||||
rice->ksum += ((x + 1) / 2) - ((rice->ksum + 16) >> 5);
|
||||
|
||||
if (rice->ksum < lim)
|
||||
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 < 3990) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (pivot < 0x10000) {
|
||||
base = range_decode_culfreq(ctx, pivot);
|
||||
range_decode_update(ctx, 1, base);
|
||||
} else {
|
||||
int base_hi = pivot, base_lo;
|
||||
int bbits = 0;
|
||||
|
||||
while (base_hi & ~0xFFFF) {
|
||||
base_hi >>= 1;
|
||||
bbits++;
|
||||
}
|
||||
base_hi = range_decode_culfreq(ctx, base_hi + 1);
|
||||
range_decode_update(ctx, 1, base_hi);
|
||||
base_lo = range_decode_culfreq(ctx, 1 << bbits);
|
||||
range_decode_update(ctx, 1, base_lo);
|
||||
|
||||
base = (base_hi << bbits) + base_lo;
|
||||
}
|
||||
|
||||
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 av_always_inline 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, sign;
|
||||
|
||||
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);
|
||||
|
||||
sign = APESIGN(decoded);
|
||||
p->coeffsA[filter][0] += p->buf[adaptA ] * sign;
|
||||
p->coeffsA[filter][1] += p->buf[adaptA - 1] * sign;
|
||||
p->coeffsA[filter][2] += p->buf[adaptA - 2] * sign;
|
||||
p->coeffsA[filter][3] += p->buf[adaptA - 3] * sign;
|
||||
p->coeffsB[filter][0] += p->buf[adaptB ] * sign;
|
||||
p->coeffsB[filter][1] += p->buf[adaptB - 1] * sign;
|
||||
p->coeffsB[filter][2] += p->buf[adaptB - 2] * sign;
|
||||
p->coeffsB[filter][3] += p->buf[adaptB - 3] * sign;
|
||||
p->coeffsB[filter][4] += p->buf[adaptB - 4] * sign;
|
||||
|
||||
return p->filterA[filter];
|
||||
}
|
||||
|
||||
static void predictor_decode_stereo(APEContext * ctx, int count)
|
||||
{
|
||||
APEPredictor *p = &ctx->predictor;
|
||||
int32_t *decoded0 = ctx->decoded0;
|
||||
int32_t *decoded1 = ctx->decoded1;
|
||||
|
||||
while (count--) {
|
||||
/* Predictor Y */
|
||||
*decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB);
|
||||
decoded0++;
|
||||
*decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB);
|
||||
decoded1++;
|
||||
|
||||
/* 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, sign;
|
||||
|
||||
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]);
|
||||
|
||||
sign = APESIGN(A);
|
||||
p->coeffsA[0][0] += p->buf[YADAPTCOEFFSA ] * sign;
|
||||
p->coeffsA[0][1] += p->buf[YADAPTCOEFFSA - 1] * sign;
|
||||
p->coeffsA[0][2] += p->buf[YADAPTCOEFFSA - 2] * sign;
|
||||
p->coeffsA[0][3] += p->buf[YADAPTCOEFFSA - 3] * sign;
|
||||
|
||||
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 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_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data));
|
||||
res = (res + (1 << (fracbits - 1))) >> fracbits;
|
||||
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 = FFABS(res);
|
||||
if (absres)
|
||||
*f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3));
|
||||
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,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->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);
|
||||
emms_c();
|
||||
|
||||
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",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_APE,
|
||||
sizeof(APEContext),
|
||||
ape_decode_init,
|
||||
NULL,
|
||||
ape_decode_close,
|
||||
ape_decode_frame,
|
||||
.capabilities = CODEC_CAP_SUBFRAMES,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"),
|
||||
};
|
||||
@@ -1,467 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* 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>
|
||||
|
||||
#ifdef HAVE_AV_CONFIG_H
|
||||
#undef HAVE_AV_CONFIG_H
|
||||
#endif
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
/*
|
||||
* Audio encoding example
|
||||
*/
|
||||
static 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 * M_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.
|
||||
*/
|
||||
static void audio_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int out_size, len;
|
||||
FILE *f, *outfile;
|
||||
uint8_t *outbuf;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
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 */
|
||||
avpkt.data = inbuf;
|
||||
avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (avpkt.size > 0) {
|
||||
out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
len = avcodec_decode_audio3(c, (short *)outbuf, &out_size, &avpkt);
|
||||
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);
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += len;
|
||||
if (avpkt.size < AUDIO_REFILL_THRESH) {
|
||||
/* Refill the input buffer, to avoid trying to decode
|
||||
* incomplete frames. Instead of this, one could also use
|
||||
* a parser, or use a proper container format through
|
||||
* libavformat. */
|
||||
memmove(inbuf, avpkt.data, avpkt.size);
|
||||
avpkt.data = inbuf;
|
||||
len = fread(avpkt.data + avpkt.size, 1,
|
||||
AUDIO_INBUF_SIZE - avpkt.size, f);
|
||||
if (len > 0)
|
||||
avpkt.size += len;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
free(outbuf);
|
||||
|
||||
avcodec_close(c);
|
||||
av_free(c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Video encoding example
|
||||
*/
|
||||
static 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
|
||||
*/
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static void video_decode_example(const char *outfilename, const char *filename)
|
||||
{
|
||||
AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int frame, got_picture, len;
|
||||
FILE *f;
|
||||
AVFrame *picture;
|
||||
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
|
||||
char buf[1024];
|
||||
AVPacket avpkt;
|
||||
|
||||
av_init_packet(&avpkt);
|
||||
|
||||
/* 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(;;) {
|
||||
avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (avpkt.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 */
|
||||
avpkt.data = inbuf;
|
||||
while (avpkt.size > 0) {
|
||||
len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
|
||||
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++;
|
||||
}
|
||||
avpkt.size -= len;
|
||||
avpkt.data += 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 */
|
||||
avpkt.data = NULL;
|
||||
avpkt.size = 0;
|
||||
len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
|
||||
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;
|
||||
}
|
||||
@@ -1,668 +0,0 @@
|
||||
/*
|
||||
* ASUS V1/V2 codec
|
||||
* Copyright (c) 2003 Michael Niedermayer
|
||||
*
|
||||
* 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
|
||||
* ASUS V1/V2 codec.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "put_bits.h"
|
||||
#include "dsputil.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;
|
||||
AVFrame picture;
|
||||
PutBitContext pb;
|
||||
GetBitContext gb;
|
||||
ScanTable scantable;
|
||||
int inv_qscale;
|
||||
int mb_width;
|
||||
int mb_height;
|
||||
int mb_width2;
|
||||
int mb_height2;
|
||||
DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
|
||||
uint16_t intra_matrix[64];
|
||||
int q_intra_matrix[64];
|
||||
uint8_t *bitstream_buffer;
|
||||
unsigned int bitstream_buffer_size;
|
||||
} ASV1Context;
|
||||
|
||||
static const uint8_t scantab[64]={
|
||||
0x00,0x08,0x01,0x09,0x10,0x18,0x11,0x19,
|
||||
0x02,0x0A,0x03,0x0B,0x12,0x1A,0x13,0x1B,
|
||||
0x04,0x0C,0x05,0x0D,0x20,0x28,0x21,0x29,
|
||||
0x06,0x0E,0x07,0x0F,0x14,0x1C,0x15,0x1D,
|
||||
0x22,0x2A,0x23,0x2B,0x30,0x38,0x31,0x39,
|
||||
0x16,0x1E,0x17,0x1F,0x24,0x2C,0x25,0x2D,
|
||||
0x32,0x3A,0x33,0x3B,0x26,0x2E,0x27,0x2F,
|
||||
0x34,0x3C,0x35,0x3D,0x36,0x3E,0x37,0x3F,
|
||||
};
|
||||
|
||||
|
||||
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},
|
||||
{0xC,5}, {0x4,5}, {0x8,5}, {0x3,2},
|
||||
{0xF,5}, //EOB
|
||||
};
|
||||
|
||||
static const uint8_t level_tab[7][2]={
|
||||
{3,4}, {3,3}, {3,2}, {0,3}, {2,2}, {2,3}, {2,4}
|
||||
};
|
||||
|
||||
static const uint8_t dc_ccp_tab[8][2]={
|
||||
{0x1,2}, {0xD,4}, {0xF,4}, {0xC,4},
|
||||
{0x5,3}, {0xE,4}, {0x4,3}, {0x0,2},
|
||||
};
|
||||
|
||||
static const uint8_t ac_ccp_tab[16][2]={
|
||||
{0x00,2}, {0x3B,6}, {0x0A,4}, {0x3A,6},
|
||||
{0x02,3}, {0x39,6}, {0x3C,6}, {0x38,6},
|
||||
{0x03,3}, {0x3D,6}, {0x08,4}, {0x1F,5},
|
||||
{0x09,4}, {0x0B,4}, {0x0D,4}, {0x0C,4},
|
||||
};
|
||||
|
||||
static const uint8_t asv2_level_tab[63][2]={
|
||||
{0x3F,10},{0x2F,10},{0x37,10},{0x27,10},{0x3B,10},{0x2B,10},{0x33,10},{0x23,10},
|
||||
{0x3D,10},{0x2D,10},{0x35,10},{0x25,10},{0x39,10},{0x29,10},{0x31,10},{0x21,10},
|
||||
{0x1F, 8},{0x17, 8},{0x1B, 8},{0x13, 8},{0x1D, 8},{0x15, 8},{0x19, 8},{0x11, 8},
|
||||
{0x0F, 6},{0x0B, 6},{0x0D, 6},{0x09, 6},
|
||||
{0x07, 4},{0x05, 4},
|
||||
{0x03, 2},
|
||||
{0x00, 5},
|
||||
{0x02, 2},
|
||||
{0x04, 4},{0x06, 4},
|
||||
{0x08, 6},{0x0C, 6},{0x0A, 6},{0x0E, 6},
|
||||
{0x10, 8},{0x18, 8},{0x14, 8},{0x1C, 8},{0x12, 8},{0x1A, 8},{0x16, 8},{0x1E, 8},
|
||||
{0x20,10},{0x30,10},{0x28,10},{0x38,10},{0x24,10},{0x34,10},{0x2C,10},{0x3C,10},
|
||||
{0x22,10},{0x32,10},{0x2A,10},{0x3A,10},{0x26,10},{0x36,10},{0x2E,10},{0x3E,10},
|
||||
};
|
||||
|
||||
|
||||
static VLC ccp_vlc;
|
||||
static VLC level_vlc;
|
||||
static VLC dc_ccp_vlc;
|
||||
static VLC ac_ccp_vlc;
|
||||
static VLC asv2_level_vlc;
|
||||
|
||||
static av_cold void init_vlcs(ASV1Context *a){
|
||||
static int done = 0;
|
||||
|
||||
if (!done) {
|
||||
done = 1;
|
||||
|
||||
INIT_VLC_STATIC(&ccp_vlc, VLC_BITS, 17,
|
||||
&ccp_tab[0][1], 2, 1,
|
||||
&ccp_tab[0][0], 2, 1, 64);
|
||||
INIT_VLC_STATIC(&dc_ccp_vlc, VLC_BITS, 8,
|
||||
&dc_ccp_tab[0][1], 2, 1,
|
||||
&dc_ccp_tab[0][0], 2, 1, 64);
|
||||
INIT_VLC_STATIC(&ac_ccp_vlc, VLC_BITS, 16,
|
||||
&ac_ccp_tab[0][1], 2, 1,
|
||||
&ac_ccp_tab[0][0], 2, 1, 64);
|
||||
INIT_VLC_STATIC(&level_vlc, VLC_BITS, 7,
|
||||
&level_tab[0][1], 2, 1,
|
||||
&level_tab[0][0], 2, 1, 64);
|
||||
INIT_VLC_STATIC(&asv2_level_vlc, ASV2_LEVEL_VLC_BITS, 63,
|
||||
&asv2_level_tab[0][1], 2, 1,
|
||||
&asv2_level_tab[0][0], 2, 1, 1024);
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME write a reversed bitstream reader to avoid the double reverse
|
||||
static inline int asv2_get_bits(GetBitContext *gb, int n){
|
||||
return av_reverse[ get_bits(gb, n) << (8-n) ];
|
||||
}
|
||||
|
||||
static inline void asv2_put_bits(PutBitContext *pb, int n, int v){
|
||||
put_bits(pb, n, av_reverse[ v << (8-n) ]);
|
||||
}
|
||||
|
||||
static inline int asv1_get_level(GetBitContext *gb){
|
||||
int code= get_vlc2(gb, level_vlc.table, VLC_BITS, 1);
|
||||
|
||||
if(code==3) return get_sbits(gb, 8);
|
||||
else return code - 3;
|
||||
}
|
||||
|
||||
static inline int asv2_get_level(GetBitContext *gb){
|
||||
int code= get_vlc2(gb, asv2_level_vlc.table, ASV2_LEVEL_VLC_BITS, 1);
|
||||
|
||||
if(code==31) return (int8_t)asv2_get_bits(gb, 8);
|
||||
else return code - 31;
|
||||
}
|
||||
|
||||
static inline void asv1_put_level(PutBitContext *pb, int level){
|
||||
unsigned int index= level + 3;
|
||||
|
||||
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_sbits(pb, 8, level);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void asv2_put_level(PutBitContext *pb, int level){
|
||||
unsigned int index= level + 31;
|
||||
|
||||
if(index <= 62) put_bits(pb, asv2_level_tab[index][1], asv2_level_tab[index][0]);
|
||||
else{
|
||||
put_bits(pb, asv2_level_tab[31][1], asv2_level_tab[31][0]);
|
||||
asv2_put_bits(pb, 8, level&0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if(ccp){
|
||||
if(ccp == 16) break;
|
||||
if(ccp < 0 || i>=10){
|
||||
av_log(a->avctx, AV_LOG_ERROR, "coded coeff pattern damaged\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
|
||||
if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
|
||||
if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
|
||||
if(ccp&1) block[a->scantable.permutated[4*i+3]]= (asv1_get_level(&a->gb) * a->intra_matrix[4*i+3])>>4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
if(ccp&2) block[a->scantable.permutated[2]]= (asv2_get_level(&a->gb) * a->intra_matrix[2])>>4;
|
||||
if(ccp&1) block[a->scantable.permutated[3]]= (asv2_get_level(&a->gb) * a->intra_matrix[3])>>4;
|
||||
}
|
||||
|
||||
for(i=1; i<count+1; i++){
|
||||
const int ccp= get_vlc2(&a->gb, ac_ccp_vlc.table, VLC_BITS, 1);
|
||||
|
||||
if(ccp){
|
||||
if(ccp&8) block[a->scantable.permutated[4*i+0]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+0])>>4;
|
||||
if(ccp&4) block[a->scantable.permutated[4*i+1]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+1])>>4;
|
||||
if(ccp&2) block[a->scantable.permutated[4*i+2]]= (asv2_get_level(&a->gb) * a->intra_matrix[4*i+2])>>4;
|
||||
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;
|
||||
|
||||
if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8;
|
||||
if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4;
|
||||
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;
|
||||
|
||||
if(ccp){
|
||||
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]);
|
||||
if(ccp&1) asv1_put_level(&a->pb, block[index + 9]);
|
||||
}else{
|
||||
nc_count++;
|
||||
}
|
||||
}
|
||||
put_bits(&a->pb, ccp_tab[16][1], ccp_tab[16][0]);
|
||||
}
|
||||
|
||||
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 )
|
||||
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;
|
||||
|
||||
if( (block[index + 0] = (block[index + 0]*a->q_intra_matrix[index + 0] + (1<<15))>>16) ) ccp |= 8;
|
||||
if( (block[index + 8] = (block[index + 8]*a->q_intra_matrix[index + 8] + (1<<15))>>16) ) ccp |= 4;
|
||||
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]);
|
||||
|
||||
if(ccp){
|
||||
if(ccp&8) asv2_put_level(&a->pb, block[index + 0]);
|
||||
if(ccp&4) asv2_put_level(&a->pb, block[index + 8]);
|
||||
if(ccp&2) asv2_put_level(&a->pb, block[index + 1]);
|
||||
if(ccp&1) asv2_put_level(&a->pb, block[index + 9]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
return -1;
|
||||
}
|
||||
}else{
|
||||
for(i=0; i<6; i++){
|
||||
if( asv2_decode_block(a, block[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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]);
|
||||
}else{
|
||||
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;
|
||||
|
||||
a->dsp.idct_put(dest_y , linesize, block[0]);
|
||||
a->dsp.idct_put(dest_y + 8, linesize, block[1]);
|
||||
a->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]);
|
||||
a->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
|
||||
|
||||
if(!(a->avctx->flags&CODEC_FLAG_GRAY)){
|
||||
a->dsp.idct_put(dest_cb, a->picture.linesize[1], block[4]);
|
||||
a->dsp.idct_put(dest_cr, a->picture.linesize[2], block[5]);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
a->dsp.get_pixels(block[0], ptr_y , linesize);
|
||||
a->dsp.get_pixels(block[1], ptr_y + 8, linesize);
|
||||
a->dsp.get_pixels(block[2], ptr_y + 8*linesize , linesize);
|
||||
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]);
|
||||
for(i=4; i<6; i++)
|
||||
a->dsp.fdct(block[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
ASV1Context * const a = avctx->priv_data;
|
||||
AVFrame *picture = data;
|
||||
AVFrame * const p= &a->picture;
|
||||
int mb_x, mb_y;
|
||||
|
||||
if(p->data[0])
|
||||
avctx->release_buffer(avctx, p);
|
||||
|
||||
p->reference= 0;
|
||||
if(avctx->get_buffer(avctx, p) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
p->pict_type= FF_I_TYPE;
|
||||
p->key_frame= 1;
|
||||
|
||||
av_fast_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!a->bitstream_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if(avctx->codec_id == CODEC_ID_ASV1)
|
||||
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]= av_reverse[ buf[i] ];
|
||||
}
|
||||
|
||||
init_get_bits(&a->gb, a->bitstream_buffer, buf_size*8);
|
||||
|
||||
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(a->mb_width2 != a->mb_width){
|
||||
mb_x= a->mb_width2;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(a->mb_height2 != a->mb_height){
|
||||
mb_y= a->mb_height2;
|
||||
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
|
||||
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++){
|
||||
printf("%d", get_bits1(&a->gb));
|
||||
}
|
||||
|
||||
for(i=0; i<s->avctx->extradata_size; i++){
|
||||
printf("%c\n", ((uint8_t*)s->avctx->extradata)[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
*picture= *(AVFrame*)&a->picture;
|
||||
*data_size = sizeof(AVPicture);
|
||||
|
||||
emms_c();
|
||||
|
||||
return (get_bits_count(&a->gb)+31)/32*4;
|
||||
}
|
||||
|
||||
#if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER
|
||||
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
|
||||
ASV1Context * const a = avctx->priv_data;
|
||||
AVFrame *pict = data;
|
||||
AVFrame * const p= &a->picture;
|
||||
int size;
|
||||
int mb_x, mb_y;
|
||||
|
||||
init_put_bits(&a->pb, buf, buf_size);
|
||||
|
||||
*p = *pict;
|
||||
p->pict_type= FF_I_TYPE;
|
||||
p->key_frame= 1;
|
||||
|
||||
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
|
||||
for(mb_x=0; mb_x<a->mb_width2; mb_x++){
|
||||
dct_get(a, mb_x, mb_y);
|
||||
encode_mb(a, a->block);
|
||||
}
|
||||
}
|
||||
|
||||
if(a->mb_width2 != a->mb_width){
|
||||
mb_x= a->mb_width2;
|
||||
for(mb_y=0; mb_y<a->mb_height2; mb_y++){
|
||||
dct_get(a, mb_x, mb_y);
|
||||
encode_mb(a, a->block);
|
||||
}
|
||||
}
|
||||
|
||||
if(a->mb_height2 != a->mb_height){
|
||||
mb_y= a->mb_height2;
|
||||
for(mb_x=0; mb_x<a->mb_width; mb_x++){
|
||||
dct_get(a, mb_x, mb_y);
|
||||
encode_mb(a, a->block);
|
||||
}
|
||||
}
|
||||
emms_c();
|
||||
|
||||
align_put_bits(&a->pb);
|
||||
while(put_bits_count(&a->pb)&31)
|
||||
put_bits(&a->pb, 8, 0);
|
||||
|
||||
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]= av_reverse[ buf[i] ];
|
||||
}
|
||||
|
||||
return size*4;
|
||||
}
|
||||
#endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */
|
||||
|
||||
static av_cold void common_init(AVCodecContext *avctx){
|
||||
ASV1Context * const a = avctx->priv_data;
|
||||
|
||||
dsputil_init(&a->dsp, avctx);
|
||||
|
||||
a->mb_width = (avctx->width + 15) / 16;
|
||||
a->mb_height = (avctx->height + 15) / 16;
|
||||
a->mb_width2 = (avctx->width + 0) / 16;
|
||||
a->mb_height2 = (avctx->height + 0) / 16;
|
||||
|
||||
avctx->coded_frame= &a->picture;
|
||||
a->avctx= avctx;
|
||||
}
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx){
|
||||
ASV1Context * const a = avctx->priv_data;
|
||||
AVFrame *p= &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= avctx->extradata[0];
|
||||
if(a->inv_qscale == 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "illegal qscale 0\n");
|
||||
if(avctx->codec_id == CODEC_ID_ASV1)
|
||||
a->inv_qscale= 6;
|
||||
else
|
||||
a->inv_qscale= 10;
|
||||
}
|
||||
|
||||
for(i=0; i<64; i++){
|
||||
int index= scantab[i];
|
||||
|
||||
a->intra_matrix[i]= 64*scale*ff_mpeg1_default_intra_matrix[index] / a->inv_qscale;
|
||||
}
|
||||
|
||||
p->qstride= a->mb_width;
|
||||
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;
|
||||
}
|
||||
|
||||
#if CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER
|
||||
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(AV_RL32("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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ASV1_ENCODER || CONFIG_ASV2_ENCODER */
|
||||
|
||||
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;
|
||||
|
||||
if(a->picture.data[0])
|
||||
avctx->release_buffer(avctx, &a->picture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec asv1_decoder = {
|
||||
"asv1",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_ASV1,
|
||||
sizeof(ASV1Context),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
|
||||
};
|
||||
|
||||
AVCodec asv2_decoder = {
|
||||
"asv2",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_ASV2,
|
||||
sizeof(ASV1Context),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
|
||||
};
|
||||
|
||||
#if CONFIG_ASV1_ENCODER
|
||||
AVCodec asv1_encoder = {
|
||||
"asv1",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_ASV1,
|
||||
sizeof(ASV1Context),
|
||||
encode_init,
|
||||
encode_frame,
|
||||
//encode_end,
|
||||
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
|
||||
.long_name= NULL_IF_CONFIG_SMALL("ASUS V1"),
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_ASV2_ENCODER
|
||||
AVCodec asv2_encoder = {
|
||||
"asv2",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_ASV2,
|
||||
sizeof(ASV1Context),
|
||||
encode_init,
|
||||
encode_frame,
|
||||
//encode_end,
|
||||
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
|
||||
.long_name= NULL_IF_CONFIG_SMALL("ASUS V2"),
|
||||
};
|
||||
#endif
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Atrac common functions
|
||||
* Copyright (c) 2006-2008 Maxim Poliakovski
|
||||
* Copyright (c) 2006-2008 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "atrac.h"
|
||||
|
||||
float sf_table[64];
|
||||
float qmf_window[48];
|
||||
|
||||
static const float qmf_48tap_half[24] = {
|
||||
-0.00001461907, -0.00009205479,-0.000056157569,0.00030117269,
|
||||
0.0002422519, -0.00085293897,-0.0005205574, 0.0020340169,
|
||||
0.00078333891, -0.0042153862, -0.00075614988, 0.0078402944,
|
||||
-0.000061169922,-0.01344162, 0.0024626821, 0.021736089,
|
||||
-0.007801671, -0.034090221, 0.01880949, 0.054326009,
|
||||
-0.043596379, -0.099384367, 0.13207909, 0.46424159
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate common tables
|
||||
*/
|
||||
|
||||
void atrac_generate_tables(void)
|
||||
{
|
||||
int i;
|
||||
float s;
|
||||
|
||||
/* Generate scale factors */
|
||||
if (!sf_table[63])
|
||||
for (i=0 ; i<64 ; i++)
|
||||
sf_table[i] = pow(2.0, (i - 15) / 3.0);
|
||||
|
||||
/* Generate the QMF window. */
|
||||
if (!qmf_window[47])
|
||||
for (i=0 ; i<24; i++) {
|
||||
s = qmf_48tap_half[i] * 2.0;
|
||||
qmf_window[i] = qmf_window[47 - i] = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Quadrature mirror synthesis filter.
|
||||
*
|
||||
* @param inlo lower part of spectrum
|
||||
* @param inhi higher part of spectrum
|
||||
* @param nIn size of spectrum buffer
|
||||
* @param pOut out buffer
|
||||
* @param delayBuf delayBuf buffer
|
||||
* @param temp temp buffer
|
||||
*/
|
||||
|
||||
|
||||
void atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp)
|
||||
{
|
||||
int i, j;
|
||||
float *p1, *p3;
|
||||
|
||||
memcpy(temp, delayBuf, 46*sizeof(float));
|
||||
|
||||
p3 = temp + 46;
|
||||
|
||||
/* loop1 */
|
||||
for(i=0; i<nIn; i+=2){
|
||||
p3[2*i+0] = inlo[i ] + inhi[i ];
|
||||
p3[2*i+1] = inlo[i ] - inhi[i ];
|
||||
p3[2*i+2] = inlo[i+1] + inhi[i+1];
|
||||
p3[2*i+3] = inlo[i+1] - inhi[i+1];
|
||||
}
|
||||
|
||||
/* loop2 */
|
||||
p1 = temp;
|
||||
for (j = nIn; j != 0; j--) {
|
||||
float s1 = 0.0;
|
||||
float s2 = 0.0;
|
||||
|
||||
for (i = 0; i < 48; i += 2) {
|
||||
s1 += p1[i] * qmf_window[i];
|
||||
s2 += p1[i+1] * qmf_window[i+1];
|
||||
}
|
||||
|
||||
pOut[0] = s2;
|
||||
pOut[1] = s1;
|
||||
|
||||
p1 += 2;
|
||||
pOut += 2;
|
||||
}
|
||||
|
||||
/* Update the delay buffer. */
|
||||
memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Atrac common data
|
||||
* Copyright (c) 2009 Maxim Poliakovski
|
||||
* Copyright (c) 2009 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
* Atrac common header
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ATRAC_H
|
||||
#define AVCODEC_ATRAC_H
|
||||
|
||||
|
||||
extern float sf_table[64];
|
||||
extern float qmf_window[48];
|
||||
|
||||
void atrac_generate_tables(void);
|
||||
void atrac_iqmf (float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp);
|
||||
|
||||
#endif /* AVCODEC_ATRAC_H */
|
||||
@@ -1,377 +0,0 @@
|
||||
/*
|
||||
* Atrac 1 compatible decoder
|
||||
* Copyright (c) 2009 Maxim Poliakovski
|
||||
* Copyright (c) 2009 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
* Atrac 1 compatible decoder.
|
||||
* This decoder handles raw ATRAC1 data and probably SDDS data.
|
||||
*/
|
||||
|
||||
/* Many thanks to Tim Craig for all the help! */
|
||||
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
#include "dsputil.h"
|
||||
#include "fft.h"
|
||||
|
||||
#include "atrac.h"
|
||||
#include "atrac1data.h"
|
||||
|
||||
#define AT1_MAX_BFU 52 ///< max number of block floating units in a sound unit
|
||||
#define AT1_SU_SIZE 212 ///< number of bytes in a sound unit
|
||||
#define AT1_SU_SAMPLES 512 ///< number of samples in a sound unit
|
||||
#define AT1_FRAME_SIZE AT1_SU_SIZE * 2
|
||||
#define AT1_SU_MAX_BITS AT1_SU_SIZE * 8
|
||||
#define AT1_MAX_CHANNELS 2
|
||||
|
||||
#define AT1_QMF_BANDS 3
|
||||
#define IDX_LOW_BAND 0
|
||||
#define IDX_MID_BAND 1
|
||||
#define IDX_HIGH_BAND 2
|
||||
|
||||
/**
|
||||
* Sound unit struct, one unit is used per channel
|
||||
*/
|
||||
typedef struct {
|
||||
int log2_block_count[AT1_QMF_BANDS]; ///< log2 number of blocks in a band
|
||||
int num_bfus; ///< number of Block Floating Units
|
||||
float* spectrum[2];
|
||||
DECLARE_ALIGNED(16, float, spec1)[AT1_SU_SAMPLES]; ///< mdct buffer
|
||||
DECLARE_ALIGNED(16, float, spec2)[AT1_SU_SAMPLES]; ///< mdct buffer
|
||||
DECLARE_ALIGNED(16, float, fst_qmf_delay)[46]; ///< delay line for the 1st stacked QMF filter
|
||||
DECLARE_ALIGNED(16, float, snd_qmf_delay)[46]; ///< delay line for the 2nd stacked QMF filter
|
||||
DECLARE_ALIGNED(16, float, last_qmf_delay)[256+23]; ///< delay line for the last stacked QMF filter
|
||||
} AT1SUCtx;
|
||||
|
||||
/**
|
||||
* The atrac1 context, holds all needed parameters for decoding
|
||||
*/
|
||||
typedef struct {
|
||||
AT1SUCtx SUs[AT1_MAX_CHANNELS]; ///< channel sound unit
|
||||
DECLARE_ALIGNED(16, float, spec)[AT1_SU_SAMPLES]; ///< the mdct spectrum buffer
|
||||
|
||||
DECLARE_ALIGNED(16, float, low)[256];
|
||||
DECLARE_ALIGNED(16, float, mid)[256];
|
||||
DECLARE_ALIGNED(16, float, high)[512];
|
||||
float* bands[3];
|
||||
DECLARE_ALIGNED(16, float, out_samples)[AT1_MAX_CHANNELS][AT1_SU_SAMPLES];
|
||||
FFTContext mdct_ctx[3];
|
||||
int channels;
|
||||
DSPContext dsp;
|
||||
} AT1Ctx;
|
||||
|
||||
/** size of the transform in samples in the long mode for each QMF band */
|
||||
static const uint16_t samples_per_band[3] = {128, 128, 256};
|
||||
static const uint8_t mdct_long_nbits[3] = {7, 7, 8};
|
||||
|
||||
|
||||
static void at1_imdct(AT1Ctx *q, float *spec, float *out, int nbits,
|
||||
int rev_spec)
|
||||
{
|
||||
FFTContext* mdct_context = &q->mdct_ctx[nbits - 5 - (nbits > 6)];
|
||||
int transf_size = 1 << nbits;
|
||||
|
||||
if (rev_spec) {
|
||||
int i;
|
||||
for (i = 0; i < transf_size / 2; i++)
|
||||
FFSWAP(float, spec[i], spec[transf_size - 1 - i]);
|
||||
}
|
||||
ff_imdct_half(mdct_context, out, spec);
|
||||
}
|
||||
|
||||
|
||||
static int at1_imdct_block(AT1SUCtx* su, AT1Ctx *q)
|
||||
{
|
||||
int band_num, band_samples, log2_block_count, nbits, num_blocks, block_size;
|
||||
unsigned int start_pos, ref_pos = 0, pos = 0;
|
||||
|
||||
for (band_num = 0; band_num < AT1_QMF_BANDS; band_num++) {
|
||||
float *prev_buf;
|
||||
int j;
|
||||
|
||||
band_samples = samples_per_band[band_num];
|
||||
log2_block_count = su->log2_block_count[band_num];
|
||||
|
||||
/* number of mdct blocks in the current QMF band: 1 - for long mode */
|
||||
/* 4 for short mode(low/middle bands) and 8 for short mode(high band)*/
|
||||
num_blocks = 1 << log2_block_count;
|
||||
|
||||
if (num_blocks == 1) {
|
||||
/* mdct block size in samples: 128 (long mode, low & mid bands), */
|
||||
/* 256 (long mode, high band) and 32 (short mode, all bands) */
|
||||
block_size = band_samples >> log2_block_count;
|
||||
|
||||
/* calc transform size in bits according to the block_size_mode */
|
||||
nbits = mdct_long_nbits[band_num] - log2_block_count;
|
||||
|
||||
if (nbits != 5 && nbits != 7 && nbits != 8)
|
||||
return -1;
|
||||
} else {
|
||||
block_size = 32;
|
||||
nbits = 5;
|
||||
}
|
||||
|
||||
start_pos = 0;
|
||||
prev_buf = &su->spectrum[1][ref_pos + band_samples - 16];
|
||||
for (j=0; j < num_blocks; j++) {
|
||||
at1_imdct(q, &q->spec[pos], &su->spectrum[0][ref_pos + start_pos], nbits, band_num);
|
||||
|
||||
/* overlap and window */
|
||||
q->dsp.vector_fmul_window(&q->bands[band_num][start_pos], prev_buf,
|
||||
&su->spectrum[0][ref_pos + start_pos], ff_sine_32, 0, 16);
|
||||
|
||||
prev_buf = &su->spectrum[0][ref_pos+start_pos + 16];
|
||||
start_pos += block_size;
|
||||
pos += block_size;
|
||||
}
|
||||
|
||||
if (num_blocks == 1)
|
||||
memcpy(q->bands[band_num] + 32, &su->spectrum[0][ref_pos + 16], 240 * sizeof(float));
|
||||
|
||||
ref_pos += band_samples;
|
||||
}
|
||||
|
||||
/* Swap buffers so the mdct overlap works */
|
||||
FFSWAP(float*, su->spectrum[0], su->spectrum[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the block size mode byte
|
||||
*/
|
||||
|
||||
static int at1_parse_bsm(GetBitContext* gb, int log2_block_cnt[AT1_QMF_BANDS])
|
||||
{
|
||||
int log2_block_count_tmp, i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* low and mid band */
|
||||
log2_block_count_tmp = get_bits(gb, 2);
|
||||
if (log2_block_count_tmp & 1)
|
||||
return -1;
|
||||
log2_block_cnt[i] = 2 - log2_block_count_tmp;
|
||||
}
|
||||
|
||||
/* high band */
|
||||
log2_block_count_tmp = get_bits(gb, 2);
|
||||
if (log2_block_count_tmp != 0 && log2_block_count_tmp != 3)
|
||||
return -1;
|
||||
log2_block_cnt[IDX_HIGH_BAND] = 3 - log2_block_count_tmp;
|
||||
|
||||
skip_bits(gb, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int at1_unpack_dequant(GetBitContext* gb, AT1SUCtx* su,
|
||||
float spec[AT1_SU_SAMPLES])
|
||||
{
|
||||
int bits_used, band_num, bfu_num, i;
|
||||
uint8_t idwls[AT1_MAX_BFU]; ///< the word length indexes for each BFU
|
||||
uint8_t idsfs[AT1_MAX_BFU]; ///< the scalefactor indexes for each BFU
|
||||
|
||||
/* parse the info byte (2nd byte) telling how much BFUs were coded */
|
||||
su->num_bfus = bfu_amount_tab1[get_bits(gb, 3)];
|
||||
|
||||
/* calc number of consumed bits:
|
||||
num_BFUs * (idwl(4bits) + idsf(6bits)) + log2_block_count(8bits) + info_byte(8bits)
|
||||
+ info_byte_copy(8bits) + log2_block_count_copy(8bits) */
|
||||
bits_used = su->num_bfus * 10 + 32 +
|
||||
bfu_amount_tab2[get_bits(gb, 2)] +
|
||||
(bfu_amount_tab3[get_bits(gb, 3)] << 1);
|
||||
|
||||
/* get word length index (idwl) for each BFU */
|
||||
for (i = 0; i < su->num_bfus; i++)
|
||||
idwls[i] = get_bits(gb, 4);
|
||||
|
||||
/* get scalefactor index (idsf) for each BFU */
|
||||
for (i = 0; i < su->num_bfus; i++)
|
||||
idsfs[i] = get_bits(gb, 6);
|
||||
|
||||
/* zero idwl/idsf for empty BFUs */
|
||||
for (i = su->num_bfus; i < AT1_MAX_BFU; i++)
|
||||
idwls[i] = idsfs[i] = 0;
|
||||
|
||||
/* read in the spectral data and reconstruct MDCT spectrum of this channel */
|
||||
for (band_num = 0; band_num < AT1_QMF_BANDS; band_num++) {
|
||||
for (bfu_num = bfu_bands_t[band_num]; bfu_num < bfu_bands_t[band_num+1]; bfu_num++) {
|
||||
int pos;
|
||||
|
||||
int num_specs = specs_per_bfu[bfu_num];
|
||||
int word_len = !!idwls[bfu_num] + idwls[bfu_num];
|
||||
float scale_factor = sf_table[idsfs[bfu_num]];
|
||||
bits_used += word_len * num_specs; /* add number of bits consumed by current BFU */
|
||||
|
||||
/* check for bitstream overflow */
|
||||
if (bits_used > AT1_SU_MAX_BITS)
|
||||
return -1;
|
||||
|
||||
/* get the position of the 1st spec according to the block size mode */
|
||||
pos = su->log2_block_count[band_num] ? bfu_start_short[bfu_num] : bfu_start_long[bfu_num];
|
||||
|
||||
if (word_len) {
|
||||
float max_quant = 1.0 / (float)((1 << (word_len - 1)) - 1);
|
||||
|
||||
for (i = 0; i < num_specs; i++) {
|
||||
/* read in a quantized spec and convert it to
|
||||
* signed int and then inverse quantization
|
||||
*/
|
||||
spec[pos+i] = get_sbits(gb, word_len) * scale_factor * max_quant;
|
||||
}
|
||||
} else { /* word_len = 0 -> empty BFU, zero all specs in the emty BFU */
|
||||
memset(&spec[pos], 0, num_specs * sizeof(float));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void at1_subband_synthesis(AT1Ctx *q, AT1SUCtx* su, float *pOut)
|
||||
{
|
||||
float temp[256];
|
||||
float iqmf_temp[512 + 46];
|
||||
|
||||
/* combine low and middle bands */
|
||||
atrac_iqmf(q->bands[0], q->bands[1], 128, temp, su->fst_qmf_delay, iqmf_temp);
|
||||
|
||||
/* delay the signal of the high band by 23 samples */
|
||||
memcpy( su->last_qmf_delay, &su->last_qmf_delay[256], sizeof(float) * 23);
|
||||
memcpy(&su->last_qmf_delay[23], q->bands[2], sizeof(float) * 256);
|
||||
|
||||
/* combine (low + middle) and high bands */
|
||||
atrac_iqmf(temp, su->last_qmf_delay, 256, pOut, su->snd_qmf_delay, iqmf_temp);
|
||||
}
|
||||
|
||||
|
||||
static int atrac1_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
AT1Ctx *q = avctx->priv_data;
|
||||
int ch, ret, i;
|
||||
GetBitContext gb;
|
||||
float* samples = data;
|
||||
|
||||
|
||||
if (buf_size < 212 * q->channels) {
|
||||
av_log(q,AV_LOG_ERROR,"Not enought data to decode!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ch = 0; ch < q->channels; ch++) {
|
||||
AT1SUCtx* su = &q->SUs[ch];
|
||||
|
||||
init_get_bits(&gb, &buf[212 * ch], 212 * 8);
|
||||
|
||||
/* parse block_size_mode, 1st byte */
|
||||
ret = at1_parse_bsm(&gb, su->log2_block_count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = at1_unpack_dequant(&gb, su, q->spec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = at1_imdct_block(su, q);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
at1_subband_synthesis(q, su, q->out_samples[ch]);
|
||||
}
|
||||
|
||||
/* interleave; FIXME, should create/use a DSP function */
|
||||
if (q->channels == 1) {
|
||||
/* mono */
|
||||
memcpy(samples, q->out_samples[0], AT1_SU_SAMPLES * 4);
|
||||
} else {
|
||||
/* stereo */
|
||||
for (i = 0; i < AT1_SU_SAMPLES; i++) {
|
||||
samples[i * 2] = q->out_samples[0][i];
|
||||
samples[i * 2 + 1] = q->out_samples[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
*data_size = q->channels * AT1_SU_SAMPLES * sizeof(*samples);
|
||||
return avctx->block_align;
|
||||
}
|
||||
|
||||
|
||||
static av_cold int atrac1_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
AT1Ctx *q = avctx->priv_data;
|
||||
|
||||
avctx->sample_fmt = SAMPLE_FMT_FLT;
|
||||
|
||||
q->channels = avctx->channels;
|
||||
|
||||
/* Init the mdct transforms */
|
||||
ff_mdct_init(&q->mdct_ctx[0], 6, 1, -1.0/ (1 << 15));
|
||||
ff_mdct_init(&q->mdct_ctx[1], 8, 1, -1.0/ (1 << 15));
|
||||
ff_mdct_init(&q->mdct_ctx[2], 9, 1, -1.0/ (1 << 15));
|
||||
|
||||
ff_init_ff_sine_windows(5);
|
||||
|
||||
atrac_generate_tables();
|
||||
|
||||
dsputil_init(&q->dsp, avctx);
|
||||
|
||||
q->bands[0] = q->low;
|
||||
q->bands[1] = q->mid;
|
||||
q->bands[2] = q->high;
|
||||
|
||||
/* Prepare the mdct overlap buffers */
|
||||
q->SUs[0].spectrum[0] = q->SUs[0].spec1;
|
||||
q->SUs[0].spectrum[1] = q->SUs[0].spec2;
|
||||
q->SUs[1].spectrum[0] = q->SUs[1].spec1;
|
||||
q->SUs[1].spectrum[1] = q->SUs[1].spec2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static av_cold int atrac1_decode_end(AVCodecContext * avctx) {
|
||||
AT1Ctx *q = avctx->priv_data;
|
||||
|
||||
ff_mdct_end(&q->mdct_ctx[0]);
|
||||
ff_mdct_end(&q->mdct_ctx[1]);
|
||||
ff_mdct_end(&q->mdct_ctx[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVCodec atrac1_decoder = {
|
||||
.name = "atrac1",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = CODEC_ID_ATRAC1,
|
||||
.priv_data_size = sizeof(AT1Ctx),
|
||||
.init = atrac1_decode_init,
|
||||
.close = atrac1_decode_end,
|
||||
.decode = atrac1_decode_frame,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Atrac 1 (Adaptive TRansform Acoustic Coding)"),
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Atrac 1 compatible decoder data
|
||||
* Copyright (c) 2009 Maxim Poliakovski
|
||||
* Copyright (c) 2009 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
* Atrac 1 compatible decoder data
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ATRAC1DATA_H
|
||||
#define AVCODEC_ATRAC1DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static const uint8_t bfu_amount_tab1[8] = {20, 28, 32, 36, 40, 44, 48, 52};
|
||||
static const uint8_t bfu_amount_tab2[4] = { 0, 112, 176, 208};
|
||||
static const uint8_t bfu_amount_tab3[8] = { 0, 24, 36, 48, 72, 108, 132, 156};
|
||||
|
||||
/** number of BFUs in each QMF band */
|
||||
static const uint8_t bfu_bands_t[4] = {0, 20, 36, 52};
|
||||
|
||||
/** number of spectral lines in each BFU
|
||||
* block floating unit = group of spectral frequencies having the
|
||||
* same quantization parameters like word length and scale factor
|
||||
*/
|
||||
static const uint8_t specs_per_bfu[52] = {
|
||||
8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, // low band
|
||||
6, 6, 6, 6, 7, 7, 7, 7, 9, 9, 9, 9, 10, 10, 10, 10, // midle band
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 20, 20, 20, 20, 20, 20, 20, 20 // high band
|
||||
};
|
||||
|
||||
/** start position of each BFU in the MDCT spectrum for the long mode */
|
||||
static const uint16_t bfu_start_long[52] = {
|
||||
0, 8, 16, 24, 32, 36, 40, 44, 48, 56, 64, 72, 80, 86, 92, 98, 104, 110, 116, 122,
|
||||
128, 134, 140, 146, 152, 159, 166, 173, 180, 189, 198, 207, 216, 226, 236, 246,
|
||||
256, 268, 280, 292, 304, 316, 328, 340, 352, 372, 392, 412, 432, 452, 472, 492,
|
||||
};
|
||||
|
||||
/** start position of each BFU in the MDCT spectrum for the short mode */
|
||||
static const uint16_t bfu_start_short[52] = {
|
||||
0, 32, 64, 96, 8, 40, 72, 104, 12, 44, 76, 108, 20, 52, 84, 116, 26, 58, 90, 122,
|
||||
128, 160, 192, 224, 134, 166, 198, 230, 141, 173, 205, 237, 150, 182, 214, 246,
|
||||
256, 288, 320, 352, 384, 416, 448, 480, 268, 300, 332, 364, 396, 428, 460, 492
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_ATRAC1DATA_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Atrac 3 compatible decoder data
|
||||
* Copyright (c) 2006-2007 Maxim Poliakovski
|
||||
* Copyright (c) 2006-2007 Benjamin Larsson
|
||||
*
|
||||
* 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
|
||||
* Atrac 3 AKA RealAudio 8 compatible decoder data
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_ATRAC3DATA_H
|
||||
#define AVCODEC_ATRAC3DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* VLC tables */
|
||||
|
||||
static const uint8_t huffcode1[9] = {
|
||||
0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits1[9] = {
|
||||
1,3,3,4,4,5,5,5,5,
|
||||
};
|
||||
|
||||
static const uint8_t huffcode2[5] = {
|
||||
0x0,0x4,0x5,0x6,0x7,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits2[5] = {
|
||||
1,3,3,3,3,
|
||||
};
|
||||
|
||||
static const uint8_t huffcode3[7] = {
|
||||
0x0,0x4,0x5,0xC,0xD,0xE,0xF,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits3[7] = {
|
||||
1,3,3,4,4,4,4,
|
||||
};
|
||||
|
||||
static const uint8_t huffcode4[9] = {
|
||||
0x0,0x4,0x5,0xC,0xD,0x1C,0x1D,0x1E,0x1F,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits4[9] = {
|
||||
1,3,3,4,4,5,5,5,5,
|
||||
};
|
||||
|
||||
static const uint8_t huffcode5[15] = {
|
||||
0x0,0x2,0x3,0x8,0x9,0xA,0xB,0x1C,0x1D,0x3C,0x3D,0x3E,0x3F,0xC,0xD,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits5[15] = {
|
||||
2,3,3,4,4,4,4,5,5,6,6,6,6,4,4
|
||||
};
|
||||
|
||||
static const uint8_t huffcode6[31] = {
|
||||
0x0,0x2,0x3,0x4,0x5,0x6,0x7,0x14,0x15,0x16,0x17,0x18,0x19,0x34,0x35,
|
||||
0x36,0x37,0x38,0x39,0x3A,0x3B,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x8,0x9,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits6[31] = {
|
||||
3,4,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,4,4
|
||||
};
|
||||
|
||||
static const uint8_t huffcode7[63] = {
|
||||
0x0,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF,0x10,0x11,0x24,0x25,0x26,0x27,0x28,
|
||||
0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x68,0x69,0x6A,0x6B,0x6C,
|
||||
0x6D,0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,0xF2,
|
||||
0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x2,0x3,
|
||||
};
|
||||
|
||||
static const uint8_t huffbits7[63] = {
|
||||
3,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,4,4
|
||||
};
|
||||
|
||||
static const uint8_t huff_tab_sizes[7] = {
|
||||
9, 5, 7, 9, 15, 31, 63,
|
||||
};
|
||||
|
||||
static const uint8_t* const huff_codes[7] = {
|
||||
huffcode1,huffcode2,huffcode3,huffcode4,huffcode5,huffcode6,huffcode7,
|
||||
};
|
||||
|
||||
static const uint8_t* const huff_bits[7] = {
|
||||
huffbits1,huffbits2,huffbits3,huffbits4,huffbits5,huffbits6,huffbits7,
|
||||
};
|
||||
|
||||
static const uint16_t atrac3_vlc_offs[] = {
|
||||
0,512,1024,1536,2048,2560,3072,3584,4096
|
||||
};
|
||||
|
||||
/* selector tables */
|
||||
|
||||
static const uint8_t CLCLengthTab[8] = {0, 4, 3, 3, 4, 4, 5, 6};
|
||||
static const int8_t seTab_0[4] = {0, 1, -2, -1};
|
||||
static const int8_t decTable1[18] = {0,0, 0,1, 0,-1, 1,0, -1,0, 1,1, 1,-1, -1,1, -1,-1};
|
||||
|
||||
|
||||
/* tables for the scalefactor decoding */
|
||||
|
||||
static const float iMaxQuant[8] = {
|
||||
0.0, 1.0/1.5, 1.0/2.5, 1.0/3.5, 1.0/4.5, 1.0/7.5, 1.0/15.5, 1.0/31.5
|
||||
};
|
||||
|
||||
static const uint16_t subbandTab[33] = {
|
||||
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224,
|
||||
256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024
|
||||
};
|
||||
|
||||
/* joint stereo related tables */
|
||||
static const float matrixCoeffs[8] = {0.0, 2.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0};
|
||||
|
||||
#endif /* AVCODEC_ATRAC3DATA_H */
|
||||
@@ -1,243 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
* audio conversion
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/libm.h"
|
||||
#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_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);
|
||||
}
|
||||
}
|
||||
|
||||
static const char* const channel_names[]={
|
||||
"FL", "FR", "FC", "LFE", "BL", "BR", "FLC", "FRC",
|
||||
"BC", "SL", "SR", "TC", "TFL", "TFC", "TFR", "TBL",
|
||||
"TBC", "TBR",
|
||||
[29] = "DL",
|
||||
[30] = "DR",
|
||||
};
|
||||
|
||||
static const char *get_channel_name(int channel_id)
|
||||
{
|
||||
if (channel_id<0 || channel_id>=FF_ARRAY_ELEMS(channel_names))
|
||||
return NULL;
|
||||
return channel_names[channel_id];
|
||||
}
|
||||
|
||||
int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name)
|
||||
{
|
||||
switch(nb_channels) {
|
||||
case 1: return CH_LAYOUT_MONO;
|
||||
case 2: return CH_LAYOUT_STEREO;
|
||||
case 3: return CH_LAYOUT_SURROUND;
|
||||
case 4: return CH_LAYOUT_QUAD;
|
||||
case 5: return CH_LAYOUT_5POINT0;
|
||||
case 6: return CH_LAYOUT_5POINT1;
|
||||
case 8: return CH_LAYOUT_7POINT1;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
int nb_channels;
|
||||
int64_t layout;
|
||||
} channel_layout_map[] = {
|
||||
{ "mono", 1, CH_LAYOUT_MONO },
|
||||
{ "stereo", 2, CH_LAYOUT_STEREO },
|
||||
{ "4.0", 4, CH_LAYOUT_4POINT0 },
|
||||
{ "quad", 4, CH_LAYOUT_QUAD },
|
||||
{ "5.0", 5, CH_LAYOUT_5POINT0 },
|
||||
{ "5.0", 5, CH_LAYOUT_5POINT0_BACK },
|
||||
{ "5.1", 6, CH_LAYOUT_5POINT1 },
|
||||
{ "5.1", 6, CH_LAYOUT_5POINT1_BACK },
|
||||
{ "5.1+downmix", 8, CH_LAYOUT_5POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
|
||||
{ "7.1", 8, CH_LAYOUT_7POINT1 },
|
||||
{ "7.1(wide)", 8, CH_LAYOUT_7POINT1_WIDE },
|
||||
{ "7.1+downmix", 10, CH_LAYOUT_7POINT1|CH_LAYOUT_STEREO_DOWNMIX, },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; channel_layout_map[i].name; i++)
|
||||
if (nb_channels == channel_layout_map[i].nb_channels &&
|
||||
channel_layout == channel_layout_map[i].layout) {
|
||||
av_strlcpy(buf, channel_layout_map[i].name, buf_size);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, buf_size, "%d channels", nb_channels);
|
||||
if (channel_layout) {
|
||||
int i,ch;
|
||||
av_strlcat(buf, " (", buf_size);
|
||||
for(i=0,ch=0; i<64; i++) {
|
||||
if ((channel_layout & (1L<<i))) {
|
||||
const char *name = get_channel_name(i);
|
||||
if (name) {
|
||||
if (ch>0) av_strlcat(buf, "|", buf_size);
|
||||
av_strlcat(buf, name, buf_size);
|
||||
}
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
av_strlcat(buf, ")", buf_size);
|
||||
}
|
||||
}
|
||||
|
||||
int avcodec_channel_layout_num_channels(int64_t channel_layout)
|
||||
{
|
||||
int count;
|
||||
uint64_t x = channel_layout;
|
||||
for (count = 0; x; count++)
|
||||
x &= x-1; // unset lowest set bit
|
||||
return count;
|
||||
}
|
||||
|
||||
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];
|
||||
const 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 ?
|
||||
|
||||
CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_U8 , *(const uint8_t*)pi)
|
||||
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
|
||||
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
|
||||
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
|
||||
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
|
||||
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
|
||||
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S16, *(const int16_t*)pi)
|
||||
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S16, *(const int16_t*)pi<<16)
|
||||
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
|
||||
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S16, *(const int16_t*)pi*(1.0 / (1<<15)))
|
||||
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
|
||||
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_S32, *(const int32_t*)pi>>16)
|
||||
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_S32, *(const int32_t*)pi)
|
||||
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
|
||||
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_S32, *(const int32_t*)pi*(1.0 / (1<<31)))
|
||||
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_FLT, av_clip_uint8( lrintf(*(const float*)pi * (1<<7)) + 0x80))
|
||||
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_FLT, av_clip_int16( lrintf(*(const float*)pi * (1<<15))))
|
||||
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
|
||||
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_FLT, *(const float*)pi)
|
||||
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_FLT, *(const float*)pi)
|
||||
else CONV(SAMPLE_FMT_U8 , uint8_t, SAMPLE_FMT_DBL, av_clip_uint8( lrint(*(const double*)pi * (1<<7)) + 0x80))
|
||||
else CONV(SAMPLE_FMT_S16, int16_t, SAMPLE_FMT_DBL, av_clip_int16( lrint(*(const double*)pi * (1<<15))))
|
||||
else CONV(SAMPLE_FMT_S32, int32_t, SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
|
||||
else CONV(SAMPLE_FMT_FLT, float , SAMPLE_FMT_DBL, *(const double*)pi)
|
||||
else CONV(SAMPLE_FMT_DBL, double , SAMPLE_FMT_DBL, *(const double*)pi)
|
||||
else return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* audio conversion
|
||||
* Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2008 Peter Ross
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AUDIOCONVERT_H
|
||||
#define AVCODEC_AUDIOCONVERT_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Audio format conversion routines
|
||||
*/
|
||||
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
|
||||
/**
|
||||
* Generate string corresponding to the sample format with
|
||||
* number sample_fmt, or a header if sample_fmt is negative.
|
||||
*
|
||||
* @param[in] buf the buffer where to write the string
|
||||
* @param[in] buf_size the size of buf
|
||||
* @param[in] sample_fmt the number of the sample format to print the corresponding info string, or
|
||||
* a negative value to print the corresponding header.
|
||||
* Meaningful values for obtaining a sample format info vary from 0 to SAMPLE_FMT_NB -1.
|
||||
*/
|
||||
void avcodec_sample_fmt_string(char *buf, int buf_size, int sample_fmt);
|
||||
|
||||
/**
|
||||
* @return NULL on error
|
||||
*/
|
||||
const char *avcodec_get_sample_fmt_name(int sample_fmt);
|
||||
|
||||
/**
|
||||
* @return SAMPLE_FMT_NONE on error
|
||||
*/
|
||||
enum SampleFormat avcodec_get_sample_fmt(const char* name);
|
||||
|
||||
/**
|
||||
* @return NULL on error
|
||||
*/
|
||||
const char *avcodec_get_channel_name(int channel_id);
|
||||
|
||||
/**
|
||||
* Return description of channel layout
|
||||
*/
|
||||
void avcodec_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int64_t channel_layout);
|
||||
|
||||
/**
|
||||
* Guess the channel layout
|
||||
* @param nb_channels
|
||||
* @param codec_id Codec identifier, or CODEC_ID_NONE if unknown
|
||||
* @param fmt_name Format name, or NULL if unknown
|
||||
* @return Channel layout mask
|
||||
*/
|
||||
int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
|
||||
|
||||
/**
|
||||
* @return the number of channels in the channel layout.
|
||||
*/
|
||||
int avcodec_channel_layout_num_channels(int64_t channel_layout);
|
||||
|
||||
struct AVAudioConvert;
|
||||
typedef struct AVAudioConvert AVAudioConvert;
|
||||
|
||||
/**
|
||||
* Create an audio sample format converter context
|
||||
* @param out_fmt Output sample format
|
||||
* @param out_channels Number of output channels
|
||||
* @param in_fmt Input sample format
|
||||
* @param in_channels Number of input channels
|
||||
* @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
|
||||
* @param flags See FF_MM_xx
|
||||
* @return NULL on error
|
||||
*/
|
||||
AVAudioConvert *av_audio_convert_alloc(enum SampleFormat out_fmt, int out_channels,
|
||||
enum SampleFormat in_fmt, int in_channels,
|
||||
const float *matrix, int flags);
|
||||
|
||||
/**
|
||||
* Free audio sample format converter context
|
||||
*/
|
||||
void av_audio_convert_free(AVAudioConvert *ctx);
|
||||
|
||||
/**
|
||||
* Convert between audio sample formats
|
||||
* @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
|
||||
* @param[in] out_stride distance between consecutive output samples (measured in bytes)
|
||||
* @param[in] in array of input buffers for each channel
|
||||
* @param[in] in_stride distance between consecutive input samples (measured in bytes)
|
||||
* @param len length of audio frame size (measured in samples)
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif /* AVCODEC_AUDIOCONVERT_H */
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Aura 2 decoder
|
||||
*
|
||||
* 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
|
||||
* Aura 2 decoder
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
typedef struct AuraDecodeContext {
|
||||
AVCodecContext *avctx;
|
||||
AVFrame frame;
|
||||
} AuraDecodeContext;
|
||||
|
||||
static av_cold int aura_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
AuraDecodeContext *s = avctx->priv_data;
|
||||
|
||||
s->avctx = avctx;
|
||||
/* width needs to be divisible by 4 for this codec to work */
|
||||
if (avctx->width & 0x3)
|
||||
return -1;
|
||||
avctx->pix_fmt = PIX_FMT_YUV422P;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aura_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *pkt)
|
||||
{
|
||||
AuraDecodeContext *s=avctx->priv_data;
|
||||
|
||||
uint8_t *Y, *U, *V;
|
||||
uint8_t val;
|
||||
int x, y;
|
||||
const uint8_t *buf = pkt->data;
|
||||
|
||||
/* prediction error tables (make it clear that they are signed values) */
|
||||
const int8_t *delta_table = (const int8_t*)buf + 16;
|
||||
|
||||
if (pkt->size != 48 + avctx->height * avctx->width) {
|
||||
av_log(avctx, AV_LOG_ERROR, "got a buffer with %d bytes when %d were expected\n",
|
||||
pkt->size, 48 + avctx->height * avctx->width);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pixel data starts 48 bytes in, after 3x16-byte tables */
|
||||
buf += 48;
|
||||
|
||||
if(s->frame.data[0])
|
||||
avctx->release_buffer(avctx, &s->frame);
|
||||
|
||||
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
|
||||
s->frame.reference = 0;
|
||||
if(avctx->get_buffer(avctx, &s->frame) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Y = s->frame.data[0];
|
||||
U = s->frame.data[1];
|
||||
V = s->frame.data[2];
|
||||
|
||||
/* iterate through each line in the height */
|
||||
for (y = 0; y < avctx->height; y++) {
|
||||
/* reset predictors */
|
||||
val = *buf++;
|
||||
U[0] = val & 0xF0;
|
||||
Y[0] = val << 4;
|
||||
val = *buf++;
|
||||
V[0] = val & 0xF0;
|
||||
Y[1] = Y[0] + delta_table[val & 0xF];
|
||||
Y += 2; U++; V++;
|
||||
|
||||
/* iterate through the remaining pixel groups (4 pixels/group) */
|
||||
for (x = 1; x < (avctx->width >> 1); x++) {
|
||||
val = *buf++;
|
||||
U[0] = U[-1] + delta_table[val >> 4];
|
||||
Y[0] = Y[-1] + delta_table[val & 0xF];
|
||||
val = *buf++;
|
||||
V[0] = V[-1] + delta_table[val >> 4];
|
||||
Y[1] = Y[ 0] + delta_table[val & 0xF];
|
||||
Y += 2; U++; V++;
|
||||
}
|
||||
Y += s->frame.linesize[0] - avctx->width;
|
||||
U += s->frame.linesize[1] - (avctx->width >> 1);
|
||||
V += s->frame.linesize[2] - (avctx->width >> 1);
|
||||
}
|
||||
|
||||
*data_size=sizeof(AVFrame);
|
||||
*(AVFrame*)data= s->frame;
|
||||
|
||||
return pkt->size;
|
||||
}
|
||||
|
||||
static av_cold int aura_decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
AuraDecodeContext *s = avctx->priv_data;
|
||||
|
||||
if (s->frame.data[0])
|
||||
avctx->release_buffer(avctx, &s->frame);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec aura2_decoder = {
|
||||
"aura2",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_AURA2,
|
||||
sizeof(AuraDecodeContext),
|
||||
aura_decode_init,
|
||||
NULL,
|
||||
aura_decode_end,
|
||||
aura_decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
NULL,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Auravision Aura 2"),
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* 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 "libavutil/mem.h"
|
||||
#include "avfft.h"
|
||||
#include "fft.h"
|
||||
|
||||
/* FFT */
|
||||
|
||||
FFTContext *av_fft_init(int nbits, int inverse)
|
||||
{
|
||||
FFTContext *s = av_malloc(sizeof(*s));
|
||||
|
||||
if (s)
|
||||
ff_fft_init(s, nbits, inverse);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void av_fft_permute(FFTContext *s, FFTComplex *z)
|
||||
{
|
||||
s->fft_permute(s, z);
|
||||
}
|
||||
|
||||
void av_fft_calc(FFTContext *s, FFTComplex *z)
|
||||
{
|
||||
s->fft_calc(s, z);
|
||||
}
|
||||
|
||||
void av_fft_end(FFTContext *s)
|
||||
{
|
||||
if (s) {
|
||||
ff_fft_end(s);
|
||||
av_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_MDCT
|
||||
|
||||
FFTContext *av_mdct_init(int nbits, int inverse, double scale)
|
||||
{
|
||||
FFTContext *s = av_malloc(sizeof(*s));
|
||||
|
||||
if (s)
|
||||
ff_mdct_init(s, nbits, inverse, scale);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
|
||||
{
|
||||
s->imdct_calc(s, output, input);
|
||||
}
|
||||
|
||||
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
|
||||
{
|
||||
s->imdct_half(s, output, input);
|
||||
}
|
||||
|
||||
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
|
||||
{
|
||||
s->mdct_calc(s, output, input);
|
||||
}
|
||||
|
||||
void av_mdct_end(FFTContext *s)
|
||||
{
|
||||
if (s) {
|
||||
ff_mdct_end(s);
|
||||
av_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MDCT */
|
||||
|
||||
#if CONFIG_RDFT
|
||||
|
||||
RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
|
||||
{
|
||||
RDFTContext *s = av_malloc(sizeof(*s));
|
||||
|
||||
if (s)
|
||||
ff_rdft_init(s, nbits, trans);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void av_rdft_calc(RDFTContext *s, FFTSample *data)
|
||||
{
|
||||
ff_rdft_calc(s, data);
|
||||
}
|
||||
|
||||
void av_rdft_end(RDFTContext *s)
|
||||
{
|
||||
if (s) {
|
||||
ff_rdft_end(s);
|
||||
av_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_RDFT */
|
||||
|
||||
#if CONFIG_DCT
|
||||
|
||||
DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
|
||||
{
|
||||
DCTContext *s = av_malloc(sizeof(*s));
|
||||
|
||||
if (s)
|
||||
ff_dct_init(s, nbits, inverse);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void av_dct_calc(DCTContext *s, FFTSample *data)
|
||||
{
|
||||
ff_dct_calc(s, data);
|
||||
}
|
||||
|
||||
void av_dct_end(DCTContext *s)
|
||||
{
|
||||
if (s) {
|
||||
ff_dct_end(s);
|
||||
av_free(s);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DCT */
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AVFFT_H
|
||||
#define AVCODEC_AVFFT_H
|
||||
|
||||
typedef float FFTSample;
|
||||
|
||||
typedef struct FFTComplex {
|
||||
FFTSample re, im;
|
||||
} FFTComplex;
|
||||
|
||||
typedef struct FFTContext FFTContext;
|
||||
|
||||
/**
|
||||
* Set up a complex FFT.
|
||||
* @param nbits log2 of the length of the input array
|
||||
* @param inverse if 0 perform the forward transform, if 1 perform the inverse
|
||||
*/
|
||||
FFTContext *av_fft_init(int nbits, int inverse);
|
||||
|
||||
/**
|
||||
* Do the permutation needed BEFORE calling ff_fft_calc().
|
||||
*/
|
||||
void av_fft_permute(FFTContext *s, FFTComplex *z);
|
||||
|
||||
/**
|
||||
* Do a complex FFT with the parameters defined in av_fft_init(). The
|
||||
* input data must be permuted before. No 1.0/sqrt(n) normalization is done.
|
||||
*/
|
||||
void av_fft_calc(FFTContext *s, FFTComplex *z);
|
||||
|
||||
void av_fft_end(FFTContext *s);
|
||||
|
||||
FFTContext *av_mdct_init(int nbits, int inverse, double scale);
|
||||
void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input);
|
||||
void av_mdct_end(FFTContext *s);
|
||||
|
||||
/* Real Discrete Fourier Transform */
|
||||
|
||||
enum RDFTransformType {
|
||||
DFT_R2C,
|
||||
IDFT_C2R,
|
||||
IDFT_R2C,
|
||||
DFT_C2R,
|
||||
};
|
||||
|
||||
typedef struct RDFTContext RDFTContext;
|
||||
|
||||
/**
|
||||
* Set up a real FFT.
|
||||
* @param nbits log2 of the length of the input array
|
||||
* @param trans the type of transform
|
||||
*/
|
||||
RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans);
|
||||
void av_rdft_calc(RDFTContext *s, FFTSample *data);
|
||||
void av_rdft_end(RDFTContext *s);
|
||||
|
||||
/* Discrete Cosine Transform */
|
||||
|
||||
typedef struct DCTContext DCTContext;
|
||||
|
||||
enum DCTTransformType {
|
||||
DCT_II = 0,
|
||||
DCT_III,
|
||||
DCT_I,
|
||||
DST_I,
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets up DCT.
|
||||
* @param nbits size of the input array:
|
||||
* (1 << nbits) for DCT-II, DCT-III and DST-I
|
||||
* (1 << nbits) + 1 for DCT-I
|
||||
*
|
||||
* @note the first element of the input of DST-I is ignored
|
||||
*/
|
||||
DCTContext *av_dct_init(int nbits, enum DCTTransformType type);
|
||||
void av_dct_calc(DCTContext *s, FFTSample *data);
|
||||
void av_dct_end (DCTContext *s);
|
||||
|
||||
#endif /* AVCODEC_AVFFT_H */
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* AVPacket functions for libavcodec
|
||||
* Copyright (c) 2000, 2001, 2002 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
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
|
||||
void av_destruct_packet_nofree(AVPacket *pkt)
|
||||
{
|
||||
pkt->data = NULL; pkt->size = 0;
|
||||
}
|
||||
|
||||
void av_destruct_packet(AVPacket *pkt)
|
||||
{
|
||||
av_free(pkt->data);
|
||||
pkt->data = NULL; pkt->size = 0;
|
||||
}
|
||||
|
||||
void av_init_packet(AVPacket *pkt)
|
||||
{
|
||||
pkt->pts = AV_NOPTS_VALUE;
|
||||
pkt->dts = AV_NOPTS_VALUE;
|
||||
pkt->pos = -1;
|
||||
pkt->duration = 0;
|
||||
pkt->convergence_duration = 0;
|
||||
pkt->flags = 0;
|
||||
pkt->stream_index = 0;
|
||||
pkt->destruct= NULL;
|
||||
}
|
||||
|
||||
int av_new_packet(AVPacket *pkt, int size)
|
||||
{
|
||||
uint8_t *data= NULL;
|
||||
if((unsigned)size < (unsigned)size + FF_INPUT_BUFFER_PADDING_SIZE)
|
||||
data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (data){
|
||||
memset(data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
}else
|
||||
size=0;
|
||||
|
||||
av_init_packet(pkt);
|
||||
pkt->data = data;
|
||||
pkt->size = size;
|
||||
pkt->destruct = av_destruct_packet;
|
||||
if(!data)
|
||||
return AVERROR(ENOMEM);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_shrink_packet(AVPacket *pkt, int size)
|
||||
{
|
||||
if (pkt->size <= size) return;
|
||||
pkt->size = size;
|
||||
memset(pkt->data + size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
}
|
||||
|
||||
int av_dup_packet(AVPacket *pkt)
|
||||
{
|
||||
if (((pkt->destruct == av_destruct_packet_nofree) || (pkt->destruct == NULL)) && pkt->data) {
|
||||
uint8_t *data;
|
||||
/* We duplicate the packet and don't forget to add the padding again. */
|
||||
if((unsigned)pkt->size > (unsigned)pkt->size + FF_INPUT_BUFFER_PADDING_SIZE)
|
||||
return AVERROR(ENOMEM);
|
||||
data = av_malloc(pkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!data) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
memcpy(data, pkt->data, pkt->size);
|
||||
memset(data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
pkt->data = data;
|
||||
pkt->destruct = av_destruct_packet;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void av_free_packet(AVPacket *pkt)
|
||||
{
|
||||
if (pkt) {
|
||||
if (pkt->destruct) pkt->destruct(pkt);
|
||||
pkt->data = NULL; pkt->size = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* 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 "get_bits.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
AVFrame picture;
|
||||
} AvsContext;
|
||||
|
||||
typedef enum {
|
||||
AVS_VIDEO = 0x01,
|
||||
AVS_AUDIO = 0x02,
|
||||
AVS_PALETTE = 0x03,
|
||||
AVS_GAME_DATA = 0x04,
|
||||
} AvsBlockType;
|
||||
|
||||
typedef enum {
|
||||
AVS_I_FRAME = 0x00,
|
||||
AVS_P_FRAME_3X3 = 0x01,
|
||||
AVS_P_FRAME_2X2 = 0x02,
|
||||
AVS_P_FRAME_2X3 = 0x03,
|
||||
} AvsVideoSubType;
|
||||
|
||||
|
||||
static int
|
||||
avs_decode_frame(AVCodecContext * avctx,
|
||||
void *data, int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
AvsContext *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;
|
||||
AvsVideoSubType sub_type;
|
||||
AvsBlockType 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",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_AVS,
|
||||
sizeof(AvsContext),
|
||||
avs_decode_init,
|
||||
NULL,
|
||||
NULL,
|
||||
avs_decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("AVS (Audio Video Standard) video"),
|
||||
};
|
||||
@@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 François Revol <revol@free.fr>
|
||||
*
|
||||
* 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 DEBUG
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
typedef struct ThreadContext{
|
||||
AVCodecContext *avctx;
|
||||
thread_id thread;
|
||||
sem_id work_sem;
|
||||
sem_id done_sem;
|
||||
int (*func)(AVCodecContext *c, void *arg);
|
||||
void *arg;
|
||||
int ret;
|
||||
}ThreadContext;
|
||||
|
||||
// it's odd Be never patented that :D
|
||||
struct benaphore {
|
||||
vint32 atom;
|
||||
sem_id sem;
|
||||
};
|
||||
static inline int lock_ben(struct benaphore *ben)
|
||||
{
|
||||
if (atomic_add(&ben->atom, 1) > 0)
|
||||
return acquire_sem(ben->sem);
|
||||
return B_OK;
|
||||
}
|
||||
static inline int unlock_ben(struct benaphore *ben)
|
||||
{
|
||||
if (atomic_add(&ben->atom, -1) > 1)
|
||||
return release_sem(ben->sem);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
static struct benaphore av_thread_lib_ben;
|
||||
|
||||
static int32 ff_thread_func(void *v){
|
||||
ThreadContext *c= v;
|
||||
|
||||
for(;;){
|
||||
//printf("thread_func %X enter wait\n", (int)v); fflush(stdout);
|
||||
acquire_sem(c->work_sem);
|
||||
//printf("thread_func %X after wait (func=%X)\n", (int)v, (int)c->func); fflush(stdout);
|
||||
if(c->func)
|
||||
c->ret= c->func(c->avctx, c->arg);
|
||||
else
|
||||
return 0;
|
||||
//printf("thread_func %X signal complete\n", (int)v); fflush(stdout);
|
||||
release_sem(c->done_sem);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free what has been allocated by avcodec_thread_init().
|
||||
* Must be called after decoding has finished, especially do not call while avcodec_thread_execute() is running.
|
||||
*/
|
||||
void avcodec_thread_free(AVCodecContext *s){
|
||||
ThreadContext *c= s->thread_opaque;
|
||||
int i;
|
||||
int32 ret;
|
||||
|
||||
for(i=0; i<s->thread_count; i++){
|
||||
|
||||
c[i].func= NULL;
|
||||
release_sem(c[i].work_sem);
|
||||
wait_for_thread(c[i].thread, &ret);
|
||||
if(c[i].work_sem > B_OK) delete_sem(c[i].work_sem);
|
||||
if(c[i].done_sem > B_OK) delete_sem(c[i].done_sem);
|
||||
}
|
||||
|
||||
av_freep(&s->thread_opaque);
|
||||
}
|
||||
|
||||
static int avcodec_thread_execute(AVCodecContext *s, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size){
|
||||
ThreadContext *c= s->thread_opaque;
|
||||
int i;
|
||||
|
||||
assert(s == c->avctx);
|
||||
assert(count <= s->thread_count);
|
||||
|
||||
/* note, we can be certain that this is not called with the same AVCodecContext by different threads at the same time */
|
||||
|
||||
for(i=0; i<count; i++){
|
||||
c[i].arg= (char*)arg + i*size;
|
||||
c[i].func= func;
|
||||
c[i].ret= 12345;
|
||||
|
||||
release_sem(c[i].work_sem);
|
||||
}
|
||||
for(i=0; i<count; i++){
|
||||
acquire_sem(c[i].done_sem);
|
||||
|
||||
c[i].func= NULL;
|
||||
if(ret) ret[i]= c[i].ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avcodec_thread_init(AVCodecContext *s, int thread_count){
|
||||
int i;
|
||||
ThreadContext *c;
|
||||
|
||||
s->thread_count= thread_count;
|
||||
|
||||
if (thread_count <= 1)
|
||||
return 0;
|
||||
|
||||
assert(!s->thread_opaque);
|
||||
c= av_mallocz(sizeof(ThreadContext)*thread_count);
|
||||
s->thread_opaque= c;
|
||||
|
||||
for(i=0; i<thread_count; i++){
|
||||
//printf("init semaphors %d\n", i); fflush(stdout);
|
||||
c[i].avctx= s;
|
||||
|
||||
if((c[i].work_sem = create_sem(0, "ff work sem")) < B_OK)
|
||||
goto fail;
|
||||
if((c[i].done_sem = create_sem(0, "ff done sem")) < B_OK)
|
||||
goto fail;
|
||||
|
||||
//printf("create thread %d\n", i); fflush(stdout);
|
||||
c[i].thread = spawn_thread(ff_thread_func, "libavcodec thread", B_LOW_PRIORITY, &c[i] );
|
||||
if( c[i].thread < B_OK ) goto fail;
|
||||
resume_thread(c[i].thread );
|
||||
}
|
||||
//printf("init done\n"); fflush(stdout);
|
||||
|
||||
s->execute= avcodec_thread_execute;
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
avcodec_thread_free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* provide a mean to serialize calls to avcodec_*() for thread safety. */
|
||||
|
||||
int avcodec_thread_lock_lib(void)
|
||||
{
|
||||
return lock_ben(&av_thread_lib_ben);
|
||||
}
|
||||
|
||||
int avcodec_thread_unlock_lib(void)
|
||||
{
|
||||
return unlock_ben(&av_thread_lib_ben);
|
||||
}
|
||||
|
||||
/* our versions of _init and _fini (which are called by those actually from crt.o) */
|
||||
|
||||
void initialize_after(void)
|
||||
{
|
||||
av_thread_lib_ben.atom = 0;
|
||||
av_thread_lib_ben.sem = create_sem(0, "libavcodec benaphore");
|
||||
}
|
||||
|
||||
void uninitialize_before(void)
|
||||
{
|
||||
delete_sem(av_thread_lib_ben.sem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
/*
|
||||
* Bethesda VID video decoder
|
||||
* Copyright (C) 2007 Nicholas Tung
|
||||
*
|
||||
* 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
|
||||
* @brief Bethesda Softworks VID Video Decoder
|
||||
* @author Nicholas Tung [ntung (at. ntung com] (2007-03)
|
||||
* @sa http://wiki.multimedia.cx/index.php?title=Bethsoft_VID
|
||||
* @sa http://www.svatopluk.com/andux/docs/dfvid.html
|
||||
*/
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "dsputil.h"
|
||||
#include "bethsoftvideo.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
typedef struct BethsoftvidContext {
|
||||
AVFrame frame;
|
||||
} BethsoftvidContext;
|
||||
|
||||
static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
BethsoftvidContext *vid = avctx->priv_data;
|
||||
vid->frame.reference = 1;
|
||||
vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
|
||||
FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_palette(AVFrame * frame, const uint8_t * palette_buffer)
|
||||
{
|
||||
uint32_t * palette = (uint32_t *)frame->data[1];
|
||||
int a;
|
||||
for(a = 0; a < 256; a++){
|
||||
palette[a] = AV_RB24(&palette_buffer[a * 3]) * 4;
|
||||
}
|
||||
frame->palette_has_changed = 1;
|
||||
}
|
||||
|
||||
static int bethsoftvid_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
BethsoftvidContext * vid = avctx->priv_data;
|
||||
char block_type;
|
||||
uint8_t * dst;
|
||||
uint8_t * frame_end;
|
||||
int remaining = avctx->width; // number of bytes remaining on a line
|
||||
const int wrap_to_next_line = vid->frame.linesize[0] - avctx->width;
|
||||
int code;
|
||||
int yoffset;
|
||||
|
||||
if (avctx->reget_buffer(avctx, &vid->frame)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
dst = vid->frame.data[0];
|
||||
frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height;
|
||||
|
||||
switch(block_type = *buf++){
|
||||
case PALETTE_BLOCK:
|
||||
set_palette(&vid->frame, buf);
|
||||
return 0;
|
||||
case VIDEO_YOFF_P_FRAME:
|
||||
yoffset = bytestream_get_le16(&buf);
|
||||
if(yoffset >= avctx->height)
|
||||
return -1;
|
||||
dst += vid->frame.linesize[0] * yoffset;
|
||||
}
|
||||
|
||||
// main code
|
||||
while((code = *buf++)){
|
||||
int length = code & 0x7f;
|
||||
|
||||
// copy any bytes starting at the current position, and ending at the frame width
|
||||
while(length > remaining){
|
||||
if(code < 0x80)
|
||||
bytestream_get_buffer(&buf, dst, remaining);
|
||||
else if(block_type == VIDEO_I_FRAME)
|
||||
memset(dst, buf[0], remaining);
|
||||
length -= remaining; // decrement the number of bytes to be copied
|
||||
dst += remaining + wrap_to_next_line; // skip over extra bytes at end of frame
|
||||
remaining = avctx->width;
|
||||
if(dst == frame_end)
|
||||
goto end;
|
||||
}
|
||||
|
||||
// copy any remaining bytes after / if line overflows
|
||||
if(code < 0x80)
|
||||
bytestream_get_buffer(&buf, dst, length);
|
||||
else if(block_type == VIDEO_I_FRAME)
|
||||
memset(dst, *buf++, length);
|
||||
remaining -= length;
|
||||
dst += length;
|
||||
}
|
||||
end:
|
||||
|
||||
*data_size = sizeof(AVFrame);
|
||||
*(AVFrame*)data = vid->frame;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
BethsoftvidContext * vid = avctx->priv_data;
|
||||
if(vid->frame.data[0])
|
||||
avctx->release_buffer(avctx, &vid->frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec bethsoftvid_decoder = {
|
||||
.name = "bethsoftvid",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = CODEC_ID_BETHSOFTVID,
|
||||
.priv_data_size = sizeof(BethsoftvidContext),
|
||||
.init = bethsoftvid_decode_init,
|
||||
.close = bethsoftvid_decode_end,
|
||||
.decode = bethsoftvid_decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Bethesda VID video"),
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Bethesda VID video decoder
|
||||
* Copyright (C) 2007 Nicholas Tung
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_BETHSOFTVIDEO_H
|
||||
#define AVCODEC_BETHSOFTVIDEO_H
|
||||
|
||||
enum BethsoftVidBlockType
|
||||
{
|
||||
PALETTE_BLOCK = 0x02,
|
||||
FIRST_AUDIO_BLOCK = 0x7c,
|
||||
AUDIO_BLOCK = 0x7d,
|
||||
VIDEO_I_FRAME = 0x03,
|
||||
VIDEO_P_FRAME = 0x01,
|
||||
VIDEO_YOFF_P_FRAME = 0x04,
|
||||
EOF_BLOCK = 0x14,
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_BETHSOFTVIDEO_H */
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Brute Force & Ignorance (BFI) video decoder
|
||||
* Copyright (c) 2008 Sisir Koppaka
|
||||
*
|
||||
* 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
|
||||
* @brief Brute Force & Ignorance (.bfi) video decoder
|
||||
* @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
|
||||
* @sa http://wiki.multimedia.cx/index.php?title=BFI
|
||||
*/
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "avcodec.h"
|
||||
#include "bytestream.h"
|
||||
|
||||
typedef struct BFIContext {
|
||||
AVCodecContext *avctx;
|
||||
AVFrame frame;
|
||||
uint8_t *dst;
|
||||
} BFIContext;
|
||||
|
||||
static av_cold int bfi_decode_init(AVCodecContext * avctx)
|
||||
{
|
||||
BFIContext *bfi = avctx->priv_data;
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
bfi->dst = av_mallocz(avctx->width * avctx->height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bfi_decode_frame(AVCodecContext * avctx, void *data,
|
||||
int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
BFIContext *bfi = avctx->priv_data;
|
||||
uint8_t *dst = bfi->dst;
|
||||
uint8_t *src, *dst_offset, colour1, colour2;
|
||||
uint8_t *frame_end = bfi->dst + avctx->width * avctx->height;
|
||||
uint32_t *pal;
|
||||
int i, j, height = avctx->height;
|
||||
|
||||
if (bfi->frame.data[0])
|
||||
avctx->release_buffer(avctx, &bfi->frame);
|
||||
|
||||
bfi->frame.reference = 1;
|
||||
|
||||
if (avctx->get_buffer(avctx, &bfi->frame) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set frame parameters and palette, if necessary */
|
||||
if (!avctx->frame_number) {
|
||||
bfi->frame.pict_type = FF_I_TYPE;
|
||||
bfi->frame.key_frame = 1;
|
||||
/* Setting the palette */
|
||||
if(avctx->extradata_size>768) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Palette is too large.\n");
|
||||
return -1;
|
||||
}
|
||||
pal = (uint32_t *) bfi->frame.data[1];
|
||||
for (i = 0; i < avctx->extradata_size / 3; i++) {
|
||||
int shift = 16;
|
||||
*pal = 0;
|
||||
for (j = 0; j < 3; j++, shift -= 8)
|
||||
*pal +=
|
||||
((avctx->extradata[i * 3 + j] << 2) |
|
||||
(avctx->extradata[i * 3 + j] >> 4)) << shift;
|
||||
pal++;
|
||||
}
|
||||
bfi->frame.palette_has_changed = 1;
|
||||
} else {
|
||||
bfi->frame.pict_type = FF_P_TYPE;
|
||||
bfi->frame.key_frame = 0;
|
||||
}
|
||||
|
||||
buf += 4; //Unpacked size, not required.
|
||||
|
||||
while (dst != frame_end) {
|
||||
static const uint8_t lentab[4]={0,2,0,1};
|
||||
unsigned int byte = *buf++, av_uninit(offset);
|
||||
unsigned int code = byte >> 6;
|
||||
unsigned int length = byte & ~0xC0;
|
||||
|
||||
/* Get length and offset(if required) */
|
||||
if (length == 0) {
|
||||
if (code == 1) {
|
||||
length = bytestream_get_byte(&buf);
|
||||
offset = bytestream_get_le16(&buf);
|
||||
} else {
|
||||
length = bytestream_get_le16(&buf);
|
||||
if (code == 2 && length == 0)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (code == 1)
|
||||
offset = bytestream_get_byte(&buf);
|
||||
}
|
||||
|
||||
/* Do boundary check */
|
||||
if (dst + (length<<lentab[code]) > frame_end)
|
||||
break;
|
||||
|
||||
switch (code) {
|
||||
|
||||
case 0: //Normal Chain
|
||||
bytestream_get_buffer(&buf, dst, length);
|
||||
dst += length;
|
||||
break;
|
||||
|
||||
case 1: //Back Chain
|
||||
dst_offset = dst - offset;
|
||||
length *= 4; //Convert dwords to bytes.
|
||||
if (dst_offset < bfi->dst)
|
||||
break;
|
||||
while (length--)
|
||||
*dst++ = *dst_offset++;
|
||||
break;
|
||||
|
||||
case 2: //Skip Chain
|
||||
dst += length;
|
||||
break;
|
||||
|
||||
case 3: //Fill Chain
|
||||
colour1 = bytestream_get_byte(&buf);
|
||||
colour2 = bytestream_get_byte(&buf);
|
||||
while (length--) {
|
||||
*dst++ = colour1;
|
||||
*dst++ = colour2;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
src = bfi->dst;
|
||||
dst = bfi->frame.data[0];
|
||||
while (height--) {
|
||||
memcpy(dst, src, avctx->width);
|
||||
src += avctx->width;
|
||||
dst += bfi->frame.linesize[0];
|
||||
}
|
||||
*data_size = sizeof(AVFrame);
|
||||
*(AVFrame *) data = bfi->frame;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int bfi_decode_close(AVCodecContext * avctx)
|
||||
{
|
||||
BFIContext *bfi = avctx->priv_data;
|
||||
if (bfi->frame.data[0])
|
||||
avctx->release_buffer(avctx, &bfi->frame);
|
||||
av_free(bfi->dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec bfi_decoder = {
|
||||
.name = "bfi",
|
||||
.type = AVMEDIA_TYPE_VIDEO,
|
||||
.id = CODEC_ID_BFI,
|
||||
.priv_data_size = sizeof(BFIContext),
|
||||
.init = bfi_decode_init,
|
||||
.close = bfi_decode_close,
|
||||
.decode = bfi_decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
|
||||
};
|
||||
@@ -1,567 +0,0 @@
|
||||
/*
|
||||
* Block Gilbert-Moore decoder
|
||||
* Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
|
||||
*
|
||||
* 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
|
||||
* Block Gilbert-Moore decoder as used by MPEG-4 ALS
|
||||
* @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "bgmc.h"
|
||||
|
||||
|
||||
#define FREQ_BITS 14 // bits used by frequency counters
|
||||
#define VALUE_BITS 18 // bits used to represent the values
|
||||
#define TOP_VALUE ((1 << VALUE_BITS) - 1) // maximum value
|
||||
#define FIRST_QTR (TOP_VALUE / 4 + 1) // first quarter of values maximum value
|
||||
#define HALF (2 * FIRST_QTR) // first half of values maximum value
|
||||
#define THIRD_QTR (3 * FIRST_QTR) // third quarter of values maximum value
|
||||
|
||||
#define LUT_BITS (FREQ_BITS - 8) // number of bits used to index lookup tables
|
||||
#define LUT_SIZE (1 << LUT_BITS) // size of the lookup tables
|
||||
#define LUT_BUFF 4 // number of buffered lookup tables
|
||||
|
||||
|
||||
/** Cumulative frequency tables for block Gilbert-Moore coding.
|
||||
*/
|
||||
static const uint16_t cf_tables_1[3][129] = {
|
||||
{
|
||||
16384, 16066, 15748, 15431, 15114, 14799, 14485, 14173, 13861, 13552,
|
||||
13243, 12939, 12635, 12336, 12038, 11745, 11452, 11161, 10870, 10586,
|
||||
10303, 10027, 9751, 9483, 9215, 8953, 8692, 8440, 8189, 7946,
|
||||
7704, 7472, 7240, 7008, 6776, 6554, 6333, 6122, 5912, 5711,
|
||||
5512, 5320, 5128, 4947, 4766, 4595, 4425, 4264, 4104, 3946,
|
||||
3788, 3640, 3493, 3355, 3218, 3090, 2963, 2842, 2721, 2609,
|
||||
2498, 2395, 2292, 2196, 2100, 2004, 1908, 1820, 1732, 1651,
|
||||
1570, 1497, 1424, 1355, 1287, 1223, 1161, 1100, 1044, 988,
|
||||
938, 888, 839, 790, 746, 702, 662, 623, 588, 553,
|
||||
520, 488, 459, 431, 405, 380, 357, 334, 311, 288,
|
||||
268, 248, 230, 213, 197, 182, 168, 154, 142, 130,
|
||||
119, 108, 99, 90, 81, 72, 64, 56, 49, 42,
|
||||
36, 30, 25, 20, 15, 11, 7, 3, 0
|
||||
},
|
||||
{
|
||||
16384, 16080, 15776, 15473, 15170, 14868, 14567, 14268, 13970, 13674,
|
||||
13378, 13086, 12794, 12505, 12218, 11936, 11654, 11373, 11092, 10818,
|
||||
10544, 10276, 10008, 9749, 9490, 9236, 8982, 8737, 8492, 8256,
|
||||
8020, 7792, 7564, 7336, 7108, 6888, 6669, 6459, 6249, 6050,
|
||||
5852, 5660, 5468, 5286, 5104, 4931, 4760, 4598, 4436, 4275,
|
||||
4115, 3965, 3816, 3674, 3534, 3403, 3272, 3147, 3023, 2907,
|
||||
2792, 2684, 2577, 2476, 2375, 2274, 2173, 2079, 1986, 1897,
|
||||
1810, 1724, 1645, 1567, 1493, 1419, 1351, 1284, 1222, 1161,
|
||||
1105, 1050, 995, 941, 891, 842, 797, 753, 713, 673,
|
||||
636, 599, 566, 533, 503, 473, 446, 419, 392, 365,
|
||||
340, 316, 294, 272, 253, 234, 216, 199, 184, 169,
|
||||
155, 142, 130, 118, 106, 95, 85, 75, 66, 57,
|
||||
49, 41, 34, 27, 21, 15, 10, 5, 0
|
||||
},
|
||||
{
|
||||
16384, 16092, 15801, 15510, 15219, 14930, 14641, 14355, 14069, 13785,
|
||||
13501, 13219, 12938, 12661, 12384, 12112, 11841, 11571, 11301, 11037,
|
||||
10773, 10514, 10256, 10005, 9754, 9508, 9263, 9025, 8787, 8557,
|
||||
8327, 8103, 7879, 7655, 7431, 7215, 7000, 6792, 6585, 6387,
|
||||
6190, 5998, 5807, 5625, 5445, 5272, 5100, 4937, 4774, 4613,
|
||||
4452, 4301, 4150, 4007, 3865, 3731, 3597, 3469, 3341, 3218,
|
||||
3099, 2981, 2869, 2758, 2652, 2546, 2440, 2334, 2234, 2134,
|
||||
2041, 1949, 1864, 1779, 1699, 1620, 1547, 1474, 1407, 1340,
|
||||
1278, 1217, 1157, 1097, 1043, 989, 940, 891, 846, 801,
|
||||
759, 718, 680, 643, 609, 575, 543, 511, 479, 447,
|
||||
418, 389, 363, 337, 314, 291, 270, 249, 230, 212,
|
||||
195, 179, 164, 149, 135, 121, 108, 96, 85, 74,
|
||||
64, 54, 45, 36, 28, 20, 13, 6, 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static const uint16_t cf_tables_2[8][193] = {
|
||||
{
|
||||
16384, 16104, 15825, 15546, 15268, 14991, 14714, 14439, 14164, 13891,
|
||||
13620, 13350, 13081, 12815, 12549, 12287, 12025, 11765, 11505, 11250,
|
||||
10996, 10746, 10497, 10254, 10011, 9772, 9534, 9303, 9072, 8848,
|
||||
8624, 8406, 8188, 7970, 7752, 7539, 7327, 7123, 6919, 6724,
|
||||
6529, 6339, 6150, 5970, 5790, 5618, 5446, 5282, 5119, 4957,
|
||||
4795, 4642, 4490, 4345, 4201, 4065, 3929, 3798, 3669, 3547,
|
||||
3425, 3310, 3196, 3086, 2976, 2866, 2756, 2650, 2545, 2447,
|
||||
2350, 2260, 2170, 2085, 2000, 1921, 1843, 1770, 1698, 1632,
|
||||
1566, 1501, 1436, 1376, 1316, 1261, 1207, 1157, 1108, 1061,
|
||||
1015, 973, 931, 893, 855, 819, 783, 747, 711, 677,
|
||||
644, 614, 584, 557, 530, 505, 480, 458, 436, 416,
|
||||
396, 378, 360, 343, 326, 310, 295, 281, 267, 255,
|
||||
243, 232, 221, 211, 201, 192, 183, 174, 166, 158,
|
||||
150, 142, 134, 126, 119, 112, 106, 100, 95, 90,
|
||||
85, 80, 76, 72, 69, 66, 63, 60, 57, 54,
|
||||
51, 48, 46, 44, 42, 40, 38, 36, 34, 33,
|
||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23,
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
|
||||
2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16116, 15849, 15582, 15316, 15050, 14785, 14521, 14257, 13995,
|
||||
13734, 13476, 13218, 12963, 12708, 12457, 12206, 11956, 11706, 11460,
|
||||
11215, 10975, 10735, 10500, 10265, 10034, 9803, 9579, 9355, 9136,
|
||||
8917, 8703, 8489, 8275, 8061, 7853, 7645, 7444, 7244, 7051,
|
||||
6858, 6671, 6484, 6305, 6127, 5956, 5785, 5622, 5459, 5298,
|
||||
5137, 4983, 4830, 4684, 4539, 4401, 4263, 4131, 3999, 3874,
|
||||
3750, 3632, 3515, 3401, 3287, 3173, 3059, 2949, 2840, 2737,
|
||||
2635, 2539, 2444, 2354, 2264, 2181, 2098, 2020, 1943, 1872,
|
||||
1801, 1731, 1661, 1596, 1532, 1472, 1412, 1357, 1303, 1251,
|
||||
1200, 1153, 1106, 1063, 1020, 979, 938, 897, 856, 818,
|
||||
780, 746, 712, 681, 650, 621, 592, 566, 540, 517,
|
||||
494, 473, 452, 431, 410, 391, 373, 356, 340, 325,
|
||||
310, 296, 282, 270, 258, 247, 236, 225, 214, 203,
|
||||
192, 182, 172, 162, 153, 144, 136, 128, 121, 114,
|
||||
108, 102, 97, 92, 87, 82, 77, 73, 69, 65,
|
||||
62, 59, 56, 53, 50, 47, 45, 43, 41, 39,
|
||||
37, 35, 33, 31, 29, 27, 26, 25, 24, 23,
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13,
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
|
||||
2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16128, 15872, 15617, 15362, 15107, 14853, 14600, 14347, 14096,
|
||||
13846, 13597, 13350, 13105, 12860, 12618, 12376, 12135, 11894, 11657,
|
||||
11421, 11189, 10957, 10730, 10503, 10279, 10056, 9838, 9620, 9407,
|
||||
9195, 8987, 8779, 8571, 8363, 8159, 7955, 7758, 7561, 7371,
|
||||
7182, 6997, 6812, 6635, 6459, 6289, 6120, 5957, 5795, 5634,
|
||||
5473, 5319, 5165, 5018, 4871, 4732, 4593, 4458, 4324, 4197,
|
||||
4071, 3951, 3831, 3714, 3597, 3480, 3363, 3250, 3138, 3032,
|
||||
2927, 2828, 2729, 2635, 2541, 2453, 2366, 2284, 2202, 2126,
|
||||
2050, 1975, 1900, 1830, 1761, 1697, 1633, 1574, 1515, 1459,
|
||||
1403, 1351, 1300, 1252, 1205, 1160, 1115, 1070, 1025, 982,
|
||||
939, 899, 860, 824, 789, 756, 723, 693, 663, 636,
|
||||
609, 584, 559, 535, 511, 489, 467, 447, 427, 409,
|
||||
391, 374, 358, 343, 328, 313, 300, 287, 274, 261,
|
||||
248, 235, 223, 211, 200, 189, 179, 169, 160, 151,
|
||||
143, 135, 128, 121, 115, 109, 103, 97, 92, 87,
|
||||
82, 77, 73, 69, 65, 61, 58, 55, 52, 49,
|
||||
46, 43, 40, 37, 35, 33, 31, 29, 27, 25,
|
||||
23, 21, 20, 19, 18, 17, 16, 15, 14, 13,
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
|
||||
2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16139, 15894, 15649, 15405, 15162, 14919, 14677, 14435, 14195,
|
||||
13955, 13717, 13479, 13243, 13008, 12775, 12542, 12310, 12079, 11851,
|
||||
11623, 11399, 11176, 10956, 10737, 10521, 10305, 10094, 9883, 9677,
|
||||
9471, 9268, 9065, 8862, 8659, 8459, 8260, 8067, 7874, 7688,
|
||||
7502, 7321, 7140, 6965, 6790, 6621, 6452, 6290, 6128, 5968,
|
||||
5808, 5655, 5503, 5356, 5209, 5069, 4929, 4794, 4660, 4532,
|
||||
4404, 4282, 4160, 4041, 3922, 3803, 3684, 3568, 3452, 3343,
|
||||
3234, 3131, 3029, 2931, 2833, 2741, 2649, 2563, 2477, 2396,
|
||||
2316, 2236, 2157, 2083, 2009, 1940, 1871, 1807, 1743, 1683,
|
||||
1623, 1567, 1511, 1459, 1407, 1357, 1307, 1257, 1207, 1159,
|
||||
1111, 1067, 1023, 983, 943, 905, 868, 834, 800, 769,
|
||||
738, 709, 681, 653, 625, 600, 575, 552, 529, 508,
|
||||
487, 466, 447, 428, 410, 392, 376, 360, 344, 328,
|
||||
313, 298, 283, 268, 255, 242, 230, 218, 207, 196,
|
||||
186, 176, 167, 158, 150, 142, 135, 128, 121, 114,
|
||||
108, 102, 97, 92, 87, 82, 78, 74, 70, 66,
|
||||
62, 58, 54, 50, 47, 44, 41, 38, 35, 32,
|
||||
30, 28, 26, 24, 22, 20, 18, 16, 14, 13,
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
|
||||
2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16149, 15915, 15681, 15447, 15214, 14981, 14749, 14517, 14286,
|
||||
14055, 13827, 13599, 13373, 13147, 12923, 12699, 12476, 12253, 12034,
|
||||
11815, 11599, 11383, 11171, 10959, 10750, 10541, 10337, 10133, 9933,
|
||||
9733, 9536, 9339, 9142, 8945, 8751, 8557, 8369, 8181, 7998,
|
||||
7816, 7638, 7460, 7288, 7116, 6950, 6785, 6625, 6465, 6306,
|
||||
6147, 5995, 5843, 5697, 5551, 5411, 5271, 5135, 5000, 4871,
|
||||
4742, 4618, 4495, 4374, 4253, 4132, 4011, 3893, 3775, 3663,
|
||||
3552, 3446, 3340, 3239, 3138, 3043, 2948, 2858, 2768, 2684,
|
||||
2600, 2516, 2433, 2355, 2278, 2205, 2133, 2065, 1997, 1932,
|
||||
1867, 1807, 1747, 1690, 1634, 1580, 1526, 1472, 1418, 1366,
|
||||
1314, 1266, 1218, 1174, 1130, 1088, 1047, 1009, 971, 936,
|
||||
901, 868, 836, 804, 772, 743, 714, 685, 658, 631,
|
||||
606, 582, 559, 536, 515, 494, 475, 456, 437, 418,
|
||||
399, 380, 362, 344, 328, 312, 297, 283, 270, 257,
|
||||
245, 233, 222, 211, 201, 191, 181, 172, 163, 155,
|
||||
147, 139, 132, 125, 119, 113, 107, 101, 96, 91,
|
||||
86, 81, 76, 71, 66, 62, 58, 54, 50, 46,
|
||||
43, 40, 37, 34, 31, 28, 26, 24, 22, 20,
|
||||
18, 16, 14, 12, 10, 8, 6, 5, 4, 3,
|
||||
2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16159, 15934, 15709, 15485, 15261, 15038, 14816, 14594, 14373,
|
||||
14152, 13933, 13714, 13497, 13280, 13065, 12850, 12636, 12422, 12211,
|
||||
12000, 11791, 11583, 11378, 11173, 10971, 10769, 10571, 10373, 10179,
|
||||
9985, 9793, 9601, 9409, 9217, 9029, 8842, 8658, 8475, 8297,
|
||||
8120, 7946, 7773, 7604, 7435, 7271, 7108, 6950, 6792, 6634,
|
||||
6477, 6326, 6175, 6029, 5883, 5742, 5602, 5466, 5330, 5199,
|
||||
5068, 4943, 4818, 4696, 4574, 4452, 4330, 4211, 4093, 3979,
|
||||
3866, 3759, 3652, 3549, 3446, 3348, 3250, 3157, 3065, 2977,
|
||||
2889, 2802, 2716, 2634, 2553, 2476, 2399, 2326, 2254, 2185,
|
||||
2117, 2052, 1987, 1926, 1866, 1808, 1750, 1692, 1634, 1578,
|
||||
1522, 1470, 1418, 1369, 1321, 1275, 1229, 1187, 1145, 1105,
|
||||
1066, 1027, 991, 955, 919, 883, 850, 817, 786, 756,
|
||||
728, 700, 674, 648, 624, 600, 578, 556, 534, 512,
|
||||
490, 468, 447, 426, 407, 388, 371, 354, 338, 322,
|
||||
307, 293, 280, 267, 255, 243, 231, 219, 209, 199,
|
||||
189, 179, 170, 161, 153, 145, 138, 131, 124, 117,
|
||||
111, 105, 99, 93, 87, 81, 76, 71, 66, 61,
|
||||
57, 53, 49, 45, 42, 39, 36, 33, 30, 27,
|
||||
24, 21, 19, 17, 15, 13, 11, 9, 7, 5,
|
||||
3, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16169, 15954, 15739, 15524, 15310, 15096, 14883, 14670, 14458,
|
||||
14246, 14035, 13824, 13614, 13405, 13198, 12991, 12785, 12579, 12376,
|
||||
12173, 11972, 11772, 11574, 11377, 11182, 10987, 10795, 10603, 10414,
|
||||
10226, 10040, 9854, 9668, 9482, 9299, 9116, 8937, 8759, 8585,
|
||||
8411, 8241, 8071, 7906, 7741, 7580, 7419, 7263, 7107, 6952,
|
||||
6797, 6647, 6497, 6353, 6209, 6070, 5931, 5796, 5661, 5531,
|
||||
5401, 5275, 5150, 5027, 4904, 4781, 4658, 4538, 4419, 4304,
|
||||
4190, 4081, 3972, 3867, 3762, 3662, 3562, 3467, 3372, 3281,
|
||||
3191, 3101, 3012, 2928, 2844, 2764, 2684, 2608, 2533, 2460,
|
||||
2387, 2318, 2250, 2185, 2121, 2059, 1997, 1935, 1873, 1813,
|
||||
1754, 1698, 1642, 1588, 1535, 1483, 1433, 1384, 1338, 1292,
|
||||
1249, 1206, 1165, 1125, 1085, 1045, 1008, 971, 937, 903,
|
||||
871, 840, 810, 780, 752, 724, 698, 672, 647, 622,
|
||||
597, 572, 548, 524, 502, 480, 460, 440, 421, 403,
|
||||
386, 369, 353, 337, 323, 309, 295, 281, 268, 255,
|
||||
243, 231, 220, 209, 199, 189, 180, 171, 163, 155,
|
||||
147, 139, 131, 123, 116, 109, 102, 95, 89, 83,
|
||||
77, 72, 67, 62, 57, 52, 48, 44, 40, 36,
|
||||
32, 28, 25, 22, 19, 16, 13, 10, 8, 6,
|
||||
4, 2, 0
|
||||
},
|
||||
{
|
||||
16384, 16177, 15970, 15764, 15558, 15353, 15148, 14944, 14740, 14537,
|
||||
14334, 14132, 13930, 13729, 13529, 13330, 13131, 12933, 12735, 12539,
|
||||
12343, 12150, 11957, 11766, 11576, 11388, 11200, 11015, 10830, 10647,
|
||||
10465, 10285, 10105, 9925, 9745, 9568, 9391, 9218, 9045, 8876,
|
||||
8707, 8541, 8375, 8213, 8051, 7894, 7737, 7583, 7429, 7277,
|
||||
7125, 6977, 6830, 6687, 6544, 6406, 6268, 6133, 5998, 5868,
|
||||
5738, 5612, 5487, 5364, 5241, 5118, 4995, 4875, 4755, 4640,
|
||||
4525, 4414, 4304, 4198, 4092, 3990, 3888, 3790, 3693, 3600,
|
||||
3507, 3415, 3323, 3235, 3147, 3064, 2981, 2902, 2823, 2746,
|
||||
2670, 2594, 2522, 2450, 2382, 2314, 2248, 2182, 2116, 2050,
|
||||
1987, 1924, 1864, 1804, 1748, 1692, 1638, 1585, 1534, 1484,
|
||||
1437, 1390, 1346, 1302, 1258, 1215, 1174, 1133, 1095, 1057,
|
||||
1021, 986, 952, 918, 887, 856, 827, 798, 770, 742,
|
||||
714, 686, 659, 632, 607, 582, 559, 536, 514, 492,
|
||||
472, 452, 433, 415, 398, 381, 364, 348, 333, 318,
|
||||
304, 290, 277, 264, 252, 240, 229, 218, 208, 198,
|
||||
188, 178, 168, 158, 149, 140, 132, 124, 116, 108,
|
||||
101, 94, 87, 81, 75, 69, 64, 59, 54, 49,
|
||||
44, 39, 35, 31, 27, 23, 19, 15, 12, 9,
|
||||
6, 3, 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static const uint16_t cf_tables_3[5][257] = {
|
||||
{
|
||||
16384, 16187, 15990, 15793, 15597, 15401, 15205, 15009, 14813, 14618,
|
||||
14423, 14230, 14037, 13845, 13653, 13463, 13273, 13083, 12894, 12706,
|
||||
12518, 12332, 12146, 11962, 11778, 11597, 11416, 11237, 11059, 10882,
|
||||
10706, 10532, 10358, 10184, 10010, 9838, 9666, 9497, 9328, 9163,
|
||||
8999, 8837, 8675, 8517, 8359, 8205, 8051, 7901, 7751, 7602,
|
||||
7453, 7308, 7163, 7022, 6882, 6745, 6609, 6476, 6343, 6214,
|
||||
6085, 5960, 5835, 5712, 5589, 5466, 5343, 5223, 5103, 4987,
|
||||
4872, 4761, 4650, 4542, 4435, 4332, 4229, 4130, 4031, 3936,
|
||||
3841, 3747, 3653, 3563, 3473, 3387, 3302, 3220, 3138, 3059,
|
||||
2980, 2905, 2830, 2759, 2688, 2619, 2550, 2481, 2412, 2345,
|
||||
2278, 2215, 2152, 2092, 2032, 1974, 1917, 1863, 1809, 1758,
|
||||
1707, 1659, 1611, 1564, 1517, 1473, 1429, 1387, 1346, 1307,
|
||||
1268, 1230, 1193, 1158, 1123, 1090, 1058, 1026, 994, 962,
|
||||
930, 899, 869, 841, 813, 786, 760, 735, 710, 687,
|
||||
664, 643, 622, 602, 582, 562, 543, 525, 507, 490,
|
||||
473, 457, 442, 427, 412, 398, 385, 373, 361, 349,
|
||||
337, 325, 313, 301, 290, 279, 269, 259, 249, 240,
|
||||
231, 222, 214, 206, 199, 192, 185, 178, 171, 165,
|
||||
159, 153, 148, 143, 138, 133, 128, 123, 119, 115,
|
||||
111, 107, 103, 99, 95, 91, 87, 83, 80, 77,
|
||||
74, 71, 68, 65, 63, 61, 59, 57, 55, 53,
|
||||
51, 49, 47, 45, 43, 41, 40, 39, 38, 37,
|
||||
36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
|
||||
26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
|
||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16195, 16006, 15817, 15629, 15441, 15253, 15065, 14878, 14692,
|
||||
14506, 14321, 14136, 13952, 13768, 13585, 13402, 13219, 13037, 12857,
|
||||
12677, 12499, 12321, 12144, 11967, 11792, 11617, 11444, 11271, 11100,
|
||||
10930, 10762, 10594, 10426, 10258, 10091, 9925, 9761, 9598, 9438,
|
||||
9278, 9120, 8963, 8809, 8655, 8504, 8354, 8207, 8060, 7914,
|
||||
7769, 7627, 7485, 7347, 7209, 7074, 6939, 6807, 6676, 6548,
|
||||
6420, 6296, 6172, 6050, 5928, 5806, 5684, 5564, 5444, 5328,
|
||||
5212, 5100, 4988, 4879, 4771, 4667, 4563, 4462, 4362, 4265,
|
||||
4169, 4073, 3978, 3886, 3795, 3707, 3619, 3535, 3451, 3369,
|
||||
3288, 3210, 3133, 3059, 2985, 2913, 2841, 2769, 2697, 2627,
|
||||
2557, 2490, 2424, 2360, 2297, 2237, 2177, 2119, 2062, 2007,
|
||||
1953, 1901, 1849, 1798, 1748, 1700, 1652, 1607, 1562, 1519,
|
||||
1476, 1435, 1394, 1355, 1317, 1281, 1245, 1210, 1175, 1140,
|
||||
1105, 1071, 1037, 1005, 973, 943, 913, 885, 857, 830,
|
||||
804, 779, 754, 731, 708, 685, 663, 642, 621, 601,
|
||||
581, 563, 545, 528, 511, 495, 479, 463, 448, 433,
|
||||
419, 405, 391, 377, 364, 351, 338, 326, 314, 302,
|
||||
291, 280, 270, 260, 251, 242, 234, 226, 218, 210,
|
||||
202, 195, 188, 181, 174, 168, 162, 156, 150, 144,
|
||||
139, 134, 129, 124, 119, 114, 109, 104, 100, 96,
|
||||
92, 88, 84, 80, 77, 74, 71, 68, 65, 62,
|
||||
59, 56, 54, 52, 50, 48, 46, 44, 42, 40,
|
||||
38, 36, 34, 33, 32, 31, 30, 29, 28, 27,
|
||||
26, 25, 24, 23, 22, 21, 20, 19, 18, 17,
|
||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16203, 16022, 15842, 15662, 15482, 15302, 15122, 14942, 14763,
|
||||
14584, 14406, 14228, 14051, 13874, 13698, 13522, 13347, 13172, 12998,
|
||||
12824, 12652, 12480, 12310, 12140, 11971, 11803, 11637, 11471, 11307,
|
||||
11143, 10980, 10817, 10654, 10491, 10330, 10169, 10011, 9853, 9697,
|
||||
9542, 9389, 9236, 9086, 8936, 8789, 8642, 8498, 8355, 8212,
|
||||
8070, 7931, 7792, 7656, 7520, 7388, 7256, 7126, 6996, 6870,
|
||||
6744, 6621, 6498, 6377, 6256, 6135, 6014, 5895, 5776, 5660,
|
||||
5545, 5433, 5321, 5212, 5104, 4999, 4895, 4793, 4692, 4594,
|
||||
4496, 4400, 4304, 4211, 4118, 4028, 3939, 3853, 3767, 3684,
|
||||
3601, 3521, 3441, 3364, 3287, 3212, 3137, 3062, 2987, 2915,
|
||||
2843, 2773, 2704, 2638, 2572, 2508, 2445, 2384, 2324, 2266,
|
||||
2208, 2153, 2098, 2044, 1990, 1939, 1888, 1839, 1791, 1745,
|
||||
1699, 1655, 1611, 1569, 1527, 1487, 1448, 1409, 1370, 1331,
|
||||
1292, 1255, 1218, 1183, 1148, 1115, 1082, 1051, 1020, 990,
|
||||
960, 932, 904, 878, 852, 826, 801, 777, 753, 731,
|
||||
709, 687, 666, 645, 625, 605, 586, 567, 550, 533,
|
||||
516, 499, 482, 465, 449, 433, 418, 403, 389, 375,
|
||||
362, 349, 337, 325, 314, 303, 293, 283, 273, 263,
|
||||
254, 245, 236, 227, 219, 211, 204, 197, 190, 183,
|
||||
177, 171, 165, 159, 153, 147, 141, 135, 130, 125,
|
||||
120, 115, 110, 105, 101, 97, 93, 89, 85, 81,
|
||||
77, 74, 71, 68, 65, 62, 59, 56, 53, 51,
|
||||
49, 47, 45, 43, 41, 39, 37, 35, 33, 31,
|
||||
29, 27, 25, 23, 22, 21, 20, 19, 18, 17,
|
||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16210, 16036, 15863, 15690, 15517, 15344, 15172, 15000, 14828,
|
||||
14656, 14485, 14314, 14145, 13976, 13808, 13640, 13472, 13304, 13137,
|
||||
12970, 12804, 12639, 12475, 12312, 12149, 11987, 11827, 11667, 11508,
|
||||
11349, 11192, 11035, 10878, 10721, 10565, 10410, 10257, 10104, 9953,
|
||||
9802, 9654, 9506, 9359, 9213, 9070, 8927, 8787, 8647, 8508,
|
||||
8369, 8233, 8097, 7964, 7831, 7700, 7570, 7442, 7315, 7190,
|
||||
7065, 6943, 6821, 6701, 6581, 6461, 6341, 6223, 6105, 5990,
|
||||
5876, 5764, 5653, 5545, 5437, 5331, 5226, 5124, 5022, 4924,
|
||||
4826, 4729, 4632, 4538, 4444, 4353, 4262, 4174, 4087, 4002,
|
||||
3917, 3835, 3753, 3674, 3595, 3518, 3441, 3364, 3287, 3212,
|
||||
3138, 3066, 2995, 2926, 2858, 2792, 2726, 2662, 2599, 2538,
|
||||
2478, 2420, 2362, 2305, 2249, 2195, 2141, 2089, 2037, 1988,
|
||||
1939, 1891, 1844, 1799, 1754, 1711, 1668, 1626, 1584, 1542,
|
||||
1500, 1459, 1418, 1380, 1342, 1305, 1269, 1234, 1199, 1166,
|
||||
1133, 1102, 1071, 1041, 1012, 983, 954, 926, 899, 872,
|
||||
847, 822, 798, 774, 751, 728, 707, 686, 666, 646,
|
||||
627, 608, 589, 570, 552, 534, 517, 500, 484, 468,
|
||||
453, 438, 424, 410, 397, 384, 372, 360, 348, 336,
|
||||
325, 314, 303, 293, 283, 273, 264, 255, 246, 237,
|
||||
229, 221, 213, 205, 197, 189, 181, 174, 167, 160,
|
||||
154, 148, 142, 136, 131, 126, 121, 116, 111, 106,
|
||||
101, 97, 93, 89, 85, 81, 77, 73, 70, 67,
|
||||
64, 61, 58, 55, 52, 49, 46, 43, 40, 37,
|
||||
35, 33, 31, 29, 27, 25, 23, 21, 19, 17,
|
||||
16, 15, 14, 13, 12, 11, 10, 9, 8, 7,
|
||||
6, 5, 4, 3, 2, 1, 0
|
||||
},
|
||||
{
|
||||
16384, 16218, 16052, 15886, 15720, 15554, 15389, 15224, 15059, 14895,
|
||||
14731, 14567, 14403, 14240, 14077, 13915, 13753, 13591, 13429, 13269,
|
||||
13109, 12950, 12791, 12633, 12476, 12320, 12164, 12009, 11854, 11701,
|
||||
11548, 11396, 11244, 11092, 10940, 10790, 10640, 10492, 10344, 10198,
|
||||
10052, 9908, 9764, 9622, 9481, 9342, 9203, 9066, 8929, 8793,
|
||||
8657, 8524, 8391, 8261, 8131, 8003, 7875, 7749, 7624, 7502,
|
||||
7380, 7260, 7140, 7022, 6904, 6786, 6668, 6551, 6435, 6322,
|
||||
6209, 6099, 5989, 5881, 5773, 5668, 5563, 5461, 5359, 5260,
|
||||
5161, 5063, 4965, 4871, 4777, 4686, 4595, 4506, 4417, 4331,
|
||||
4245, 4162, 4079, 3999, 3919, 3841, 3763, 3685, 3607, 3530,
|
||||
3454, 3380, 3307, 3236, 3166, 3097, 3029, 2963, 2897, 2834,
|
||||
2771, 2710, 2650, 2591, 2532, 2475, 2418, 2363, 2309, 2257,
|
||||
2205, 2155, 2105, 2057, 2009, 1963, 1918, 1873, 1828, 1783,
|
||||
1738, 1694, 1650, 1607, 1565, 1524, 1484, 1445, 1407, 1369,
|
||||
1333, 1297, 1263, 1229, 1197, 1165, 1134, 1103, 1073, 1043,
|
||||
1015, 987, 960, 933, 907, 882, 858, 834, 811, 788,
|
||||
766, 744, 722, 700, 679, 658, 638, 618, 599, 581,
|
||||
563, 545, 528, 511, 495, 480, 465, 451, 437, 423,
|
||||
410, 397, 384, 372, 360, 348, 337, 326, 315, 305,
|
||||
295, 285, 275, 265, 255, 245, 236, 227, 219, 211,
|
||||
203, 195, 188, 181, 174, 167, 161, 155, 149, 143,
|
||||
137, 131, 126, 121, 116, 111, 106, 101, 97, 93,
|
||||
89, 85, 81, 77, 73, 69, 65, 61, 58, 55,
|
||||
52, 49, 46, 43, 40, 37, 34, 32, 30, 28,
|
||||
26, 24, 22, 20, 18, 16, 14, 12, 10, 8,
|
||||
6, 5, 4, 3, 2, 1, 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static const uint16_t * const cf_table[16] = {
|
||||
cf_tables_1[0], cf_tables_1[1], cf_tables_1[2], cf_tables_2[0],
|
||||
cf_tables_2[1], cf_tables_2[2], cf_tables_2[3], cf_tables_2[4],
|
||||
cf_tables_2[5], cf_tables_2[6], cf_tables_2[7], cf_tables_3[0],
|
||||
cf_tables_3[1], cf_tables_3[2], cf_tables_3[3], cf_tables_3[4]
|
||||
};
|
||||
|
||||
|
||||
/** Initializes a given lookup table using a given delta
|
||||
*/
|
||||
static void bgmc_lut_fillp(uint8_t *lut, unsigned int *lut_status,
|
||||
unsigned int delta)
|
||||
{
|
||||
unsigned int sx, i;
|
||||
|
||||
for (sx = 0; sx < 16; sx++)
|
||||
for (i = 0; i < LUT_SIZE; i++) {
|
||||
unsigned int target = (i + 1) << (FREQ_BITS - LUT_BITS);
|
||||
unsigned int symbol = 1 << delta;
|
||||
|
||||
while (cf_table[sx][symbol] > target)
|
||||
symbol += 1 << delta;
|
||||
|
||||
*lut++ = symbol >> delta;
|
||||
}
|
||||
|
||||
*lut_status = delta;
|
||||
}
|
||||
|
||||
|
||||
/** Retunes the index of a suitable lookup table for a given delta
|
||||
*/
|
||||
static uint8_t* bgmc_lut_getp(uint8_t *lut, unsigned int *lut_status,
|
||||
unsigned int delta)
|
||||
{
|
||||
unsigned int i = av_clip(delta, 0, LUT_BUFF - 1);
|
||||
|
||||
lut += (i * LUT_SIZE) << 4;
|
||||
|
||||
if (lut_status[i] != delta)
|
||||
bgmc_lut_fillp(lut, &lut_status[i], delta);
|
||||
|
||||
return lut;
|
||||
}
|
||||
|
||||
|
||||
/** Initializes the lookup table arrays
|
||||
*/
|
||||
int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, unsigned int **cf_lut_status)
|
||||
{
|
||||
*cf_lut = av_malloc(sizeof(*cf_lut ) * LUT_BUFF * 16 * LUT_SIZE);
|
||||
*cf_lut_status = av_malloc(sizeof(*cf_lut_status) * LUT_BUFF);
|
||||
|
||||
if (!cf_lut || !cf_lut_status) {
|
||||
ff_bgmc_end(cf_lut, cf_lut_status);
|
||||
av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** Releases the lookup table arrays
|
||||
*/
|
||||
void ff_bgmc_end(uint8_t **cf_lut, unsigned int **cf_lut_status)
|
||||
{
|
||||
av_freep(cf_lut);
|
||||
av_freep(cf_lut_status);
|
||||
}
|
||||
|
||||
|
||||
/** Initializes decoding and reads the first value
|
||||
*/
|
||||
void ff_bgmc_decode_init(GetBitContext *gb,
|
||||
unsigned int *h, unsigned int *l, unsigned int *v)
|
||||
{
|
||||
*h = TOP_VALUE;
|
||||
*l = 0;
|
||||
*v = get_bits_long(gb, VALUE_BITS);
|
||||
}
|
||||
|
||||
|
||||
/** Finish decoding
|
||||
*/
|
||||
void ff_bgmc_decode_end(GetBitContext *gb)
|
||||
{
|
||||
skip_bits_long(gb, -(VALUE_BITS - 2));
|
||||
}
|
||||
|
||||
|
||||
/** Reads and decodes a block Gilbert-Moore coded symbol
|
||||
*/
|
||||
void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst,
|
||||
unsigned int delta, unsigned int sx,
|
||||
unsigned int *h, unsigned int *l, unsigned int *v,
|
||||
uint8_t *cf_lut, unsigned int *cf_lut_status)
|
||||
{
|
||||
unsigned int i;
|
||||
uint8_t *lut = bgmc_lut_getp(cf_lut, cf_lut_status, delta);
|
||||
|
||||
// read current state
|
||||
unsigned int high = *h;
|
||||
unsigned int low = *l;
|
||||
unsigned int value = *v;
|
||||
|
||||
lut += sx * LUT_SIZE;
|
||||
|
||||
// decode num samples
|
||||
for (i = 0; i < num; i++) {
|
||||
unsigned int range = high - low + 1;
|
||||
unsigned int target = (((value - low + 1) << FREQ_BITS) - 1) / range;
|
||||
unsigned int symbol = lut[target >> (FREQ_BITS - LUT_BITS)] << delta;
|
||||
|
||||
while (cf_table[sx][symbol] > target)
|
||||
symbol += 1 << delta;
|
||||
|
||||
symbol = (symbol >> delta) - 1;
|
||||
|
||||
high = low + ((range * cf_table[sx][(symbol ) << delta] - (1 << FREQ_BITS)) >> FREQ_BITS);
|
||||
low = low + ((range * cf_table[sx][(symbol + 1) << delta] ) >> FREQ_BITS);
|
||||
|
||||
while (1) {
|
||||
if (high >= HALF) {
|
||||
if (low >= HALF) {
|
||||
value -= HALF;
|
||||
low -= HALF;
|
||||
high -= HALF;
|
||||
} else if (low >= FIRST_QTR && high < THIRD_QTR) {
|
||||
value -= FIRST_QTR;
|
||||
low -= FIRST_QTR;
|
||||
high -= FIRST_QTR;
|
||||
} else break;
|
||||
}
|
||||
|
||||
low *= 2;
|
||||
high = 2 * high + 1;
|
||||
value = 2 * value + get_bits1(gb);
|
||||
}
|
||||
|
||||
*dst++ = symbol;
|
||||
}
|
||||
|
||||
// save current state
|
||||
*h = high;
|
||||
*l = low;
|
||||
*v = value;
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Block Gilbert-Moore decoder
|
||||
* Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
|
||||
*
|
||||
* 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
|
||||
* Block Gilbert-Moore decoder header
|
||||
* @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AVCODEC_BGMC_H
|
||||
#define AVCODEC_BGMC_H
|
||||
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
|
||||
int ff_bgmc_init(AVCodecContext *avctx, uint8_t **cf_lut, unsigned int **cf_lut_status);
|
||||
|
||||
|
||||
void ff_bgmc_end(uint8_t **cf_lut, unsigned int **cf_lut_status);
|
||||
|
||||
|
||||
void ff_bgmc_decode_init(GetBitContext *gb,
|
||||
unsigned int *h, unsigned int *l, unsigned int *v);
|
||||
|
||||
|
||||
void ff_bgmc_decode_end(GetBitContext *gb);
|
||||
|
||||
|
||||
void ff_bgmc_decode(GetBitContext *gb, unsigned int num, int32_t *dst,
|
||||
unsigned int delta, unsigned int sx,
|
||||
unsigned int *h, unsigned int *l, unsigned int *v,
|
||||
uint8_t *cf_lut, unsigned int *cf_lut_status);
|
||||
|
||||
|
||||
#endif /* AVCODEC_BGMC_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,311 +0,0 @@
|
||||
/*
|
||||
* Bink Audio decoder
|
||||
* Copyright (c) 2007-2010 Peter Ross (pross@xvid.org)
|
||||
* Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
|
||||
*
|
||||
* 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
|
||||
* Bink Audio decoder
|
||||
*
|
||||
* Technical details here:
|
||||
* http://wiki.multimedia.cx/index.php?title=Bink_Audio
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#define ALT_BITSTREAM_READER_LE
|
||||
#include "get_bits.h"
|
||||
#include "dsputil.h"
|
||||
#include "fft.h"
|
||||
|
||||
extern const uint16_t ff_wma_critical_freqs[25];
|
||||
|
||||
#define MAX_CHANNELS 2
|
||||
#define BINK_BLOCK_MAX_SIZE (MAX_CHANNELS << 11)
|
||||
|
||||
typedef struct {
|
||||
AVCodecContext *avctx;
|
||||
GetBitContext gb;
|
||||
DSPContext dsp;
|
||||
int first;
|
||||
int channels;
|
||||
int frame_len; ///< transform size (samples)
|
||||
int overlap_len; ///< overlap size (samples)
|
||||
int block_size;
|
||||
int num_bands;
|
||||
unsigned int *bands;
|
||||
float root;
|
||||
DECLARE_ALIGNED(16, FFTSample, coeffs)[BINK_BLOCK_MAX_SIZE];
|
||||
DECLARE_ALIGNED(16, short, previous)[BINK_BLOCK_MAX_SIZE / 16]; ///< coeffs from previous audio block
|
||||
float *coeffs_ptr[MAX_CHANNELS]; ///< pointers to the coeffs arrays for float_to_int16_interleave
|
||||
union {
|
||||
RDFTContext rdft;
|
||||
DCTContext dct;
|
||||
} trans;
|
||||
} BinkAudioContext;
|
||||
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
BinkAudioContext *s = avctx->priv_data;
|
||||
int sample_rate = avctx->sample_rate;
|
||||
int sample_rate_half;
|
||||
int i;
|
||||
int frame_len_bits;
|
||||
|
||||
s->avctx = avctx;
|
||||
dsputil_init(&s->dsp, avctx);
|
||||
|
||||
/* determine frame length */
|
||||
if (avctx->sample_rate < 22050) {
|
||||
frame_len_bits = 9;
|
||||
} else if (avctx->sample_rate < 44100) {
|
||||
frame_len_bits = 10;
|
||||
} else {
|
||||
frame_len_bits = 11;
|
||||
}
|
||||
s->frame_len = 1 << frame_len_bits;
|
||||
|
||||
if (s->channels > MAX_CHANNELS) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) {
|
||||
// audio is already interleaved for the RDFT format variant
|
||||
sample_rate *= avctx->channels;
|
||||
s->frame_len *= avctx->channels;
|
||||
s->channels = 1;
|
||||
if (avctx->channels == 2)
|
||||
frame_len_bits++;
|
||||
} else {
|
||||
s->channels = avctx->channels;
|
||||
}
|
||||
|
||||
s->overlap_len = s->frame_len / 16;
|
||||
s->block_size = (s->frame_len - s->overlap_len) * s->channels;
|
||||
sample_rate_half = (sample_rate + 1) / 2;
|
||||
s->root = 2.0 / sqrt(s->frame_len);
|
||||
|
||||
/* calculate number of bands */
|
||||
for (s->num_bands = 1; s->num_bands < 25; s->num_bands++)
|
||||
if (sample_rate_half <= ff_wma_critical_freqs[s->num_bands - 1])
|
||||
break;
|
||||
|
||||
s->bands = av_malloc((s->num_bands + 1) * sizeof(*s->bands));
|
||||
if (!s->bands)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
/* populate bands data */
|
||||
s->bands[0] = 1;
|
||||
for (i = 1; i < s->num_bands; i++)
|
||||
s->bands[i] = ff_wma_critical_freqs[i - 1] * (s->frame_len / 2) / sample_rate_half;
|
||||
s->bands[s->num_bands] = s->frame_len / 2;
|
||||
|
||||
s->first = 1;
|
||||
avctx->sample_fmt = SAMPLE_FMT_S16;
|
||||
|
||||
for (i = 0; i < s->channels; i++)
|
||||
s->coeffs_ptr[i] = s->coeffs + i * s->frame_len;
|
||||
|
||||
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT)
|
||||
ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R);
|
||||
else if (CONFIG_BINKAUDIO_DCT_DECODER)
|
||||
ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III);
|
||||
else
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float get_float(GetBitContext *gb)
|
||||
{
|
||||
int power = get_bits(gb, 5);
|
||||
float f = ldexpf(get_bits_long(gb, 23), power - 23);
|
||||
if (get_bits1(gb))
|
||||
f = -f;
|
||||
return f;
|
||||
}
|
||||
|
||||
static const uint8_t rle_length_tab[16] = {
|
||||
2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode Bink Audio block
|
||||
* @param[out] out Output buffer (must contain s->block_size elements)
|
||||
*/
|
||||
static void decode_block(BinkAudioContext *s, short *out, int use_dct)
|
||||
{
|
||||
int ch, i, j, k;
|
||||
float q, quant[25];
|
||||
int width, coeff;
|
||||
GetBitContext *gb = &s->gb;
|
||||
|
||||
if (use_dct)
|
||||
skip_bits(gb, 2);
|
||||
|
||||
for (ch = 0; ch < s->channels; ch++) {
|
||||
FFTSample *coeffs = s->coeffs_ptr[ch];
|
||||
q = 0.0f;
|
||||
coeffs[0] = get_float(gb) * s->root;
|
||||
coeffs[1] = get_float(gb) * s->root;
|
||||
|
||||
for (i = 0; i < s->num_bands; i++) {
|
||||
/* constant is result of 0.066399999/log10(M_E) */
|
||||
int value = get_bits(gb, 8);
|
||||
quant[i] = expf(FFMIN(value, 95) * 0.15289164787221953823f) * s->root;
|
||||
}
|
||||
|
||||
// find band (k)
|
||||
for (k = 0; s->bands[k] < 1; k++) {
|
||||
q = quant[k];
|
||||
}
|
||||
|
||||
// parse coefficients
|
||||
i = 2;
|
||||
while (i < s->frame_len) {
|
||||
if (get_bits1(gb)) {
|
||||
j = i + rle_length_tab[get_bits(gb, 4)] * 8;
|
||||
} else {
|
||||
j = i + 8;
|
||||
}
|
||||
|
||||
j = FFMIN(j, s->frame_len);
|
||||
|
||||
width = get_bits(gb, 4);
|
||||
if (width == 0) {
|
||||
memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
|
||||
i = j;
|
||||
while (s->bands[k] * 2 < i)
|
||||
q = quant[k++];
|
||||
} else {
|
||||
while (i < j) {
|
||||
if (s->bands[k] * 2 == i)
|
||||
q = quant[k++];
|
||||
coeff = get_bits(gb, width);
|
||||
if (coeff) {
|
||||
if (get_bits1(gb))
|
||||
coeffs[i] = -q * coeff;
|
||||
else
|
||||
coeffs[i] = q * coeff;
|
||||
} else {
|
||||
coeffs[i] = 0.0f;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CONFIG_BINKAUDIO_DCT_DECODER && use_dct) {
|
||||
coeffs[0] /= 0.5;
|
||||
ff_dct_calc (&s->trans.dct, coeffs);
|
||||
s->dsp.vector_fmul_scalar(coeffs, coeffs, s->frame_len / 2, s->frame_len);
|
||||
}
|
||||
else if (CONFIG_BINKAUDIO_RDFT_DECODER)
|
||||
ff_rdft_calc(&s->trans.rdft, coeffs);
|
||||
}
|
||||
|
||||
if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
|
||||
for (i = 0; i < s->channels; i++)
|
||||
for (j = 0; j < s->frame_len; j++)
|
||||
s->coeffs_ptr[i][j] = 385.0 + s->coeffs_ptr[i][j]*(1.0/32767.0);
|
||||
}
|
||||
s->dsp.float_to_int16_interleave(out, (const float **)s->coeffs_ptr, s->frame_len, s->channels);
|
||||
|
||||
if (!s->first) {
|
||||
int count = s->overlap_len * s->channels;
|
||||
int shift = av_log2(count);
|
||||
for (i = 0; i < count; i++) {
|
||||
out[i] = (s->previous[i] * (count - i) + out[i] * i) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(s->previous, out + s->block_size,
|
||||
s->overlap_len * s->channels * sizeof(*out));
|
||||
|
||||
s->first = 0;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
BinkAudioContext * s = avctx->priv_data;
|
||||
av_freep(&s->bands);
|
||||
if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT)
|
||||
ff_rdft_end(&s->trans.rdft);
|
||||
else if (CONFIG_BINKAUDIO_DCT_DECODER)
|
||||
ff_dct_end(&s->trans.dct);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_bits_align32(GetBitContext *s)
|
||||
{
|
||||
int n = (-get_bits_count(s)) & 31;
|
||||
if (n) skip_bits(s, n);
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
BinkAudioContext *s = avctx->priv_data;
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
short *samples = data;
|
||||
short *samples_end = (short*)((uint8_t*)data + *data_size);
|
||||
int reported_size;
|
||||
GetBitContext *gb = &s->gb;
|
||||
|
||||
init_get_bits(gb, buf, buf_size * 8);
|
||||
|
||||
reported_size = get_bits_long(gb, 32);
|
||||
while (get_bits_count(gb) / 8 < buf_size &&
|
||||
samples + s->block_size <= samples_end) {
|
||||
decode_block(s, samples, avctx->codec->id == CODEC_ID_BINKAUDIO_DCT);
|
||||
samples += s->block_size;
|
||||
get_bits_align32(gb);
|
||||
}
|
||||
|
||||
*data_size = FFMIN(reported_size, (uint8_t*)samples - (uint8_t*)data);
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
AVCodec binkaudio_rdft_decoder = {
|
||||
"binkaudio_rdft",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_BINKAUDIO_RDFT,
|
||||
sizeof(BinkAudioContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (RDFT)")
|
||||
};
|
||||
|
||||
AVCodec binkaudio_dct_decoder = {
|
||||
"binkaudio_dct",
|
||||
AVMEDIA_TYPE_AUDIO,
|
||||
CODEC_ID_BINKAUDIO_DCT,
|
||||
sizeof(BinkAudioContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Bink Audio (DCT)")
|
||||
};
|
||||
@@ -1,614 +0,0 @@
|
||||
/*
|
||||
* Bink video decoder
|
||||
* Copyright (C) 2009 Kostya Shishkov
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_BINKDATA_H
|
||||
#define AVCODEC_BINKDATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** Bink DCT and residue 8x8 block scan order */
|
||||
static const uint8_t bink_scan[64] = {
|
||||
0, 1, 8, 9, 2, 3, 10, 11,
|
||||
4, 5, 12, 13, 6, 7, 14, 15,
|
||||
20, 21, 28, 29, 22, 23, 30, 31,
|
||||
16, 17, 24, 25, 32, 33, 40, 41,
|
||||
34, 35, 42, 43, 48, 49, 56, 57,
|
||||
50, 51, 58, 59, 18, 19, 26, 27,
|
||||
36, 37, 44, 45, 38, 39, 46, 47,
|
||||
52, 53, 60, 61, 54, 55, 62, 63
|
||||
};
|
||||
|
||||
static const uint8_t bink_tree_bits[16][16] = {
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D,
|
||||
0x0F, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x01, 0x09, 0x05, 0x15, 0x0D, 0x1D,
|
||||
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D, 0x1D,
|
||||
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x04, 0x02, 0x06, 0x01, 0x09, 0x05, 0x0D,
|
||||
0x03, 0x13, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x04, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09,
|
||||
0x05, 0x0D, 0x03, 0x0B, 0x07, 0x17, 0x0F, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05,
|
||||
0x0D, 0x03, 0x0B, 0x1B, 0x07, 0x17, 0x0F, 0x1F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x05, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
|
||||
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x03, 0x13, 0x0B, 0x2B, 0x1B, 0x3B,
|
||||
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B, 0x1B,
|
||||
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x01, 0x05, 0x0D, 0x03, 0x13, 0x0B,
|
||||
0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x13, 0x0B,
|
||||
0x1B, 0x07, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x01, 0x03, 0x13, 0x0B, 0x1B, 0x3B,
|
||||
0x07, 0x27, 0x17, 0x37, 0x0F, 0x2F, 0x1F, 0x3F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17, 0x37,
|
||||
0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x05, 0x03, 0x07, 0x17, 0x37, 0x77,
|
||||
0x0F, 0x4F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
|
||||
},
|
||||
{
|
||||
0x00, 0x02, 0x01, 0x05, 0x03, 0x07, 0x27, 0x17,
|
||||
0x37, 0x0F, 0x2F, 0x6F, 0x1F, 0x5F, 0x3F, 0x7F,
|
||||
},
|
||||
};
|
||||
|
||||
static const uint8_t bink_tree_lens[16][16] = {
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
|
||||
{ 1, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
|
||||
{ 2, 2, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
|
||||
{ 2, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 },
|
||||
{ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5 },
|
||||
{ 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5 },
|
||||
{ 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5 },
|
||||
{ 1, 3, 3, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||
{ 1, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||
{ 1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||
{ 2, 2, 3, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
|
||||
{ 1, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6 },
|
||||
{ 2, 2, 2, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 },
|
||||
{ 1, 3, 3, 3, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7 },
|
||||
{ 1, 3, 3, 3, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 },
|
||||
{ 2, 2, 3, 3, 3, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7 },
|
||||
};
|
||||
|
||||
static const uint8_t bink_patterns[16][64] = {
|
||||
{
|
||||
0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
|
||||
0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01,
|
||||
0x02, 0x0A, 0x12, 0x1A, 0x22, 0x2A, 0x32, 0x3A,
|
||||
0x3B, 0x33, 0x2B, 0x23, 0x1B, 0x13, 0x0B, 0x03,
|
||||
0x04, 0x0C, 0x14, 0x1C, 0x24, 0x2C, 0x34, 0x3C,
|
||||
0x3D, 0x35, 0x2D, 0x25, 0x1D, 0x15, 0x0D, 0x05,
|
||||
0x06, 0x0E, 0x16, 0x1E, 0x26, 0x2E, 0x36, 0x3E,
|
||||
0x3F, 0x37, 0x2F, 0x27, 0x1F, 0x17, 0x0F, 0x07,
|
||||
},
|
||||
{
|
||||
0x3B, 0x3A, 0x39, 0x38, 0x30, 0x31, 0x32, 0x33,
|
||||
0x2B, 0x2A, 0x29, 0x28, 0x20, 0x21, 0x22, 0x23,
|
||||
0x1B, 0x1A, 0x19, 0x18, 0x10, 0x11, 0x12, 0x13,
|
||||
0x0B, 0x0A, 0x09, 0x08, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x0C,
|
||||
0x14, 0x15, 0x16, 0x17, 0x1F, 0x1E, 0x1D, 0x1C,
|
||||
0x24, 0x25, 0x26, 0x27, 0x2F, 0x2E, 0x2D, 0x2C,
|
||||
0x34, 0x35, 0x36, 0x37, 0x3F, 0x3E, 0x3D, 0x3C,
|
||||
},
|
||||
{
|
||||
0x19, 0x11, 0x12, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
|
||||
0x02, 0x0A, 0x09, 0x01, 0x00, 0x08, 0x10, 0x18,
|
||||
0x20, 0x28, 0x30, 0x38, 0x39, 0x31, 0x29, 0x2A,
|
||||
0x32, 0x3A, 0x3B, 0x33, 0x2B, 0x23, 0x22, 0x21,
|
||||
0x1D, 0x15, 0x16, 0x1E, 0x1F, 0x17, 0x0F, 0x07,
|
||||
0x06, 0x0E, 0x0D, 0x05, 0x04, 0x0C, 0x14, 0x1C,
|
||||
0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x35, 0x2D, 0x2E,
|
||||
0x36, 0x3E, 0x3F, 0x37, 0x2F, 0x27, 0x26, 0x25,
|
||||
},
|
||||
{
|
||||
0x03, 0x0B, 0x02, 0x0A, 0x01, 0x09, 0x00, 0x08,
|
||||
0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
|
||||
0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
|
||||
0x30, 0x38, 0x31, 0x39, 0x32, 0x3A, 0x33, 0x3B,
|
||||
0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
|
||||
0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
|
||||
0x1C, 0x14, 0x1D, 0x15, 0x1E, 0x16, 0x1F, 0x17,
|
||||
0x0F, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04,
|
||||
},
|
||||
{
|
||||
0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
|
||||
0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
|
||||
0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
|
||||
0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
|
||||
0x27, 0x26, 0x2F, 0x2E, 0x37, 0x36, 0x3F, 0x3E,
|
||||
0x3D, 0x3C, 0x35, 0x34, 0x2D, 0x2C, 0x25, 0x24,
|
||||
0x23, 0x22, 0x2B, 0x2A, 0x33, 0x32, 0x3B, 0x3A,
|
||||
0x39, 0x38, 0x31, 0x30, 0x29, 0x28, 0x21, 0x20,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x08, 0x09, 0x0A, 0x0B,
|
||||
0x10, 0x11, 0x12, 0x13, 0x18, 0x19, 0x1A, 0x1B,
|
||||
0x20, 0x21, 0x22, 0x23, 0x28, 0x29, 0x2A, 0x2B,
|
||||
0x30, 0x31, 0x32, 0x33, 0x38, 0x39, 0x3A, 0x3B,
|
||||
0x04, 0x05, 0x06, 0x07, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x14, 0x15, 0x16, 0x17, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x24, 0x25, 0x26, 0x27, 0x2C, 0x2D, 0x2E, 0x2F,
|
||||
0x34, 0x35, 0x36, 0x37, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
},
|
||||
{
|
||||
0x06, 0x07, 0x0F, 0x0E, 0x0D, 0x05, 0x0C, 0x04,
|
||||
0x03, 0x0B, 0x02, 0x0A, 0x09, 0x01, 0x00, 0x08,
|
||||
0x10, 0x18, 0x11, 0x19, 0x12, 0x1A, 0x13, 0x1B,
|
||||
0x14, 0x1C, 0x15, 0x1D, 0x16, 0x1E, 0x17, 0x1F,
|
||||
0x27, 0x2F, 0x26, 0x2E, 0x25, 0x2D, 0x24, 0x2C,
|
||||
0x23, 0x2B, 0x22, 0x2A, 0x21, 0x29, 0x20, 0x28,
|
||||
0x31, 0x30, 0x38, 0x39, 0x3A, 0x32, 0x3B, 0x33,
|
||||
0x3C, 0x34, 0x3D, 0x35, 0x36, 0x37, 0x3F, 0x3E,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x2F, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x28,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38,
|
||||
},
|
||||
{
|
||||
0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
|
||||
0x12, 0x13, 0x1B, 0x1A, 0x19, 0x11, 0x10, 0x18,
|
||||
0x20, 0x28, 0x29, 0x21, 0x22, 0x23, 0x2B, 0x2A,
|
||||
0x32, 0x31, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
|
||||
0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37, 0x36, 0x35,
|
||||
0x2D, 0x2C, 0x24, 0x25, 0x26, 0x2E, 0x2F, 0x27,
|
||||
0x1F, 0x17, 0x16, 0x1E, 0x1D, 0x1C, 0x14, 0x15,
|
||||
0x0D, 0x0C, 0x04, 0x05, 0x06, 0x0E, 0x0F, 0x07,
|
||||
},
|
||||
{
|
||||
0x18, 0x19, 0x10, 0x11, 0x08, 0x09, 0x00, 0x01,
|
||||
0x02, 0x03, 0x0A, 0x0B, 0x12, 0x13, 0x1A, 0x1B,
|
||||
0x1C, 0x1D, 0x14, 0x15, 0x0C, 0x0D, 0x04, 0x05,
|
||||
0x06, 0x07, 0x0E, 0x0F, 0x16, 0x17, 0x1E, 0x1F,
|
||||
0x26, 0x27, 0x2E, 0x2F, 0x36, 0x37, 0x3E, 0x3F,
|
||||
0x3C, 0x3D, 0x34, 0x35, 0x2C, 0x2D, 0x24, 0x25,
|
||||
0x22, 0x23, 0x2A, 0x2B, 0x32, 0x33, 0x3A, 0x3B,
|
||||
0x38, 0x39, 0x30, 0x31, 0x28, 0x29, 0x20, 0x21,
|
||||
},
|
||||
{
|
||||
0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B,
|
||||
0x13, 0x1B, 0x12, 0x1A, 0x11, 0x19, 0x10, 0x18,
|
||||
0x20, 0x28, 0x21, 0x29, 0x22, 0x2A, 0x23, 0x2B,
|
||||
0x33, 0x3B, 0x32, 0x3A, 0x31, 0x39, 0x30, 0x38,
|
||||
0x3C, 0x34, 0x3D, 0x35, 0x3E, 0x36, 0x3F, 0x37,
|
||||
0x2F, 0x27, 0x2E, 0x26, 0x2D, 0x25, 0x2C, 0x24,
|
||||
0x1F, 0x17, 0x1E, 0x16, 0x1D, 0x15, 0x1C, 0x14,
|
||||
0x0C, 0x04, 0x0D, 0x05, 0x0E, 0x06, 0x0F, 0x07,
|
||||
},
|
||||
{
|
||||
0x00, 0x08, 0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13,
|
||||
0x0B, 0x03, 0x02, 0x01, 0x09, 0x11, 0x12, 0x0A,
|
||||
0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F, 0x17,
|
||||
0x0F, 0x07, 0x06, 0x05, 0x0D, 0x15, 0x16, 0x0E,
|
||||
0x24, 0x2C, 0x34, 0x3C, 0x3D, 0x3E, 0x3F, 0x37,
|
||||
0x2F, 0x27, 0x26, 0x25, 0x2D, 0x35, 0x36, 0x2E,
|
||||
0x20, 0x28, 0x30, 0x38, 0x39, 0x3A, 0x3B, 0x33,
|
||||
0x2B, 0x23, 0x22, 0x21, 0x29, 0x31, 0x32, 0x2A,
|
||||
},
|
||||
{
|
||||
0x00, 0x08, 0x09, 0x01, 0x02, 0x03, 0x0B, 0x0A,
|
||||
0x13, 0x1B, 0x1A, 0x12, 0x11, 0x10, 0x18, 0x19,
|
||||
0x21, 0x20, 0x28, 0x29, 0x2A, 0x22, 0x23, 0x2B,
|
||||
0x33, 0x3B, 0x3A, 0x32, 0x31, 0x39, 0x38, 0x30,
|
||||
0x34, 0x3C, 0x3D, 0x35, 0x36, 0x3E, 0x3F, 0x37,
|
||||
0x2F, 0x27, 0x26, 0x2E, 0x2D, 0x2C, 0x24, 0x25,
|
||||
0x1D, 0x1C, 0x14, 0x15, 0x16, 0x1E, 0x1F, 0x17,
|
||||
0x0E, 0x0F, 0x07, 0x06, 0x05, 0x0D, 0x0C, 0x04,
|
||||
},
|
||||
{
|
||||
0x18, 0x10, 0x08, 0x00, 0x01, 0x02, 0x03, 0x0B,
|
||||
0x13, 0x1B, 0x1A, 0x19, 0x11, 0x0A, 0x09, 0x12,
|
||||
0x1C, 0x14, 0x0C, 0x04, 0x05, 0x06, 0x07, 0x0F,
|
||||
0x17, 0x1F, 0x1E, 0x1D, 0x15, 0x0E, 0x0D, 0x16,
|
||||
0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27, 0x2F,
|
||||
0x37, 0x3F, 0x3E, 0x3D, 0x35, 0x2E, 0x2D, 0x36,
|
||||
0x38, 0x30, 0x28, 0x20, 0x21, 0x22, 0x23, 0x2B,
|
||||
0x33, 0x3B, 0x3A, 0x39, 0x31, 0x2A, 0x29, 0x32,
|
||||
},
|
||||
{
|
||||
0x00, 0x08, 0x09, 0x01, 0x02, 0x0A, 0x12, 0x11,
|
||||
0x10, 0x18, 0x19, 0x1A, 0x1B, 0x13, 0x0B, 0x03,
|
||||
0x07, 0x06, 0x0E, 0x0F, 0x17, 0x16, 0x15, 0x0D,
|
||||
0x05, 0x04, 0x0C, 0x14, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
0x3F, 0x3E, 0x36, 0x37, 0x2F, 0x2E, 0x2D, 0x35,
|
||||
0x3D, 0x3C, 0x34, 0x2C, 0x24, 0x25, 0x26, 0x27,
|
||||
0x38, 0x30, 0x31, 0x39, 0x3A, 0x32, 0x2A, 0x29,
|
||||
0x28, 0x20, 0x21, 0x22, 0x23, 0x2B, 0x33, 0x3B,
|
||||
},
|
||||
{
|
||||
0x00, 0x01, 0x08, 0x09, 0x10, 0x11, 0x18, 0x19,
|
||||
0x20, 0x21, 0x28, 0x29, 0x30, 0x31, 0x38, 0x39,
|
||||
0x3A, 0x3B, 0x32, 0x33, 0x2A, 0x2B, 0x22, 0x23,
|
||||
0x1A, 0x1B, 0x12, 0x13, 0x0A, 0x0B, 0x02, 0x03,
|
||||
0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
|
||||
0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x3C, 0x3D,
|
||||
0x3E, 0x3F, 0x36, 0x37, 0x2E, 0x2F, 0x26, 0x27,
|
||||
0x1E, 0x1F, 0x16, 0x17, 0x0E, 0x0F, 0x06, 0x07,
|
||||
}
|
||||
};
|
||||
|
||||
static const uint32_t bink_intra_quant[16][64] = {
|
||||
{
|
||||
0x010000, 0x016315, 0x01E83D, 0x02A535, 0x014E7B, 0x016577, 0x02F1E6, 0x02724C,
|
||||
0x010000, 0x00EEDA, 0x024102, 0x017F9B, 0x00BE80, 0x00611E, 0x01083C, 0x00A552,
|
||||
0x021F88, 0x01DC53, 0x027FAD, 0x01F697, 0x014819, 0x00A743, 0x015A31, 0x009688,
|
||||
0x02346F, 0x030EE5, 0x01FBFA, 0x02C096, 0x01D000, 0x028396, 0x019247, 0x01F9AA,
|
||||
0x02346F, 0x01FBFA, 0x01DC53, 0x0231B8, 0x012F12, 0x01E06C, 0x00CB10, 0x0119A8,
|
||||
0x01C48C, 0x019748, 0x014E86, 0x0122AF, 0x02C628, 0x027F20, 0x0297B5, 0x023F32,
|
||||
0x025000, 0x01AB6B, 0x01D122, 0x0159B3, 0x012669, 0x008D43, 0x00EE1F, 0x0075ED,
|
||||
0x01490C, 0x010288, 0x00F735, 0x00EF51, 0x00E0F1, 0x0072AD, 0x00A4D8, 0x006517,
|
||||
},
|
||||
{
|
||||
0x015555, 0x01D971, 0x028AFC, 0x0386F1, 0x01BDF9, 0x01DC9F, 0x03ED33, 0x034311,
|
||||
0x015555, 0x013E78, 0x030158, 0x01FF7A, 0x00FE00, 0x00817D, 0x01604F, 0x00DC6D,
|
||||
0x02D4B5, 0x027B19, 0x0354E7, 0x029E1F, 0x01B577, 0x00DF04, 0x01CD96, 0x00C8B6,
|
||||
0x02F095, 0x0413DC, 0x02A54E, 0x03AB73, 0x026AAB, 0x035A1E, 0x02185E, 0x02A238,
|
||||
0x02F095, 0x02A54E, 0x027B19, 0x02ECF5, 0x019418, 0x028090, 0x010EC0, 0x01778A,
|
||||
0x025B66, 0x021F0B, 0x01BE09, 0x018394, 0x03B2E0, 0x03542A, 0x0374F1, 0x02FEEE,
|
||||
0x031555, 0x0239E4, 0x026C2D, 0x01CCEE, 0x01888C, 0x00BC59, 0x013D7E, 0x009D3C,
|
||||
0x01B6BB, 0x0158B5, 0x01499C, 0x013F17, 0x012BEC, 0x0098E6, 0x00DBCB, 0x0086C9,
|
||||
},
|
||||
{
|
||||
0x01AAAB, 0x024FCE, 0x032DBB, 0x0468AD, 0x022D78, 0x0253C7, 0x04E87F, 0x0413D5,
|
||||
0x01AAAB, 0x018E16, 0x03C1AE, 0x027F58, 0x013D80, 0x00A1DC, 0x01B863, 0x011388,
|
||||
0x0389E2, 0x0319DF, 0x042A21, 0x0345A7, 0x0222D4, 0x0116C5, 0x0240FC, 0x00FAE3,
|
||||
0x03ACBA, 0x0518D3, 0x034EA1, 0x04964F, 0x030555, 0x0430A5, 0x029E76, 0x034AC5,
|
||||
0x03ACBA, 0x034EA1, 0x0319DF, 0x03A833, 0x01F91E, 0x0320B4, 0x015270, 0x01D56D,
|
||||
0x02F23F, 0x02A6CE, 0x022D8B, 0x01E479, 0x049F98, 0x042935, 0x04522D, 0x03BEA9,
|
||||
0x03DAAB, 0x02C85D, 0x030738, 0x02402A, 0x01EAAF, 0x00EB6F, 0x018CDE, 0x00C48A,
|
||||
0x022469, 0x01AEE2, 0x019C02, 0x018EDD, 0x0176E7, 0x00BF20, 0x0112BE, 0x00A87B,
|
||||
},
|
||||
{
|
||||
0x020000, 0x02C62A, 0x03D07A, 0x054A69, 0x029CF6, 0x02CAEF, 0x05E3CC, 0x04E499,
|
||||
0x020000, 0x01DDB4, 0x048204, 0x02FF36, 0x017D01, 0x00C23C, 0x021077, 0x014AA3,
|
||||
0x043F0F, 0x03B8A6, 0x04FF5A, 0x03ED2E, 0x029032, 0x014E86, 0x02B461, 0x012D11,
|
||||
0x0468DF, 0x061DCA, 0x03F7F5, 0x05812C, 0x03A000, 0x05072C, 0x03248D, 0x03F353,
|
||||
0x0468DF, 0x03F7F5, 0x03B8A6, 0x046370, 0x025E24, 0x03C0D8, 0x019620, 0x02334F,
|
||||
0x038919, 0x032E91, 0x029D0D, 0x02455E, 0x058C50, 0x04FE3F, 0x052F69, 0x047E65,
|
||||
0x04A000, 0x0356D6, 0x03A243, 0x02B365, 0x024CD2, 0x011A85, 0x01DC3E, 0x00EBD9,
|
||||
0x029218, 0x020510, 0x01EE69, 0x01DEA2, 0x01C1E2, 0x00E559, 0x0149B0, 0x00CA2D,
|
||||
},
|
||||
{
|
||||
0x02AAAB, 0x03B2E3, 0x0515F8, 0x070DE2, 0x037BF2, 0x03B93E, 0x07DA65, 0x068621,
|
||||
0x02AAAB, 0x027CF0, 0x0602B1, 0x03FEF3, 0x01FC01, 0x0102FA, 0x02C09F, 0x01B8DA,
|
||||
0x05A96A, 0x04F632, 0x06A9CE, 0x053C3E, 0x036AED, 0x01BE09, 0x039B2D, 0x01916B,
|
||||
0x05E129, 0x0827B8, 0x054A9C, 0x0756E5, 0x04D555, 0x06B43B, 0x0430BC, 0x05446F,
|
||||
0x05E129, 0x054A9C, 0x04F632, 0x05D9EB, 0x032830, 0x050121, 0x021D80, 0x02EF14,
|
||||
0x04B6CC, 0x043E16, 0x037C11, 0x030728, 0x0765C0, 0x06A855, 0x06E9E2, 0x05FDDB,
|
||||
0x062AAB, 0x0473C8, 0x04D85A, 0x0399DC, 0x031118, 0x0178B2, 0x027AFD, 0x013A77,
|
||||
0x036D76, 0x02B16A, 0x029337, 0x027E2E, 0x0257D8, 0x0131CC, 0x01B796, 0x010D91,
|
||||
},
|
||||
{
|
||||
0x038000, 0x04DACA, 0x06ACD5, 0x094238, 0x0492AE, 0x04E322, 0x0A4EA5, 0x08900C,
|
||||
0x038000, 0x0343FB, 0x07E388, 0x053E9F, 0x029AC1, 0x0153E8, 0x039CD0, 0x02429E,
|
||||
0x076E5B, 0x068322, 0x08BEDE, 0x06DF11, 0x047C57, 0x02496B, 0x04BBAB, 0x020EDD,
|
||||
0x07B786, 0x0AB421, 0x06F1ED, 0x09A20D, 0x065800, 0x08CC8E, 0x057FF7, 0x06E9D2,
|
||||
0x07B786, 0x06F1ED, 0x068322, 0x07AE04, 0x0424BF, 0x06917B, 0x02C6B8, 0x03D9CB,
|
||||
0x062FEB, 0x05917D, 0x0492D7, 0x03F964, 0x09B58C, 0x08BCEF, 0x0912F8, 0x07DD30,
|
||||
0x081800, 0x05D7F7, 0x065BF6, 0x04B9F1, 0x040670, 0x01EE69, 0x03416C, 0x019CBC,
|
||||
0x047FAA, 0x0388DC, 0x036138, 0x03459C, 0x03134C, 0x01915C, 0x0240F5, 0x0161CF,
|
||||
},
|
||||
{
|
||||
0x040000, 0x058C54, 0x07A0F4, 0x0A94D3, 0x0539EC, 0x0595DD, 0x0BC798, 0x09C932,
|
||||
0x040000, 0x03BB68, 0x090409, 0x05FE6D, 0x02FA01, 0x018477, 0x0420EE, 0x029547,
|
||||
0x087E1F, 0x07714C, 0x09FEB5, 0x07DA5D, 0x052064, 0x029D0D, 0x0568C3, 0x025A21,
|
||||
0x08D1BE, 0x0C3B94, 0x07EFEA, 0x0B0258, 0x074000, 0x0A0E59, 0x06491A, 0x07E6A7,
|
||||
0x08D1BE, 0x07EFEA, 0x07714C, 0x08C6E0, 0x04BC48, 0x0781B1, 0x032C3F, 0x04669F,
|
||||
0x071232, 0x065D22, 0x053A1A, 0x048ABC, 0x0B18A0, 0x09FC7F, 0x0A5ED3, 0x08FCC9,
|
||||
0x094000, 0x06ADAC, 0x074487, 0x0566CA, 0x0499A5, 0x02350B, 0x03B87B, 0x01D7B3,
|
||||
0x052430, 0x040A20, 0x03DCD3, 0x03BD45, 0x0383C5, 0x01CAB3, 0x029361, 0x01945A,
|
||||
},
|
||||
{
|
||||
0x050000, 0x06EF69, 0x098931, 0x0D3A07, 0x068867, 0x06FB55, 0x0EB97E, 0x0C3B7E,
|
||||
0x050000, 0x04AA42, 0x0B450B, 0x077E08, 0x03B881, 0x01E595, 0x05292A, 0x033A99,
|
||||
0x0A9DA7, 0x094D9F, 0x0C7E62, 0x09D0F4, 0x06687D, 0x034450, 0x06C2F4, 0x02F0AA,
|
||||
0x0B062D, 0x0F4A78, 0x09EBE4, 0x0DC2EE, 0x091000, 0x0C91EF, 0x07DB61, 0x09E050,
|
||||
0x0B062D, 0x09EBE4, 0x094D9F, 0x0AF898, 0x05EB59, 0x09621D, 0x03F74F, 0x058046,
|
||||
0x08D6BE, 0x07F46A, 0x0688A0, 0x05AD6B, 0x0DDEC8, 0x0C7B9F, 0x0CF687, 0x0B3BFB,
|
||||
0x0B9000, 0x085917, 0x0915A8, 0x06C07D, 0x05C00E, 0x02C24D, 0x04A69A, 0x024D9F,
|
||||
0x066D3C, 0x050CA7, 0x04D407, 0x04AC96, 0x0464B6, 0x023D5F, 0x033839, 0x01F971,
|
||||
},
|
||||
{
|
||||
0x060000, 0x08527E, 0x0B716E, 0x0FDF3C, 0x07D6E1, 0x0860CC, 0x11AB63, 0x0EADCB,
|
||||
0x060000, 0x05991C, 0x0D860D, 0x08FDA3, 0x047702, 0x0246B3, 0x063165, 0x03DFEA,
|
||||
0x0CBD2E, 0x0B29F1, 0x0EFE0F, 0x0BC78B, 0x07B096, 0x03EB93, 0x081D24, 0x038732,
|
||||
0x0D3A9C, 0x12595D, 0x0BE7DF, 0x108384, 0x0AE000, 0x0F1585, 0x096DA8, 0x0BD9FA,
|
||||
0x0D3A9C, 0x0BE7DF, 0x0B29F1, 0x0D2A50, 0x071A6B, 0x0B4289, 0x04C25F, 0x0699EE,
|
||||
0x0A9B4A, 0x098BB2, 0x07D727, 0x06D01A, 0x10A4F0, 0x0EFABE, 0x0F8E3C, 0x0D7B2E,
|
||||
0x0DE000, 0x0A0482, 0x0AE6CA, 0x081A2F, 0x06E677, 0x034F90, 0x0594B9, 0x02C38C,
|
||||
0x07B649, 0x060F2F, 0x05CB3C, 0x059BE7, 0x0545A7, 0x02B00C, 0x03DD11, 0x025E87,
|
||||
},
|
||||
{
|
||||
0x080000, 0x0B18A8, 0x0F41E8, 0x1529A5, 0x0A73D7, 0x0B2BBB, 0x178F2F, 0x139264,
|
||||
0x080000, 0x0776CF, 0x120812, 0x0BFCD9, 0x05F402, 0x0308EF, 0x0841DC, 0x052A8E,
|
||||
0x10FC3E, 0x0EE297, 0x13FD69, 0x0FB4B9, 0x0A40C8, 0x053A1A, 0x0AD186, 0x04B442,
|
||||
0x11A37B, 0x187727, 0x0FDFD4, 0x1604B0, 0x0E8000, 0x141CB1, 0x0C9235, 0x0FCD4D,
|
||||
0x11A37B, 0x0FDFD4, 0x0EE297, 0x118DC0, 0x09788F, 0x0F0362, 0x06587F, 0x08CD3D,
|
||||
0x0E2463, 0x0CBA43, 0x0A7434, 0x091577, 0x163140, 0x13F8FE, 0x14BDA5, 0x11F992,
|
||||
0x128000, 0x0D5B58, 0x0E890D, 0x0ACD94, 0x093349, 0x046A15, 0x0770F7, 0x03AF65,
|
||||
0x0A4861, 0x08143F, 0x07B9A6, 0x077A89, 0x070789, 0x039565, 0x0526C2, 0x0328B4,
|
||||
},
|
||||
{
|
||||
0x0C0000, 0x10A4FD, 0x16E2DB, 0x1FBE78, 0x0FADC3, 0x10C198, 0x2356C7, 0x1D5B96,
|
||||
0x0C0000, 0x0B3237, 0x1B0C1A, 0x11FB46, 0x08EE03, 0x048D66, 0x0C62CA, 0x07BFD5,
|
||||
0x197A5D, 0x1653E3, 0x1DFC1E, 0x178F16, 0x0F612C, 0x07D727, 0x103A49, 0x070E64,
|
||||
0x1A7539, 0x24B2BB, 0x17CFBD, 0x210709, 0x15C000, 0x1E2B0A, 0x12DB4F, 0x17B3F4,
|
||||
0x1A7539, 0x17CFBD, 0x1653E3, 0x1A54A0, 0x0E34D7, 0x168513, 0x0984BE, 0x0D33DC,
|
||||
0x153695, 0x131765, 0x0FAE4E, 0x0DA033, 0x2149E1, 0x1DF57D, 0x1F1C78, 0x1AF65B,
|
||||
0x1BC000, 0x140904, 0x15CD94, 0x10345E, 0x0DCCEE, 0x069F20, 0x0B2972, 0x058718,
|
||||
0x0F6C91, 0x0C1E5E, 0x0B9678, 0x0B37CE, 0x0A8B4E, 0x056018, 0x07BA22, 0x04BD0E,
|
||||
},
|
||||
{
|
||||
0x110000, 0x179466, 0x206C0C, 0x2CF87F, 0x16362A, 0x17BCED, 0x321044, 0x299714,
|
||||
0x110000, 0x0FDC79, 0x265125, 0x19794E, 0x0CA685, 0x0672FB, 0x118BF4, 0x0AFA6D,
|
||||
0x241804, 0x1FA181, 0x2A7A80, 0x21600A, 0x15C9A9, 0x0B1B77, 0x16FD3C, 0x09FF0D,
|
||||
0x257B66, 0x33FD33, 0x21BBA2, 0x2EC9F7, 0x1ED000, 0x2ABCF9, 0x1AB6B0, 0x219444,
|
||||
0x257B66, 0x21BBA2, 0x1FA181, 0x254D38, 0x142030, 0x1FE730, 0x0D7C0E, 0x12B423,
|
||||
0x1E0D52, 0x1B0BCF, 0x1636EE, 0x134D9E, 0x2F28A9, 0x2A711B, 0x2C12FF, 0x263256,
|
||||
0x275000, 0x1C621B, 0x1EE33C, 0x16F4DB, 0x138CFB, 0x09616E, 0x0FD00C, 0x07D4B7,
|
||||
0x15D9CE, 0x112B06, 0x106A80, 0x0FE464, 0x0EF004, 0x079D77, 0x0AF25B, 0x06B67F,
|
||||
},
|
||||
{
|
||||
0x160000, 0x1E83CF, 0x29F53D, 0x3A3286, 0x1CBE90, 0x1EB842, 0x40C9C2, 0x35D293,
|
||||
0x160000, 0x1486BA, 0x319630, 0x20F756, 0x105F06, 0x085891, 0x16B51E, 0x0E3506,
|
||||
0x2EB5AA, 0x28EF20, 0x36F8E1, 0x2B30FE, 0x1C3225, 0x0E5FC7, 0x1DC030, 0x0CEFB7,
|
||||
0x308193, 0x4347AC, 0x2BA786, 0x3C8CE5, 0x27E000, 0x374EE7, 0x229212, 0x2B7494,
|
||||
0x308193, 0x2BA786, 0x28EF20, 0x3045D0, 0x1A0B89, 0x29494D, 0x11735D, 0x183469,
|
||||
0x26E410, 0x230039, 0x1CBF8F, 0x18FB09, 0x3D0771, 0x36ECBA, 0x390986, 0x316E52,
|
||||
0x32E000, 0x24BB33, 0x27F8E4, 0x1DB557, 0x194D09, 0x0C23BB, 0x1476A6, 0x0A2256,
|
||||
0x1C470A, 0x1637AD, 0x153E87, 0x1490FA, 0x1354B9, 0x09DAD6, 0x0E2A94, 0x08AFF0,
|
||||
},
|
||||
{
|
||||
0x1C0000, 0x26D64D, 0x3566AA, 0x4A11C2, 0x249572, 0x27190E, 0x527525, 0x44805E,
|
||||
0x1C0000, 0x1A1FD6, 0x3F1C3E, 0x29F4F9, 0x14D607, 0x0A9F44, 0x1CE683, 0x1214F0,
|
||||
0x3B72D9, 0x341911, 0x45F6F0, 0x36F889, 0x23E2BB, 0x124B5B, 0x25DD54, 0x1076E9,
|
||||
0x3DBC30, 0x55A109, 0x378F64, 0x4D1069, 0x32C000, 0x46646C, 0x2BFFB9, 0x374E8E,
|
||||
0x3DBC30, 0x378F64, 0x341911, 0x3D7020, 0x2125F5, 0x348BD6, 0x1635BC, 0x1ECE57,
|
||||
0x317F5B, 0x2C8BEB, 0x2496B6, 0x1FCB22, 0x4DAC61, 0x45E778, 0x4897C2, 0x3EE97F,
|
||||
0x40C000, 0x2EBFB5, 0x32DFAE, 0x25CF86, 0x203380, 0x0F734B, 0x1A0B5F, 0x0CE5E2,
|
||||
0x23FD53, 0x1C46DC, 0x1B09C4, 0x1A2CE1, 0x189A60, 0x0C8AE2, 0x1207A5, 0x0B0E77,
|
||||
},
|
||||
{
|
||||
0x220000, 0x2F28CC, 0x40D818, 0x59F0FE, 0x2C6C53, 0x2F79DA, 0x642089, 0x532E29,
|
||||
0x220000, 0x1FB8F1, 0x4CA24B, 0x32F29C, 0x194D09, 0x0CE5F7, 0x2317E8, 0x15F4DB,
|
||||
0x483007, 0x3F4303, 0x54F4FF, 0x42C014, 0x2B9351, 0x1636EE, 0x2DFA79, 0x13FE1A,
|
||||
0x4AF6CC, 0x67FA67, 0x437743, 0x5D93EE, 0x3DA000, 0x5579F1, 0x356D61, 0x432888,
|
||||
0x4AF6CC, 0x437743, 0x3F4303, 0x4A9A70, 0x284060, 0x3FCE60, 0x1AF81B, 0x256845,
|
||||
0x3C1AA5, 0x36179D, 0x2C6DDD, 0x269B3C, 0x5E5152, 0x54E237, 0x5825FE, 0x4C64AD,
|
||||
0x4EA000, 0x38C437, 0x3DC678, 0x2DE9B5, 0x2719F7, 0x12C2DB, 0x1FA018, 0x0FA96E,
|
||||
0x2BB39B, 0x22560C, 0x20D500, 0x1FC8C8, 0x1DE007, 0x0F3AEE, 0x15E4B7, 0x0D6CFE,
|
||||
},
|
||||
{
|
||||
0x2C0000, 0x3D079E, 0x53EA79, 0x74650C, 0x397D20, 0x3D7083, 0x819383, 0x6BA525,
|
||||
0x2C0000, 0x290D75, 0x632C61, 0x41EEAC, 0x20BE0C, 0x10B121, 0x2D6A3B, 0x1C6A0C,
|
||||
0x5D6B54, 0x51DE40, 0x6DF1C2, 0x5661FB, 0x38644B, 0x1CBF8F, 0x3B8060, 0x19DF6D,
|
||||
0x610326, 0x868F57, 0x574F0B, 0x7919CA, 0x4FC000, 0x6E9DCE, 0x452423, 0x56E928,
|
||||
0x610326, 0x574F0B, 0x51DE40, 0x608BA0, 0x341713, 0x52929A, 0x22E6BA, 0x3068D2,
|
||||
0x4DC821, 0x460071, 0x397F1E, 0x31F611, 0x7A0EE2, 0x6DD974, 0x72130C, 0x62DCA3,
|
||||
0x65C000, 0x497665, 0x4FF1C9, 0x3B6AAE, 0x329A12, 0x184776, 0x28ED4D, 0x1444AC,
|
||||
0x388E14, 0x2C6F5A, 0x2A7D0F, 0x2921F4, 0x26A973, 0x13B5AD, 0x1C5528, 0x115FDF,
|
||||
},
|
||||
};
|
||||
|
||||
static const uint32_t bink_inter_quant[16][64] = {
|
||||
{
|
||||
0x010000, 0x017946, 0x01A5A9, 0x0248DC, 0x016363, 0x0152A7, 0x0243EC, 0x0209EA,
|
||||
0x012000, 0x00E248, 0x01BBDA, 0x015CBC, 0x00A486, 0x0053E0, 0x00F036, 0x008095,
|
||||
0x01B701, 0x016959, 0x01B0B9, 0x0153FD, 0x00F8E7, 0x007EE4, 0x00EA30, 0x007763,
|
||||
0x01B701, 0x0260EB, 0x019DE9, 0x023E1B, 0x017000, 0x01FE6E, 0x012DB5, 0x01A27B,
|
||||
0x01E0D1, 0x01B0B9, 0x018A33, 0x01718D, 0x00D87A, 0x014449, 0x007B9A, 0x00AB71,
|
||||
0x013178, 0x0112EA, 0x00AD08, 0x009BB9, 0x023D97, 0x020437, 0x021CCC, 0x01E6B4,
|
||||
0x018000, 0x012DB5, 0x0146D9, 0x0100CE, 0x00CFD2, 0x006E5C, 0x00B0E4, 0x005A2D,
|
||||
0x00E9CC, 0x00B7B1, 0x00846F, 0x006B85, 0x008337, 0x0042E5, 0x004A10, 0x002831,
|
||||
},
|
||||
{
|
||||
0x015555, 0x01F708, 0x023237, 0x030BD0, 0x01D9D9, 0x01C389, 0x03053B, 0x02B7E3,
|
||||
0x018000, 0x012DB5, 0x024FCE, 0x01D0FA, 0x00DB5D, 0x006FD5, 0x014048, 0x00AB71,
|
||||
0x024957, 0x01E1CC, 0x0240F7, 0x01C551, 0x014BDE, 0x00A92F, 0x013840, 0x009F2F,
|
||||
0x024957, 0x032BE4, 0x0227E1, 0x02FD7A, 0x01EAAB, 0x02A893, 0x019247, 0x022DF9,
|
||||
0x028116, 0x0240F7, 0x020D99, 0x01ECBC, 0x0120A3, 0x01B061, 0x00A4CE, 0x00E497,
|
||||
0x01974B, 0x016E8E, 0x00E6B5, 0x00CFA2, 0x02FCC9, 0x02B04A, 0x02D110, 0x0288F1,
|
||||
0x020000, 0x019247, 0x01B3CC, 0x015668, 0x011518, 0x009325, 0x00EBDA, 0x00783D,
|
||||
0x0137BB, 0x00F4ED, 0x00B093, 0x008F5C, 0x00AEF4, 0x005931, 0x0062BF, 0x003597,
|
||||
},
|
||||
{
|
||||
0x01AAAB, 0x0274CB, 0x02BEC4, 0x03CEC4, 0x02504F, 0x02346C, 0x03C689, 0x0365DC,
|
||||
0x01E000, 0x017922, 0x02E3C1, 0x024539, 0x011235, 0x008BCA, 0x01905A, 0x00D64D,
|
||||
0x02DBAD, 0x025A40, 0x02D134, 0x0236A5, 0x019ED6, 0x00D37B, 0x018650, 0x00C6FB,
|
||||
0x02DBAD, 0x03F6DD, 0x02B1D9, 0x03BCD8, 0x026555, 0x0352B8, 0x01F6D8, 0x02B977,
|
||||
0x03215C, 0x02D134, 0x029100, 0x0267EB, 0x0168CC, 0x021C7A, 0x00CE01, 0x011DBD,
|
||||
0x01FD1E, 0x01CA31, 0x012062, 0x01038A, 0x03BBFB, 0x035C5C, 0x038554, 0x032B2D,
|
||||
0x028000, 0x01F6D8, 0x0220C0, 0x01AC02, 0x015A5E, 0x00B7EF, 0x0126D1, 0x00964C,
|
||||
0x0185A9, 0x013228, 0x00DCB8, 0x00B333, 0x00DAB2, 0x006F7D, 0x007B6F, 0x0042FC,
|
||||
},
|
||||
{
|
||||
0x020000, 0x02F28D, 0x034B52, 0x0491B8, 0x02C6C5, 0x02A54E, 0x0487D8, 0x0413D5,
|
||||
0x024000, 0x01C48F, 0x0377B5, 0x02B977, 0x01490C, 0x00A7BF, 0x01E06C, 0x01012A,
|
||||
0x036E03, 0x02D2B3, 0x036172, 0x02A7FA, 0x01F1CE, 0x00FDC7, 0x01D460, 0x00EEC7,
|
||||
0x036E03, 0x04C1D6, 0x033BD1, 0x047C37, 0x02E000, 0x03FCDD, 0x025B6A, 0x0344F5,
|
||||
0x03C1A1, 0x036172, 0x031466, 0x02E31B, 0x01B0F5, 0x028892, 0x00F735, 0x0156E2,
|
||||
0x0262F1, 0x0225D5, 0x015A10, 0x013772, 0x047B2D, 0x04086E, 0x043998, 0x03CD69,
|
||||
0x030000, 0x025B6A, 0x028DB3, 0x02019B, 0x019FA3, 0x00DCB8, 0x0161C7, 0x00B45B,
|
||||
0x01D398, 0x016F63, 0x0108DD, 0x00D70A, 0x01066F, 0x0085C9, 0x00941F, 0x005062,
|
||||
},
|
||||
{
|
||||
0x02AAAB, 0x03EE11, 0x04646D, 0x0617A0, 0x03B3B2, 0x038713, 0x060A75, 0x056FC6,
|
||||
0x030000, 0x025B6A, 0x049F9B, 0x03A1F4, 0x01B6BB, 0x00DFAA, 0x028090, 0x0156E2,
|
||||
0x0492AE, 0x03C399, 0x0481ED, 0x038AA2, 0x0297BD, 0x01525F, 0x027080, 0x013E5E,
|
||||
0x0492AE, 0x0657C8, 0x044FC1, 0x05FAF4, 0x03D555, 0x055126, 0x03248D, 0x045BF2,
|
||||
0x05022D, 0x0481ED, 0x041B33, 0x03D979, 0x024147, 0x0360C3, 0x01499C, 0x01C92E,
|
||||
0x032E96, 0x02DD1C, 0x01CD6A, 0x019F43, 0x05F991, 0x056093, 0x05A220, 0x0511E1,
|
||||
0x040000, 0x03248D, 0x036799, 0x02ACCF, 0x022A2F, 0x01264B, 0x01D7B5, 0x00F079,
|
||||
0x026F75, 0x01E9D9, 0x016127, 0x011EB8, 0x015DE9, 0x00B262, 0x00C57F, 0x006B2D,
|
||||
},
|
||||
{
|
||||
0x038000, 0x052876, 0x05C3CF, 0x07FF02, 0x04DBD9, 0x04A148, 0x07EDBA, 0x0722B4,
|
||||
0x03F000, 0x0317FB, 0x06117C, 0x04C491, 0x023FD5, 0x01258F, 0x0348BD, 0x01C209,
|
||||
0x060085, 0x04F0B9, 0x05EA87, 0x04A5F5, 0x036728, 0x01BC1C, 0x0333A8, 0x01A1DB,
|
||||
0x060085, 0x085336, 0x05A8AE, 0x07D960, 0x050800, 0x06FA82, 0x041FF9, 0x05B8AE,
|
||||
0x0692DA, 0x05EA87, 0x0563B2, 0x050D6E, 0x02F5AD, 0x046F00, 0x01B09C, 0x02580C,
|
||||
0x042D25, 0x03C235, 0x025D9B, 0x022108, 0x07D78F, 0x070EC1, 0x0764CA, 0x06A777,
|
||||
0x054000, 0x041FF9, 0x0477F9, 0x0382D0, 0x02D75E, 0x018242, 0x026B1D, 0x013B9F,
|
||||
0x03324A, 0x0282ED, 0x01CF83, 0x017851, 0x01CB42, 0x00EA21, 0x010336, 0x008CAC,
|
||||
},
|
||||
{
|
||||
0x040000, 0x05E519, 0x0696A4, 0x092370, 0x058D8A, 0x054A9C, 0x090FB0, 0x0827AA,
|
||||
0x048000, 0x03891F, 0x06EF69, 0x0572EE, 0x029218, 0x014F7E, 0x03C0D8, 0x020254,
|
||||
0x06DC05, 0x05A565, 0x06C2E4, 0x054FF3, 0x03E39B, 0x01FB8E, 0x03A8C0, 0x01DD8D,
|
||||
0x06DC05, 0x0983AC, 0x0677A2, 0x08F86E, 0x05C000, 0x07F9B9, 0x04B6D4, 0x0689EB,
|
||||
0x078343, 0x06C2E4, 0x0628CC, 0x05C635, 0x0361EA, 0x051124, 0x01EE69, 0x02ADC5,
|
||||
0x04C5E1, 0x044BAA, 0x02B41F, 0x026EE5, 0x08F65A, 0x0810DD, 0x087330, 0x079AD1,
|
||||
0x060000, 0x04B6D4, 0x051B65, 0x040337, 0x033F47, 0x01B970, 0x02C38F, 0x0168B6,
|
||||
0x03A730, 0x02DEC6, 0x0211BA, 0x01AE14, 0x020CDD, 0x010B93, 0x01283E, 0x00A0C4,
|
||||
},
|
||||
{
|
||||
0x050000, 0x075E60, 0x083C4D, 0x0B6C4C, 0x06F0ED, 0x069D43, 0x0B539C, 0x0A3194,
|
||||
0x05A000, 0x046B67, 0x08AB44, 0x06CFAA, 0x03369E, 0x01A35E, 0x04B10F, 0x0282E8,
|
||||
0x089307, 0x070EBF, 0x08739C, 0x06A3F0, 0x04DC82, 0x027A72, 0x0492F0, 0x0254F0,
|
||||
0x089307, 0x0BE497, 0x08158B, 0x0B3689, 0x073000, 0x09F827, 0x05E489, 0x082C66,
|
||||
0x096413, 0x08739C, 0x07B2FF, 0x0737C2, 0x043A64, 0x06556D, 0x026A04, 0x035936,
|
||||
0x05F75A, 0x055E94, 0x036127, 0x030A9E, 0x0B33F1, 0x0A1514, 0x0A8FFC, 0x098186,
|
||||
0x078000, 0x05E489, 0x06623F, 0x050405, 0x040F19, 0x0227CC, 0x037473, 0x01C2E3,
|
||||
0x0490FC, 0x039677, 0x029629, 0x021999, 0x029015, 0x014E78, 0x01724E, 0x00C8F5,
|
||||
},
|
||||
{
|
||||
0x060000, 0x08D7A6, 0x09E1F6, 0x0DB528, 0x085450, 0x07EFEA, 0x0D9788, 0x0C3B7E,
|
||||
0x06C000, 0x054DAE, 0x0A671E, 0x082C66, 0x03DB24, 0x01F73E, 0x05A145, 0x03037D,
|
||||
0x0A4A08, 0x087818, 0x0A2455, 0x07F7ED, 0x05D569, 0x02F955, 0x057D20, 0x02CC54,
|
||||
0x0A4A08, 0x0E4582, 0x09B373, 0x0D74A5, 0x08A000, 0x0BF696, 0x07123E, 0x09CEE0,
|
||||
0x0B44E4, 0x0A2455, 0x093D32, 0x08A950, 0x0512DF, 0x0799B6, 0x02E59E, 0x0404A7,
|
||||
0x0728D2, 0x06717F, 0x040E2F, 0x03A657, 0x0D7187, 0x0C194B, 0x0CACC8, 0x0B683A,
|
||||
0x090000, 0x07123E, 0x07A918, 0x0604D2, 0x04DEEA, 0x029629, 0x042556, 0x021D11,
|
||||
0x057AC8, 0x044E28, 0x031A97, 0x02851E, 0x03134C, 0x01915C, 0x01BC5D, 0x00F126,
|
||||
},
|
||||
{
|
||||
0x080000, 0x0BCA33, 0x0D2D48, 0x1246E0, 0x0B1B15, 0x0A9538, 0x121F5F, 0x104F53,
|
||||
0x090000, 0x07123E, 0x0DDED2, 0x0AE5DD, 0x052430, 0x029EFD, 0x0781B1, 0x0404A7,
|
||||
0x0DB80B, 0x0B4ACB, 0x0D85C7, 0x0A9FE7, 0x07C736, 0x03F71D, 0x075180, 0x03BB1A,
|
||||
0x0DB80B, 0x130757, 0x0CEF44, 0x11F0DC, 0x0B8000, 0x0FF372, 0x096DA8, 0x0D13D6,
|
||||
0x0F0686, 0x0D85C7, 0x0C5198, 0x0B8C6A, 0x06C3D4, 0x0A2248, 0x03DCD3, 0x055B8A,
|
||||
0x098BC3, 0x089754, 0x05683E, 0x04DDC9, 0x11ECB4, 0x1021B9, 0x10E661, 0x0F35A3,
|
||||
0x0C0000, 0x096DA8, 0x0A36CB, 0x08066E, 0x067E8E, 0x0372E1, 0x05871E, 0x02D16B,
|
||||
0x074E60, 0x05BD8B, 0x042374, 0x035C28, 0x0419BB, 0x021726, 0x02507C, 0x014188,
|
||||
},
|
||||
{
|
||||
0x0C0000, 0x11AF4C, 0x13C3EC, 0x1B6A50, 0x10A89F, 0x0FDFD4, 0x1B2F0F, 0x1876FD,
|
||||
0x0D8000, 0x0A9B5D, 0x14CE3C, 0x1058CB, 0x07B649, 0x03EE7B, 0x0B4289, 0x0606FB,
|
||||
0x149410, 0x10F030, 0x1448AB, 0x0FEFDA, 0x0BAAD2, 0x05F2AB, 0x0AFA40, 0x0598A7,
|
||||
0x149410, 0x1C8B03, 0x1366E6, 0x1AE949, 0x114000, 0x17ED2B, 0x0E247C, 0x139DC1,
|
||||
0x1689C8, 0x1448AB, 0x127A63, 0x11529F, 0x0A25BE, 0x0F336D, 0x05CB3C, 0x08094E,
|
||||
0x0E51A4, 0x0CE2FE, 0x081C5D, 0x074CAE, 0x1AE30E, 0x183296, 0x195991, 0x16D074,
|
||||
0x120000, 0x0E247C, 0x0F5230, 0x0C09A5, 0x09BDD5, 0x052C51, 0x084AAC, 0x043A21,
|
||||
0x0AF590, 0x089C51, 0x06352E, 0x050A3B, 0x062698, 0x0322B9, 0x0378BA, 0x01E24D,
|
||||
},
|
||||
{
|
||||
0x110000, 0x190DAC, 0x1C0039, 0x26D69C, 0x17998C, 0x167D16, 0x2682AB, 0x22A891,
|
||||
0x132000, 0x0F06C3, 0x1D797F, 0x172876, 0x0AECE7, 0x0591D9, 0x0FF398, 0x0889E3,
|
||||
0x1D2717, 0x17FEEF, 0x1CBC47, 0x1693CA, 0x108754, 0x086D1D, 0x0F8D30, 0x07ED98,
|
||||
0x1D2717, 0x286F9A, 0x1B7C71, 0x261FD3, 0x187000, 0x21E552, 0x140904, 0x1BCA27,
|
||||
0x1FEDDC, 0x1CBC47, 0x1A2D62, 0x188A62, 0x0E6022, 0x1588DA, 0x083540, 0x0B6284,
|
||||
0x1448FE, 0x124192, 0x0B7D84, 0x0A574B, 0x2616FF, 0x2247AA, 0x23E98D, 0x2051FA,
|
||||
0x198000, 0x140904, 0x15B46F, 0x110DAA, 0x0DCCEE, 0x07541E, 0x0BBF1F, 0x05FD04,
|
||||
0x0F868B, 0x0C32C8, 0x08CB57, 0x0723D4, 0x08B6AD, 0x047130, 0x04EB08, 0x02AB42,
|
||||
},
|
||||
{
|
||||
0x160000, 0x206C0C, 0x243C86, 0x3242E8, 0x1E8A79, 0x1D1A59, 0x31D646, 0x2CDA25,
|
||||
0x18C000, 0x13722A, 0x2624C3, 0x1DF820, 0x0E2385, 0x073537, 0x14A4A7, 0x0B0CCC,
|
||||
0x25BA1D, 0x1F0DAE, 0x252FE4, 0x1D37BB, 0x1563D6, 0x0AE78E, 0x142021, 0x0A4288,
|
||||
0x25BA1D, 0x345430, 0x2391FB, 0x31565C, 0x1FA000, 0x2BDD7A, 0x19ED8D, 0x23F68C,
|
||||
0x2951EF, 0x252FE4, 0x21E061, 0x1FC224, 0x129A87, 0x1BDE47, 0x0A9F44, 0x0EBBBA,
|
||||
0x1A4058, 0x17A026, 0x0EDEAB, 0x0D61E9, 0x314AEF, 0x2C5CBE, 0x2E798A, 0x29D380,
|
||||
0x210000, 0x19ED8D, 0x1C16AE, 0x1611AE, 0x11DC06, 0x097BEA, 0x0F3391, 0x07BFE7,
|
||||
0x141787, 0x0FC93E, 0x0B617F, 0x093D6D, 0x0B46C1, 0x05BFA8, 0x065D55, 0x037437,
|
||||
},
|
||||
{
|
||||
0x1C0000, 0x2943B2, 0x2E1E7C, 0x3FF810, 0x26DEC9, 0x250A43, 0x3F6DCE, 0x3915A3,
|
||||
0x1F8000, 0x18BFD8, 0x308BE1, 0x262485, 0x11FEA9, 0x092C75, 0x1A45EB, 0x0E1049,
|
||||
0x300425, 0x2785C6, 0x2F5439, 0x252FA8, 0x1B393F, 0x0DE0E4, 0x199D41, 0x0D0EDC,
|
||||
0x300425, 0x4299B2, 0x2D456E, 0x3ECB00, 0x284000, 0x37D40F, 0x20FFCB, 0x2DC56D,
|
||||
0x3496D3, 0x2F5439, 0x2B1D93, 0x286B74, 0x17AD66, 0x2377FE, 0x0D84E2, 0x12C062,
|
||||
0x21692A, 0x1E11A5, 0x12ECDA, 0x110840, 0x3EBC76, 0x387608, 0x3B2652, 0x353BBA,
|
||||
0x2A0000, 0x20FFCB, 0x23BFC6, 0x1C1681, 0x16BAF1, 0x0C1213, 0x1358E8, 0x09DCF8,
|
||||
0x19924F, 0x141767, 0x0E7C16, 0x0BC28A, 0x0E5A0D, 0x075104, 0x0819B2, 0x04655D,
|
||||
},
|
||||
{
|
||||
0x220000, 0x321B58, 0x380072, 0x4DAD38, 0x2F3318, 0x2CFA2D, 0x4D0556, 0x455122,
|
||||
0x264000, 0x1E0D86, 0x3AF2FE, 0x2E50EB, 0x15D9CE, 0x0B23B2, 0x1FE730, 0x1113C7,
|
||||
0x3A4E2D, 0x2FFDDF, 0x39788E, 0x2D2795, 0x210EA8, 0x10DA39, 0x1F1A61, 0x0FDB2F,
|
||||
0x3A4E2D, 0x50DF33, 0x36F8E1, 0x4C3FA5, 0x30E000, 0x43CAA5, 0x281209, 0x37944D,
|
||||
0x3FDBB7, 0x39788E, 0x345AC4, 0x3114C3, 0x1CC044, 0x2B11B4, 0x106A80, 0x16C509,
|
||||
0x2891FC, 0x248324, 0x16FB08, 0x14AE97, 0x4C2DFD, 0x448F54, 0x47D31B, 0x40A3F5,
|
||||
0x330000, 0x281209, 0x2B68DF, 0x221B53, 0x1B99DB, 0x0EA83B, 0x177E3E, 0x0BFA09,
|
||||
0x1F0D17, 0x18658F, 0x1196AE, 0x0E47A8, 0x116D5A, 0x08E260, 0x09D60F, 0x055684,
|
||||
},
|
||||
{
|
||||
0x2C0000, 0x40D818, 0x48790C, 0x6485D0, 0x3D14F2, 0x3A34B2, 0x63AC8D, 0x59B44A,
|
||||
0x318000, 0x26E454, 0x4C4986, 0x3BF03F, 0x1C470A, 0x0E6A6E, 0x29494D, 0x161998,
|
||||
0x4B743A, 0x3E1B5C, 0x4A5FC7, 0x3A6F75, 0x2AC7AC, 0x15CF1D, 0x284041, 0x148510,
|
||||
0x4B743A, 0x68A861, 0x4723F6, 0x62ACB8, 0x3F4000, 0x57BAF3, 0x33DB1A, 0x47ED19,
|
||||
0x52A3DE, 0x4A5FC7, 0x43C0C2, 0x3F8448, 0x25350D, 0x37BC8E, 0x153E87, 0x1D7775,
|
||||
0x3480B0, 0x2F404C, 0x1DBD56, 0x1AC3D2, 0x6295DE, 0x58B97B, 0x5CF313, 0x53A701,
|
||||
0x420000, 0x33DB1A, 0x382D5C, 0x2C235D, 0x23B80D, 0x12F7D4, 0x1E6723, 0x0F7FCF,
|
||||
0x282F0E, 0x1F927D, 0x16C2FF, 0x127AD9, 0x168D83, 0x0B7F50, 0x0CBAAA, 0x06E86E,
|
||||
},
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_BINKDATA_H */
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Bink IDCT algorithm
|
||||
* Copyright (c) 2009 Kostya Shishkov
|
||||
*
|
||||
* 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
|
||||
* Bink IDCT algorithm
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
|
||||
#define A1 2896 /* (1/sqrt(2))<<12 */
|
||||
#define A2 2217
|
||||
#define A3 3784
|
||||
#define A4 -5352
|
||||
|
||||
#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
|
||||
const int a0 = (src)[s0] + (src)[s4]; \
|
||||
const int a1 = (src)[s0] - (src)[s4]; \
|
||||
const int a2 = (src)[s2] + (src)[s6]; \
|
||||
const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
|
||||
const int a4 = (src)[s5] + (src)[s3]; \
|
||||
const int a5 = (src)[s5] - (src)[s3]; \
|
||||
const int a6 = (src)[s1] + (src)[s7]; \
|
||||
const int a7 = (src)[s1] - (src)[s7]; \
|
||||
const int b0 = a4 + a6; \
|
||||
const int b1 = (A3*(a5 + a7)) >> 11; \
|
||||
const int b2 = ((A4*a5) >> 11) - b0 + b1; \
|
||||
const int b3 = (A1*(a6 - a4) >> 11) - b2; \
|
||||
const int b4 = ((A2*a7) >> 11) + b3 - b1; \
|
||||
(dest)[d0] = munge(a0+a2 +b0); \
|
||||
(dest)[d1] = munge(a1+a3-a2+b2); \
|
||||
(dest)[d2] = munge(a1-a3+a2+b3); \
|
||||
(dest)[d3] = munge(a0-a2 -b4); \
|
||||
(dest)[d4] = munge(a0-a2 +b4); \
|
||||
(dest)[d5] = munge(a1-a3+a2-b3); \
|
||||
(dest)[d6] = munge(a1+a3-a2-b2); \
|
||||
(dest)[d7] = munge(a0+a2 -b0); \
|
||||
}
|
||||
/* end IDCT_TRANSFORM macro */
|
||||
|
||||
#define MUNGE_NONE(x) (x)
|
||||
#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
|
||||
|
||||
#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
|
||||
#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
|
||||
|
||||
static inline void bink_idct_col(DCTELEM *dest, const DCTELEM *src)
|
||||
{
|
||||
if ((src[8]|src[16]|src[24]|src[32]|src[40]|src[48]|src[56])==0) {
|
||||
dest[0] =
|
||||
dest[8] =
|
||||
dest[16] =
|
||||
dest[24] =
|
||||
dest[32] =
|
||||
dest[40] =
|
||||
dest[48] =
|
||||
dest[56] = src[0];
|
||||
} else {
|
||||
IDCT_COL(dest, src);
|
||||
}
|
||||
}
|
||||
|
||||
void ff_bink_idct_c(DCTELEM *block)
|
||||
{
|
||||
int i;
|
||||
DCTELEM temp[64];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
bink_idct_col(&temp[i], &block[i]);
|
||||
for (i = 0; i < 8; i++) {
|
||||
IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
|
||||
}
|
||||
}
|
||||
|
||||
void ff_bink_idct_add_c(uint8_t *dest, int linesize, DCTELEM *block)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
ff_bink_idct_c(block);
|
||||
for (i = 0; i < 8; i++, dest += linesize, block += 8)
|
||||
for (j = 0; j < 8; j++)
|
||||
dest[j] += block[j];
|
||||
}
|
||||
|
||||
void ff_bink_idct_put_c(uint8_t *dest, int linesize, DCTELEM *block)
|
||||
{
|
||||
int i;
|
||||
DCTELEM temp[64];
|
||||
for (i = 0; i < 8; i++)
|
||||
bink_idct_col(&temp[i], &block[i]);
|
||||
for (i = 0; i < 8; i++) {
|
||||
IDCT_ROW( (&dest[i*linesize]), (&temp[8*i]) );
|
||||
}
|
||||
}
|
||||
@@ -1,482 +0,0 @@
|
||||
/*
|
||||
* Common bit i/o utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2010 Loren Merritt
|
||||
*
|
||||
* alternative bitstream reader & writer by 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
|
||||
* bitstream api.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
#include "put_bits.h"
|
||||
|
||||
const uint8_t ff_log2_run[32]={
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 5, 5, 6, 6, 7, 7,
|
||||
8, 9,10,11,12,13,14,15
|
||||
};
|
||||
|
||||
void align_put_bits(PutBitContext *s)
|
||||
{
|
||||
#ifdef ALT_BITSTREAM_WRITER
|
||||
put_bits(s,( - s->index) & 7,0);
|
||||
#else
|
||||
put_bits(s,s->bit_left & 7,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ff_put_string(PutBitContext *pb, const char *string, int terminate_string)
|
||||
{
|
||||
while(*string){
|
||||
put_bits(pb, 8, *string);
|
||||
string++;
|
||||
}
|
||||
if(terminate_string)
|
||||
put_bits(pb, 8, 0);
|
||||
}
|
||||
|
||||
void ff_copy_bits(PutBitContext *pb, const uint8_t *src, int length)
|
||||
{
|
||||
int words= length>>4;
|
||||
int bits= length&15;
|
||||
int i;
|
||||
|
||||
if(length==0) return;
|
||||
|
||||
if(CONFIG_SMALL || words < 16 || put_bits_count(pb)&7){
|
||||
for(i=0; i<words; i++) put_bits(pb, 16, AV_RB16(src + 2*i));
|
||||
}else{
|
||||
for(i=0; put_bits_count(pb)&31; i++)
|
||||
put_bits(pb, 8, src[i]);
|
||||
flush_put_bits(pb);
|
||||
memcpy(put_bits_ptr(pb), src+i, 2*words-i);
|
||||
skip_put_bytes(pb, 2*words-i);
|
||||
}
|
||||
|
||||
put_bits(pb, bits, AV_RB16(src + 2*words)>>(16-bits));
|
||||
}
|
||||
|
||||
/* VLC decoding */
|
||||
|
||||
//#define DEBUG_VLC
|
||||
|
||||
#define GET_DATA(v, table, i, wrap, size) \
|
||||
{\
|
||||
const uint8_t *ptr = (const uint8_t *)table + i * wrap;\
|
||||
switch(size) {\
|
||||
case 1:\
|
||||
v = *(const uint8_t *)ptr;\
|
||||
break;\
|
||||
case 2:\
|
||||
v = *(const uint16_t *)ptr;\
|
||||
break;\
|
||||
default:\
|
||||
v = *(const uint32_t *)ptr;\
|
||||
break;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
static int alloc_table(VLC *vlc, int size, int use_static)
|
||||
{
|
||||
int index;
|
||||
index = vlc->table_size;
|
||||
vlc->table_size += size;
|
||||
if (vlc->table_size > vlc->table_allocated) {
|
||||
if(use_static)
|
||||
abort(); //cant do anything, init_vlc() is used with too little memory
|
||||
vlc->table_allocated += (1 << vlc->bits);
|
||||
vlc->table = av_realloc(vlc->table,
|
||||
sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
|
||||
if (!vlc->table)
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
static av_always_inline uint32_t bitswap_32(uint32_t x) {
|
||||
return av_reverse[x&0xFF]<<24
|
||||
| av_reverse[(x>>8)&0xFF]<<16
|
||||
| av_reverse[(x>>16)&0xFF]<<8
|
||||
| av_reverse[x>>24];
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t bits;
|
||||
uint16_t symbol;
|
||||
/** codeword, with the first bit-to-be-read in the msb
|
||||
* (even if intended for a little-endian bitstream reader) */
|
||||
uint32_t code;
|
||||
} VLCcode;
|
||||
|
||||
static int compare_vlcspec(const void *a, const void *b)
|
||||
{
|
||||
const VLCcode *sa=a, *sb=b;
|
||||
return (sa->code >> 1) - (sb->code >> 1);
|
||||
}
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
/**
|
||||
* Build VLC decoding tables suitable for use with get_vlc().
|
||||
*
|
||||
* @param vlc the context to be initted
|
||||
*
|
||||
* @param table_nb_bits max length of vlc codes to store directly in this table
|
||||
* (Longer codes are delegated to subtables.)
|
||||
*
|
||||
* @param nb_codes number of elements in codes[]
|
||||
*
|
||||
* @param codes descriptions of the vlc codes
|
||||
* These must be ordered such that codes going into the same subtable are contiguous.
|
||||
* Sorting by VLCcode.code is sufficient, though not necessary.
|
||||
*/
|
||||
static int build_table(VLC *vlc, int table_nb_bits, int nb_codes,
|
||||
VLCcode *codes, int flags)
|
||||
{
|
||||
int table_size, table_index, index, code_prefix, symbol, subtable_bits;
|
||||
int i, j, k, n, nb, inc;
|
||||
uint32_t code;
|
||||
VLC_TYPE (*table)[2];
|
||||
|
||||
table_size = 1 << table_nb_bits;
|
||||
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d\n",
|
||||
table_index, table_size);
|
||||
#endif
|
||||
if (table_index < 0)
|
||||
return -1;
|
||||
table = &vlc->table[table_index];
|
||||
|
||||
for (i = 0; i < table_size; i++) {
|
||||
table[i][1] = 0; //bits
|
||||
table[i][0] = -1; //codes
|
||||
}
|
||||
|
||||
/* first pass: map codes and compute auxillary table sizes */
|
||||
for (i = 0; i < nb_codes; i++) {
|
||||
n = codes[i].bits;
|
||||
code = codes[i].code;
|
||||
symbol = codes[i].symbol;
|
||||
#if defined(DEBUG_VLC) && 0
|
||||
av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code);
|
||||
#endif
|
||||
if (n <= table_nb_bits) {
|
||||
/* no need to add another table */
|
||||
j = code >> (32 - table_nb_bits);
|
||||
nb = 1 << (table_nb_bits - n);
|
||||
inc = 1;
|
||||
if (flags & INIT_VLC_LE) {
|
||||
j = bitswap_32(code);
|
||||
inc = 1 << n;
|
||||
}
|
||||
for (k = 0; k < nb; k++) {
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n",
|
||||
j, i, n);
|
||||
#endif
|
||||
if (table[j][1] /*bits*/ != 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
|
||||
return -1;
|
||||
}
|
||||
table[j][1] = n; //bits
|
||||
table[j][0] = symbol;
|
||||
j += inc;
|
||||
}
|
||||
} else {
|
||||
/* fill auxiliary table recursively */
|
||||
n -= table_nb_bits;
|
||||
code_prefix = code >> (32 - table_nb_bits);
|
||||
subtable_bits = n;
|
||||
codes[i].bits = n;
|
||||
codes[i].code = code << table_nb_bits;
|
||||
for (k = i+1; k < nb_codes; k++) {
|
||||
n = codes[k].bits - table_nb_bits;
|
||||
if (n <= 0)
|
||||
break;
|
||||
code = codes[k].code;
|
||||
if (code >> (32 - table_nb_bits) != code_prefix)
|
||||
break;
|
||||
codes[k].bits = n;
|
||||
codes[k].code = code << table_nb_bits;
|
||||
subtable_bits = FFMAX(subtable_bits, n);
|
||||
}
|
||||
subtable_bits = FFMIN(subtable_bits, table_nb_bits);
|
||||
j = (flags & INIT_VLC_LE) ? bitswap_32(code_prefix) >> (32 - table_nb_bits) : code_prefix;
|
||||
table[j][1] = -subtable_bits;
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n",
|
||||
j, codes[i].bits + table_nb_bits);
|
||||
#endif
|
||||
index = build_table(vlc, subtable_bits, k-i, codes+i, flags);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
/* note: realloc has been done, so reload tables */
|
||||
table = &vlc->table[table_index];
|
||||
table[j][0] = index; //code
|
||||
i = k-1;
|
||||
}
|
||||
}
|
||||
return table_index;
|
||||
}
|
||||
|
||||
|
||||
/* Build VLC decoding tables suitable for use with get_vlc().
|
||||
|
||||
'nb_bits' set thee decoding table size (2^nb_bits) entries. The
|
||||
bigger it is, the faster is the decoding. But it should not be too
|
||||
big to save memory and L1 cache. '9' is a good compromise.
|
||||
|
||||
'nb_codes' : number of vlcs codes
|
||||
|
||||
'bits' : table which gives the size (in bits) of each vlc code.
|
||||
|
||||
'codes' : table which gives the bit pattern of of each vlc code.
|
||||
|
||||
'symbols' : table which gives the values to be returned from get_vlc().
|
||||
|
||||
'xxx_wrap' : give the number of bytes between each entry of the
|
||||
'bits' or 'codes' tables.
|
||||
|
||||
'xxx_size' : gives the number of bytes of each entry of the 'bits'
|
||||
or 'codes' tables.
|
||||
|
||||
'wrap' and 'size' allows to use any memory configuration and types
|
||||
(byte/word/long) to store the 'bits', 'codes', and 'symbols' tables.
|
||||
|
||||
'use_static' should be set to 1 for tables, which should be freed
|
||||
with av_free_static(), 0 if free_vlc() will be used.
|
||||
*/
|
||||
int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
const void *symbols, int symbols_wrap, int symbols_size,
|
||||
int flags)
|
||||
{
|
||||
VLCcode buf[nb_codes];
|
||||
int i, j;
|
||||
|
||||
vlc->bits = nb_bits;
|
||||
if(flags & INIT_VLC_USE_NEW_STATIC){
|
||||
if(vlc->table_size && vlc->table_size == vlc->table_allocated){
|
||||
return 0;
|
||||
}else if(vlc->table_size){
|
||||
abort(); // fatal error, we are called on a partially initialized table
|
||||
}
|
||||
}else {
|
||||
vlc->table = NULL;
|
||||
vlc->table_allocated = 0;
|
||||
vlc->table_size = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes);
|
||||
#endif
|
||||
|
||||
assert(symbols_size <= 2 || !symbols);
|
||||
j = 0;
|
||||
#define COPY(condition)\
|
||||
for (i = 0; i < nb_codes; i++) {\
|
||||
GET_DATA(buf[j].bits, bits, i, bits_wrap, bits_size);\
|
||||
if (!(condition))\
|
||||
continue;\
|
||||
GET_DATA(buf[j].code, codes, i, codes_wrap, codes_size);\
|
||||
if (flags & INIT_VLC_LE)\
|
||||
buf[j].code = bitswap_32(buf[j].code);\
|
||||
else\
|
||||
buf[j].code <<= 32 - buf[j].bits;\
|
||||
if (symbols)\
|
||||
GET_DATA(buf[j].symbol, symbols, i, symbols_wrap, symbols_size)\
|
||||
else\
|
||||
buf[j].symbol = i;\
|
||||
j++;\
|
||||
}
|
||||
COPY(buf[j].bits > nb_bits);
|
||||
// qsort is the slowest part of init_vlc, and could probably be improved or avoided
|
||||
qsort(buf, j, sizeof(VLCcode), compare_vlcspec);
|
||||
COPY(buf[j].bits && buf[j].bits <= nb_bits);
|
||||
nb_codes = j;
|
||||
|
||||
if (build_table(vlc, nb_bits, nb_codes, buf, flags) < 0) {
|
||||
av_freep(&vlc->table);
|
||||
return -1;
|
||||
}
|
||||
if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
|
||||
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
static int build_table(VLC *vlc, int table_nb_bits,
|
||||
int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
const void *symbols, int symbols_wrap, int symbols_size,
|
||||
uint32_t code_prefix, int n_prefix, int flags)
|
||||
{
|
||||
int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2, symbol;
|
||||
uint32_t code;
|
||||
VLC_TYPE (*table)[2];
|
||||
|
||||
table_size = 1 << table_nb_bits;
|
||||
table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d code_prefix=%x n=%d\n",
|
||||
table_index, table_size, code_prefix, n_prefix);
|
||||
#endif
|
||||
if (table_index < 0)
|
||||
return -1;
|
||||
table = &vlc->table[table_index];
|
||||
|
||||
for(i=0;i<table_size;i++) {
|
||||
table[i][1] = 0; //bits
|
||||
table[i][0] = -1; //codes
|
||||
}
|
||||
|
||||
/* first pass: map codes and compute auxillary table sizes */
|
||||
for(i=0;i<nb_codes;i++) {
|
||||
GET_DATA(n, bits, i, bits_wrap, bits_size);
|
||||
GET_DATA(code, codes, i, codes_wrap, codes_size);
|
||||
/* we accept tables with holes */
|
||||
if (n <= 0)
|
||||
continue;
|
||||
if (!symbols)
|
||||
symbol = i;
|
||||
else
|
||||
GET_DATA(symbol, symbols, i, symbols_wrap, symbols_size);
|
||||
#if defined(DEBUG_VLC) && 0
|
||||
av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code);
|
||||
#endif
|
||||
/* if code matches the prefix, it is in the table */
|
||||
n -= n_prefix;
|
||||
if(flags & INIT_VLC_LE)
|
||||
code_prefix2= code & (n_prefix>=32 ? 0xffffffff : (1 << n_prefix)-1);
|
||||
else
|
||||
code_prefix2= code >> n;
|
||||
if (n > 0 && code_prefix2 == code_prefix) {
|
||||
if (n <= table_nb_bits) {
|
||||
/* no need to add another table */
|
||||
j = (code << (table_nb_bits - n)) & (table_size - 1);
|
||||
nb = 1 << (table_nb_bits - n);
|
||||
for(k=0;k<nb;k++) {
|
||||
if(flags & INIT_VLC_LE)
|
||||
j = (code >> n_prefix) + (k<<n);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n",
|
||||
j, i, n);
|
||||
#endif
|
||||
if (table[j][1] /*bits*/ != 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");
|
||||
return -1;
|
||||
}
|
||||
table[j][1] = n; //bits
|
||||
table[j][0] = symbol;
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
n -= table_nb_bits;
|
||||
j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n",
|
||||
j, n);
|
||||
#endif
|
||||
/* compute table size */
|
||||
n1 = -table[j][1]; //bits
|
||||
if (n > n1)
|
||||
n1 = n;
|
||||
table[j][1] = -n1; //bits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* second pass : fill auxillary tables recursively */
|
||||
for(i=0;i<table_size;i++) {
|
||||
n = table[i][1]; //bits
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
if (n > table_nb_bits) {
|
||||
n = table_nb_bits;
|
||||
table[i][1] = -n; //bits
|
||||
}
|
||||
index = build_table(vlc, n, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
symbols, symbols_wrap, symbols_size,
|
||||
(flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i),
|
||||
n_prefix + table_nb_bits, flags);
|
||||
if (index < 0)
|
||||
return -1;
|
||||
/* note: realloc has been done, so reload tables */
|
||||
table = &vlc->table[table_index];
|
||||
table[i][0] = index; //code
|
||||
}
|
||||
}
|
||||
return table_index;
|
||||
}
|
||||
|
||||
int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
|
||||
const void *bits, int bits_wrap, int bits_size,
|
||||
const void *codes, int codes_wrap, int codes_size,
|
||||
const void *symbols, int symbols_wrap, int symbols_size,
|
||||
int flags)
|
||||
{
|
||||
vlc->bits = nb_bits;
|
||||
if(flags & INIT_VLC_USE_NEW_STATIC){
|
||||
if(vlc->table_size && vlc->table_size == vlc->table_allocated){
|
||||
return 0;
|
||||
}else if(vlc->table_size){
|
||||
abort(); // fatal error, we are called on a partially initialized table
|
||||
}
|
||||
}else {
|
||||
vlc->table = NULL;
|
||||
vlc->table_allocated = 0;
|
||||
vlc->table_size = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VLC
|
||||
av_log(NULL,AV_LOG_DEBUG,"build table nb_codes=%d\n", nb_codes);
|
||||
#endif
|
||||
|
||||
if (build_table(vlc, nb_bits, nb_codes,
|
||||
bits, bits_wrap, bits_size,
|
||||
codes, codes_wrap, codes_size,
|
||||
symbols, symbols_wrap, symbols_size,
|
||||
0, 0, flags) < 0) {
|
||||
av_freep(&vlc->table);
|
||||
return -1;
|
||||
}
|
||||
if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
|
||||
av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
|
||||
return 0;
|
||||
}
|
||||
#endif // GCC2 version
|
||||
|
||||
|
||||
void free_vlc(VLC *vlc)
|
||||
{
|
||||
av_freep(&vlc->table);
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
static AVBitStreamFilter *first_bitstream_filter= NULL;
|
||||
|
||||
AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f){
|
||||
if(f) return f->next;
|
||||
else return first_bitstream_filter;
|
||||
}
|
||||
|
||||
void av_register_bitstream_filter(AVBitStreamFilter *bsf){
|
||||
bsf->next = first_bitstream_filter;
|
||||
first_bitstream_filter= bsf;
|
||||
}
|
||||
|
||||
AVBitStreamFilterContext *av_bitstream_filter_init(const char *name){
|
||||
AVBitStreamFilter *bsf= first_bitstream_filter;
|
||||
|
||||
while(bsf){
|
||||
if(!strcmp(name, bsf->name)){
|
||||
AVBitStreamFilterContext *bsfc= av_mallocz(sizeof(AVBitStreamFilterContext));
|
||||
bsfc->filter= bsf;
|
||||
bsfc->priv_data= av_mallocz(bsf->priv_data_size);
|
||||
return bsfc;
|
||||
}
|
||||
bsf= bsf->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc){
|
||||
if(bsfc->filter->close)
|
||||
bsfc->filter->close(bsfc);
|
||||
av_freep(&bsfc->priv_data);
|
||||
av_parser_close(bsfc->parser);
|
||||
av_free(bsfc);
|
||||
}
|
||||
|
||||
int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
|
||||
AVCodecContext *avctx, const char *args,
|
||||
uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size, int keyframe){
|
||||
*poutbuf= (uint8_t *) buf;
|
||||
*poutbuf_size= buf_size;
|
||||
return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size, buf, buf_size, keyframe);
|
||||
}
|
||||
@@ -1,349 +0,0 @@
|
||||
/*
|
||||
* BMP image format decoder
|
||||
* Copyright (c) 2005 Mans Rullgard
|
||||
*
|
||||
* 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 "bytestream.h"
|
||||
#include "bmp.h"
|
||||
#include "msrledec.h"
|
||||
|
||||
static av_cold int bmp_decode_init(AVCodecContext *avctx){
|
||||
BMPContext *s = avctx->priv_data;
|
||||
|
||||
avcodec_get_frame_defaults((AVFrame*)&s->picture);
|
||||
avctx->coded_frame = (AVFrame*)&s->picture;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bmp_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
BMPContext *s = avctx->priv_data;
|
||||
AVFrame *picture = data;
|
||||
AVFrame *p = &s->picture;
|
||||
unsigned int fsize, hsize;
|
||||
int width, height;
|
||||
unsigned int depth;
|
||||
BiCompression comp;
|
||||
unsigned int ihsize;
|
||||
int i, j, n, linesize;
|
||||
uint32_t rgb[3];
|
||||
uint8_t *ptr;
|
||||
int dsize;
|
||||
const uint8_t *buf0 = buf;
|
||||
|
||||
if(buf_size < 14){
|
||||
av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(bytestream_get_byte(&buf) != 'B' ||
|
||||
bytestream_get_byte(&buf) != 'M') {
|
||||
av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fsize = bytestream_get_le32(&buf);
|
||||
if(buf_size < fsize){
|
||||
av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
|
||||
buf_size, fsize);
|
||||
fsize = buf_size;
|
||||
}
|
||||
|
||||
buf += 2; /* reserved1 */
|
||||
buf += 2; /* reserved2 */
|
||||
|
||||
hsize = bytestream_get_le32(&buf); /* header size */
|
||||
ihsize = bytestream_get_le32(&buf); /* more header size */
|
||||
if(ihsize + 14 > hsize){
|
||||
av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sometimes file size is set to some headers size, set a real size in that case */
|
||||
if(fsize == 14 || fsize == ihsize + 14)
|
||||
fsize = buf_size - 2;
|
||||
|
||||
if(fsize <= hsize){
|
||||
av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
|
||||
fsize, hsize);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(ihsize){
|
||||
case 40: // windib v3
|
||||
case 64: // OS/2 v2
|
||||
case 108: // windib v4
|
||||
case 124: // windib v5
|
||||
width = bytestream_get_le32(&buf);
|
||||
height = bytestream_get_le32(&buf);
|
||||
break;
|
||||
case 12: // OS/2 v1
|
||||
width = bytestream_get_le16(&buf);
|
||||
height = bytestream_get_le16(&buf);
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "unsupported BMP file, patch welcome\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(bytestream_get_le16(&buf) != 1){ /* planes */
|
||||
av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
depth = bytestream_get_le16(&buf);
|
||||
|
||||
if(ihsize == 40)
|
||||
comp = bytestream_get_le32(&buf);
|
||||
else
|
||||
comp = BMP_RGB;
|
||||
|
||||
if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){
|
||||
av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(comp == BMP_BITFIELDS){
|
||||
buf += 20;
|
||||
rgb[0] = bytestream_get_le32(&buf);
|
||||
rgb[1] = bytestream_get_le32(&buf);
|
||||
rgb[2] = bytestream_get_le32(&buf);
|
||||
}
|
||||
|
||||
avctx->width = width;
|
||||
avctx->height = height > 0? height: -height;
|
||||
|
||||
avctx->pix_fmt = PIX_FMT_NONE;
|
||||
|
||||
switch(depth){
|
||||
case 32:
|
||||
if(comp == BMP_BITFIELDS){
|
||||
rgb[0] = (rgb[0] >> 15) & 3;
|
||||
rgb[1] = (rgb[1] >> 15) & 3;
|
||||
rgb[2] = (rgb[2] >> 15) & 3;
|
||||
|
||||
if(rgb[0] + rgb[1] + rgb[2] != 3 ||
|
||||
rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
rgb[0] = 2;
|
||||
rgb[1] = 1;
|
||||
rgb[2] = 0;
|
||||
}
|
||||
|
||||
avctx->pix_fmt = PIX_FMT_BGR24;
|
||||
break;
|
||||
case 24:
|
||||
avctx->pix_fmt = PIX_FMT_BGR24;
|
||||
break;
|
||||
case 16:
|
||||
if(comp == BMP_RGB)
|
||||
avctx->pix_fmt = PIX_FMT_RGB555;
|
||||
if(comp == BMP_BITFIELDS)
|
||||
avctx->pix_fmt = rgb[1] == 0x07E0 ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
|
||||
break;
|
||||
case 8:
|
||||
if(hsize - ihsize - 14 > 0)
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
else
|
||||
avctx->pix_fmt = PIX_FMT_GRAY8;
|
||||
break;
|
||||
case 4:
|
||||
if(hsize - ihsize - 14 > 0){
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
}else{
|
||||
av_log(avctx, AV_LOG_ERROR, "Unknown palette for 16-colour BMP\n");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
avctx->pix_fmt = PIX_FMT_MONOBLACK;
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "depth %d not supported\n", depth);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(avctx->pix_fmt == PIX_FMT_NONE){
|
||||
av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(p->data[0])
|
||||
avctx->release_buffer(avctx, p);
|
||||
|
||||
p->reference = 0;
|
||||
if(avctx->get_buffer(avctx, p) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
p->pict_type = FF_I_TYPE;
|
||||
p->key_frame = 1;
|
||||
|
||||
buf = buf0 + hsize;
|
||||
dsize = buf_size - hsize;
|
||||
|
||||
/* Line size in file multiple of 4 */
|
||||
n = ((avctx->width * depth) / 8 + 3) & ~3;
|
||||
|
||||
if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
|
||||
av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
|
||||
dsize, n * avctx->height);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// RLE may skip decoding some picture areas, so blank picture before decoding
|
||||
if(comp == BMP_RLE4 || comp == BMP_RLE8)
|
||||
memset(p->data[0], 0, avctx->height * p->linesize[0]);
|
||||
|
||||
if(depth == 4 || depth == 8)
|
||||
memset(p->data[1], 0, 1024);
|
||||
|
||||
if(height > 0){
|
||||
ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
|
||||
linesize = -p->linesize[0];
|
||||
} else {
|
||||
ptr = p->data[0];
|
||||
linesize = p->linesize[0];
|
||||
}
|
||||
|
||||
if(avctx->pix_fmt == PIX_FMT_PAL8){
|
||||
int colors = 1 << depth;
|
||||
if(ihsize >= 36){
|
||||
int t;
|
||||
buf = buf0 + 46;
|
||||
t = bytestream_get_le32(&buf);
|
||||
if(t < 0 || t > (1 << depth)){
|
||||
av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
|
||||
}else if(t){
|
||||
colors = t;
|
||||
}
|
||||
}
|
||||
buf = buf0 + 14 + ihsize; //palette location
|
||||
if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry
|
||||
for(i = 0; i < colors; i++)
|
||||
((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
|
||||
}else{
|
||||
for(i = 0; i < colors; i++)
|
||||
((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
|
||||
}
|
||||
buf = buf0 + hsize;
|
||||
}
|
||||
if(comp == BMP_RLE4 || comp == BMP_RLE8){
|
||||
if(height < 0){
|
||||
p->data[0] += p->linesize[0] * (avctx->height - 1);
|
||||
p->linesize[0] = -p->linesize[0];
|
||||
}
|
||||
ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize);
|
||||
if(height < 0){
|
||||
p->data[0] += p->linesize[0] * (avctx->height - 1);
|
||||
p->linesize[0] = -p->linesize[0];
|
||||
}
|
||||
}else{
|
||||
switch(depth){
|
||||
case 1:
|
||||
case 8:
|
||||
case 24:
|
||||
for(i = 0; i < avctx->height; i++){
|
||||
memcpy(ptr, buf, n);
|
||||
buf += n;
|
||||
ptr += linesize;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for(i = 0; i < avctx->height; i++){
|
||||
int j;
|
||||
for(j = 0; j < n; j++){
|
||||
ptr[j*2+0] = (buf[j] >> 4) & 0xF;
|
||||
ptr[j*2+1] = buf[j] & 0xF;
|
||||
}
|
||||
buf += n;
|
||||
ptr += linesize;
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
for(i = 0; i < avctx->height; i++){
|
||||
const uint16_t *src = (const uint16_t *) buf;
|
||||
uint16_t *dst = (uint16_t *) ptr;
|
||||
|
||||
for(j = 0; j < avctx->width; j++)
|
||||
*dst++ = le2me_16(*src++);
|
||||
|
||||
buf += n;
|
||||
ptr += linesize;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
for(i = 0; i < avctx->height; i++){
|
||||
const uint8_t *src = buf;
|
||||
uint8_t *dst = ptr;
|
||||
|
||||
for(j = 0; j < avctx->width; j++){
|
||||
dst[0] = src[rgb[2]];
|
||||
dst[1] = src[rgb[1]];
|
||||
dst[2] = src[rgb[0]];
|
||||
dst += 3;
|
||||
src += 4;
|
||||
}
|
||||
|
||||
buf += n;
|
||||
ptr += linesize;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*picture = s->picture;
|
||||
*data_size = sizeof(AVPicture);
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
static av_cold int bmp_decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
BMPContext* c = avctx->priv_data;
|
||||
|
||||
if (c->picture.data[0])
|
||||
avctx->release_buffer(avctx, &c->picture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec bmp_decoder = {
|
||||
"bmp",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_BMP,
|
||||
sizeof(BMPContext),
|
||||
bmp_decode_init,
|
||||
NULL,
|
||||
bmp_decode_end,
|
||||
bmp_decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("BMP image"),
|
||||
};
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* internals for BMP codecs
|
||||
* Copyright (c) 2005 Mans Rullgard
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_BMP_H
|
||||
#define AVCODEC_BMP_H
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
typedef struct BMPContext {
|
||||
AVFrame picture;
|
||||
} BMPContext;
|
||||
|
||||
typedef enum {
|
||||
BMP_RGB =0,
|
||||
BMP_RLE8 =1,
|
||||
BMP_RLE4 =2,
|
||||
BMP_BITFIELDS =3,
|
||||
} BiCompression;
|
||||
|
||||
#endif /* AVCODEC_BMP_H */
|
||||
@@ -1,149 +0,0 @@
|
||||
/*
|
||||
* BMP image format encoder
|
||||
* Copyright (c) 2006, 2007 Michel Bardiaux
|
||||
* Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
|
||||
*
|
||||
* 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 "bytestream.h"
|
||||
#include "bmp.h"
|
||||
|
||||
static const uint32_t monoblack_pal[] = { 0x000000, 0xFFFFFF };
|
||||
static const uint32_t rgb565_masks[] = { 0xF800, 0x07E0, 0x001F };
|
||||
|
||||
static av_cold int bmp_encode_init(AVCodecContext *avctx){
|
||||
BMPContext *s = avctx->priv_data;
|
||||
|
||||
avcodec_get_frame_defaults((AVFrame*)&s->picture);
|
||||
avctx->coded_frame = (AVFrame*)&s->picture;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bmp_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
|
||||
BMPContext *s = avctx->priv_data;
|
||||
AVFrame *pict = data;
|
||||
AVFrame * const p= (AVFrame*)&s->picture;
|
||||
int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize;
|
||||
const uint32_t *pal = NULL;
|
||||
int pad_bytes_per_row, bit_count, pal_entries = 0, compression = BMP_RGB;
|
||||
uint8_t *ptr;
|
||||
unsigned char* buf0 = buf;
|
||||
*p = *pict;
|
||||
p->pict_type= FF_I_TYPE;
|
||||
p->key_frame= 1;
|
||||
switch (avctx->pix_fmt) {
|
||||
case PIX_FMT_BGR24:
|
||||
bit_count = 24;
|
||||
break;
|
||||
case PIX_FMT_RGB555:
|
||||
bit_count = 16;
|
||||
break;
|
||||
case PIX_FMT_RGB565:
|
||||
bit_count = 16;
|
||||
compression = BMP_BITFIELDS;
|
||||
pal = rgb565_masks; // abuse pal to hold color masks
|
||||
pal_entries = 3;
|
||||
break;
|
||||
case PIX_FMT_RGB8:
|
||||
case PIX_FMT_BGR8:
|
||||
case PIX_FMT_RGB4_BYTE:
|
||||
case PIX_FMT_BGR4_BYTE:
|
||||
case PIX_FMT_GRAY8:
|
||||
case PIX_FMT_PAL8:
|
||||
bit_count = 8;
|
||||
pal = (uint32_t *)p->data[1];
|
||||
break;
|
||||
case PIX_FMT_MONOBLACK:
|
||||
bit_count = 1;
|
||||
pal = monoblack_pal;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (pal && !pal_entries) pal_entries = 1 << bit_count;
|
||||
n_bytes_per_row = ((int64_t)avctx->width * (int64_t)bit_count + 7LL) >> 3LL;
|
||||
pad_bytes_per_row = (4 - n_bytes_per_row) & 3;
|
||||
n_bytes_image = avctx->height * (n_bytes_per_row + pad_bytes_per_row);
|
||||
|
||||
// STRUCTURE.field refer to the MSVC documentation for BITMAPFILEHEADER
|
||||
// and related pages.
|
||||
#define SIZE_BITMAPFILEHEADER 14
|
||||
#define SIZE_BITMAPINFOHEADER 40
|
||||
hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
|
||||
n_bytes = n_bytes_image + hsize;
|
||||
if(n_bytes>buf_size) {
|
||||
av_log(avctx, AV_LOG_ERROR, "buf size too small (need %d, got %d)\n", n_bytes, buf_size);
|
||||
return -1;
|
||||
}
|
||||
bytestream_put_byte(&buf, 'B'); // BITMAPFILEHEADER.bfType
|
||||
bytestream_put_byte(&buf, 'M'); // do.
|
||||
bytestream_put_le32(&buf, n_bytes); // BITMAPFILEHEADER.bfSize
|
||||
bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved1
|
||||
bytestream_put_le16(&buf, 0); // BITMAPFILEHEADER.bfReserved2
|
||||
bytestream_put_le32(&buf, hsize); // BITMAPFILEHEADER.bfOffBits
|
||||
bytestream_put_le32(&buf, SIZE_BITMAPINFOHEADER); // BITMAPINFOHEADER.biSize
|
||||
bytestream_put_le32(&buf, avctx->width); // BITMAPINFOHEADER.biWidth
|
||||
bytestream_put_le32(&buf, avctx->height); // BITMAPINFOHEADER.biHeight
|
||||
bytestream_put_le16(&buf, 1); // BITMAPINFOHEADER.biPlanes
|
||||
bytestream_put_le16(&buf, bit_count); // BITMAPINFOHEADER.biBitCount
|
||||
bytestream_put_le32(&buf, compression); // BITMAPINFOHEADER.biCompression
|
||||
bytestream_put_le32(&buf, n_bytes_image); // BITMAPINFOHEADER.biSizeImage
|
||||
bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biXPelsPerMeter
|
||||
bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biYPelsPerMeter
|
||||
bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrUsed
|
||||
bytestream_put_le32(&buf, 0); // BITMAPINFOHEADER.biClrImportant
|
||||
for (i = 0; i < pal_entries; i++)
|
||||
bytestream_put_le32(&buf, pal[i] & 0xFFFFFF);
|
||||
// BMP files are bottom-to-top so we start from the end...
|
||||
ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
|
||||
buf = buf0 + hsize;
|
||||
for(i = 0; i < avctx->height; i++) {
|
||||
if (bit_count == 16) {
|
||||
const uint16_t *src = (const uint16_t *) ptr;
|
||||
uint16_t *dst = (uint16_t *) buf;
|
||||
for(n = 0; n < avctx->width; n++)
|
||||
AV_WL16(dst + n, src[n]);
|
||||
} else {
|
||||
memcpy(buf, ptr, n_bytes_per_row);
|
||||
}
|
||||
buf += n_bytes_per_row;
|
||||
memset(buf, 0, pad_bytes_per_row);
|
||||
buf += pad_bytes_per_row;
|
||||
ptr -= p->linesize[0]; // ... and go back
|
||||
}
|
||||
return n_bytes;
|
||||
}
|
||||
|
||||
AVCodec bmp_encoder = {
|
||||
"bmp",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_BMP,
|
||||
sizeof(BMPContext),
|
||||
bmp_encode_init,
|
||||
bmp_encode_frame,
|
||||
NULL, //encode_end,
|
||||
.pix_fmts = (const enum PixelFormat[]){
|
||||
PIX_FMT_BGR24,
|
||||
PIX_FMT_RGB555, PIX_FMT_RGB565,
|
||||
PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE, PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY8, PIX_FMT_PAL8,
|
||||
PIX_FMT_MONOBLACK,
|
||||
PIX_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("BMP image"),
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Bytestream functions
|
||||
* copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_BYTESTREAM_H
|
||||
#define AVCODEC_BYTESTREAM_H
|
||||
|
||||
#include <string.h>
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
#define DEF_T(type, name, bytes, read, write) \
|
||||
static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\
|
||||
(*b) += bytes;\
|
||||
return read(*b - bytes);\
|
||||
}\
|
||||
static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\
|
||||
write(*b, value);\
|
||||
(*b) += bytes;\
|
||||
}
|
||||
|
||||
#define DEF(name, bytes, read, write) \
|
||||
DEF_T(unsigned int, name, bytes, read, write)
|
||||
#define DEF64(name, bytes, read, write) \
|
||||
DEF_T(uint64_t, name, bytes, read, write)
|
||||
|
||||
DEF64(le64, 8, AV_RL64, AV_WL64)
|
||||
DEF (le32, 4, AV_RL32, AV_WL32)
|
||||
DEF (le24, 3, AV_RL24, AV_WL24)
|
||||
DEF (le16, 2, AV_RL16, AV_WL16)
|
||||
DEF64(be64, 8, AV_RB64, AV_WB64)
|
||||
DEF (be32, 4, AV_RB32, AV_WB32)
|
||||
DEF (be24, 3, AV_RB24, AV_WB24)
|
||||
DEF (be16, 2, AV_RB16, AV_WB16)
|
||||
DEF (byte, 1, AV_RB8 , AV_WB8 )
|
||||
|
||||
#undef DEF
|
||||
#undef DEF64
|
||||
#undef DEF_T
|
||||
|
||||
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
|
||||
{
|
||||
memcpy(dst, *b, size);
|
||||
(*b) += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
|
||||
{
|
||||
memcpy(*b, src, size);
|
||||
(*b) += size;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_BYTESTREAM_H */
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Interplay C93 video decoder
|
||||
* Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
|
||||
*
|
||||
* 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 "bytestream.h"
|
||||
|
||||
typedef struct {
|
||||
AVFrame pictures[2];
|
||||
int currentpic;
|
||||
} C93DecoderContext;
|
||||
|
||||
typedef enum {
|
||||
C93_8X8_FROM_PREV = 0x02,
|
||||
C93_4X4_FROM_PREV = 0x06,
|
||||
C93_4X4_FROM_CURR = 0x07,
|
||||
C93_8X8_2COLOR = 0x08,
|
||||
C93_4X4_2COLOR = 0x0A,
|
||||
C93_4X4_4COLOR_GRP = 0x0B,
|
||||
C93_4X4_4COLOR = 0x0D,
|
||||
C93_NOOP = 0x0E,
|
||||
C93_8X8_INTRA = 0x0F,
|
||||
} C93BlockType;
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 192
|
||||
|
||||
#define C93_HAS_PALETTE 0x01
|
||||
#define C93_FIRST_FRAME 0x02
|
||||
|
||||
static av_cold int decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
avctx->pix_fmt = PIX_FMT_PAL8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
C93DecoderContext * const c93 = avctx->priv_data;
|
||||
|
||||
if (c93->pictures[0].data[0])
|
||||
avctx->release_buffer(avctx, &c93->pictures[0]);
|
||||
if (c93->pictures[1].data[0])
|
||||
avctx->release_buffer(avctx, &c93->pictures[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int copy_block(AVCodecContext *avctx, uint8_t *to,
|
||||
uint8_t *from, int offset, int height, int stride)
|
||||
{
|
||||
int i;
|
||||
int width = height;
|
||||
int from_x = offset % WIDTH;
|
||||
int from_y = offset / WIDTH;
|
||||
int overflow = from_x + width - WIDTH;
|
||||
|
||||
if (!from) {
|
||||
/* silently ignoring predictive blocks in first frame */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (from_y + height > HEIGHT) {
|
||||
av_log(avctx, AV_LOG_ERROR, "invalid offset %d during C93 decoding\n",
|
||||
offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (overflow > 0) {
|
||||
width -= overflow;
|
||||
for (i = 0; i < height; i++) {
|
||||
memcpy(&to[i*stride+width], &from[(from_y+i)*stride], overflow);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
memcpy(&to[i*stride], &from[(from_y+i)*stride+from_x], width);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void draw_n_color(uint8_t *out, int stride, int width,
|
||||
int height, int bpp, uint8_t cols[4], uint8_t grps[4], uint32_t col)
|
||||
{
|
||||
int x, y;
|
||||
for (y = 0; y < height; y++) {
|
||||
if (grps)
|
||||
cols[0] = grps[3 * (y >> 1)];
|
||||
for (x = 0; x < width; x++) {
|
||||
if (grps)
|
||||
cols[1]= grps[(x >> 1) + 1];
|
||||
out[x + y*stride] = cols[col & ((1 << bpp) - 1)];
|
||||
col >>= bpp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *data_size, AVPacket *avpkt)
|
||||
{
|
||||
const uint8_t *buf = avpkt->data;
|
||||
int buf_size = avpkt->size;
|
||||
C93DecoderContext * const c93 = avctx->priv_data;
|
||||
AVFrame * const newpic = &c93->pictures[c93->currentpic];
|
||||
AVFrame * const oldpic = &c93->pictures[c93->currentpic^1];
|
||||
AVFrame *picture = data;
|
||||
uint8_t *out;
|
||||
int stride, i, x, y, bt = 0;
|
||||
|
||||
c93->currentpic ^= 1;
|
||||
|
||||
newpic->reference = 1;
|
||||
newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
|
||||
FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
|
||||
if (avctx->reget_buffer(avctx, newpic)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
stride = newpic->linesize[0];
|
||||
|
||||
if (buf[0] & C93_FIRST_FRAME) {
|
||||
newpic->pict_type = FF_I_TYPE;
|
||||
newpic->key_frame = 1;
|
||||
} else {
|
||||
newpic->pict_type = FF_P_TYPE;
|
||||
newpic->key_frame = 0;
|
||||
}
|
||||
|
||||
if (*buf++ & C93_HAS_PALETTE) {
|
||||
uint32_t *palette = (uint32_t *) newpic->data[1];
|
||||
const uint8_t *palbuf = buf + buf_size - 768 - 1;
|
||||
for (i = 0; i < 256; i++) {
|
||||
palette[i] = bytestream_get_be24(&palbuf);
|
||||
}
|
||||
} else {
|
||||
if (oldpic->data[1])
|
||||
memcpy(newpic->data[1], oldpic->data[1], 256 * 4);
|
||||
}
|
||||
|
||||
for (y = 0; y < HEIGHT; y += 8) {
|
||||
out = newpic->data[0] + y * stride;
|
||||
for (x = 0; x < WIDTH; x += 8) {
|
||||
uint8_t *copy_from = oldpic->data[0];
|
||||
unsigned int offset, j;
|
||||
uint8_t cols[4], grps[4];
|
||||
C93BlockType block_type;
|
||||
|
||||
if (!bt)
|
||||
bt = *buf++;
|
||||
|
||||
block_type= bt & 0x0F;
|
||||
switch (block_type) {
|
||||
case C93_8X8_FROM_PREV:
|
||||
offset = bytestream_get_le16(&buf);
|
||||
if (copy_block(avctx, out, copy_from, offset, 8, stride))
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case C93_4X4_FROM_CURR:
|
||||
copy_from = newpic->data[0];
|
||||
case C93_4X4_FROM_PREV:
|
||||
for (j = 0; j < 8; j += 4) {
|
||||
for (i = 0; i < 8; i += 4) {
|
||||
offset = bytestream_get_le16(&buf);
|
||||
if (copy_block(avctx, &out[j*stride+i],
|
||||
copy_from, offset, 4, stride))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case C93_8X8_2COLOR:
|
||||
bytestream_get_buffer(&buf, cols, 2);
|
||||
for (i = 0; i < 8; i++) {
|
||||
draw_n_color(out + i*stride, stride, 8, 1, 1, cols,
|
||||
NULL, *buf++);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case C93_4X4_2COLOR:
|
||||
case C93_4X4_4COLOR:
|
||||
case C93_4X4_4COLOR_GRP:
|
||||
for (j = 0; j < 8; j += 4) {
|
||||
for (i = 0; i < 8; i += 4) {
|
||||
if (block_type == C93_4X4_2COLOR) {
|
||||
bytestream_get_buffer(&buf, cols, 2);
|
||||
draw_n_color(out + i + j*stride, stride, 4, 4,
|
||||
1, cols, NULL, bytestream_get_le16(&buf));
|
||||
} else if (block_type == C93_4X4_4COLOR) {
|
||||
bytestream_get_buffer(&buf, cols, 4);
|
||||
draw_n_color(out + i + j*stride, stride, 4, 4,
|
||||
2, cols, NULL, bytestream_get_le32(&buf));
|
||||
} else {
|
||||
bytestream_get_buffer(&buf, grps, 4);
|
||||
draw_n_color(out + i + j*stride, stride, 4, 4,
|
||||
1, cols, grps, bytestream_get_le16(&buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case C93_NOOP:
|
||||
break;
|
||||
|
||||
case C93_8X8_INTRA:
|
||||
for (j = 0; j < 8; j++)
|
||||
bytestream_get_buffer(&buf, out + j*stride, 8);
|
||||
break;
|
||||
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n",
|
||||
block_type, x, y);
|
||||
return -1;
|
||||
}
|
||||
bt >>= 4;
|
||||
out += 8;
|
||||
}
|
||||
}
|
||||
|
||||
*picture = *newpic;
|
||||
*data_size = sizeof(AVFrame);
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
AVCodec c93_decoder = {
|
||||
"c93",
|
||||
AVMEDIA_TYPE_VIDEO,
|
||||
CODEC_ID_C93,
|
||||
sizeof(C93DecoderContext),
|
||||
decode_init,
|
||||
NULL,
|
||||
decode_end,
|
||||
decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("Interplay C93"),
|
||||
};
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
||||
* Copyright (c) 2003 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
|
||||
* Context Adaptive Binary Arithmetic Coder.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "get_bits.h"
|
||||
#include "cabac.h"
|
||||
|
||||
static const uint8_t lps_range[64][4]= {
|
||||
{128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205},
|
||||
{116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166},
|
||||
{ 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135},
|
||||
{ 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110},
|
||||
{ 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89},
|
||||
{ 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
|
||||
{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59},
|
||||
{ 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
|
||||
{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39},
|
||||
{ 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
|
||||
{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25},
|
||||
{ 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
|
||||
{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17},
|
||||
{ 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14},
|
||||
{ 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11},
|
||||
{ 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2},
|
||||
};
|
||||
|
||||
uint8_t ff_h264_mlps_state[4*64];
|
||||
uint8_t ff_h264_lps_range[4*2*64];
|
||||
uint8_t ff_h264_lps_state[2*64];
|
||||
uint8_t ff_h264_mps_state[2*64];
|
||||
|
||||
static const uint8_t mps_state[64]= {
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9,10,11,12,13,14,15,16,
|
||||
17,18,19,20,21,22,23,24,
|
||||
25,26,27,28,29,30,31,32,
|
||||
33,34,35,36,37,38,39,40,
|
||||
41,42,43,44,45,46,47,48,
|
||||
49,50,51,52,53,54,55,56,
|
||||
57,58,59,60,61,62,62,63,
|
||||
};
|
||||
|
||||
static const uint8_t lps_state[64]= {
|
||||
0, 0, 1, 2, 2, 4, 4, 5,
|
||||
6, 7, 8, 9, 9,11,11,12,
|
||||
13,13,15,15,16,16,18,18,
|
||||
19,19,21,21,22,22,23,24,
|
||||
24,25,26,26,27,27,28,29,
|
||||
29,30,30,30,31,32,32,33,
|
||||
33,33,34,34,35,35,35,36,
|
||||
36,36,37,37,37,38,38,63,
|
||||
};
|
||||
#if 0
|
||||
const uint8_t ff_h264_norm_shift_old[128]= {
|
||||
7,6,5,5,4,4,4,4,3,3,3,3,3,3,3,3,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
#endif
|
||||
const uint8_t ff_h264_norm_shift[512]= {
|
||||
9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buf_size size of buf in bits
|
||||
*/
|
||||
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
|
||||
init_put_bits(&c->pb, buf, buf_size);
|
||||
|
||||
c->low= 0;
|
||||
c->range= 0x1FE;
|
||||
c->outstanding_count= 0;
|
||||
#ifdef STRICT_LIMITS
|
||||
c->sym_count =0;
|
||||
#endif
|
||||
|
||||
c->pb.bit_left++; //avoids firstBitFlag
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param buf_size size of buf in bits
|
||||
*/
|
||||
void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
|
||||
c->bytestream_start=
|
||||
c->bytestream= buf;
|
||||
c->bytestream_end= buf + buf_size;
|
||||
|
||||
#if CABAC_BITS == 16
|
||||
c->low = (*c->bytestream++)<<18;
|
||||
c->low+= (*c->bytestream++)<<10;
|
||||
#else
|
||||
c->low = (*c->bytestream++)<<10;
|
||||
#endif
|
||||
c->low+= ((*c->bytestream++)<<2) + 2;
|
||||
c->range= 0x1FE;
|
||||
}
|
||||
|
||||
void ff_init_cabac_states(CABACContext *c){
|
||||
int i, j;
|
||||
|
||||
for(i=0; i<64; i++){
|
||||
for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
|
||||
ff_h264_lps_range[j*2*64+2*i+0]=
|
||||
ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j];
|
||||
}
|
||||
|
||||
ff_h264_mlps_state[128+2*i+0]=
|
||||
ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0;
|
||||
ff_h264_mlps_state[128+2*i+1]=
|
||||
ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1;
|
||||
|
||||
if( i ){
|
||||
#ifdef BRANCHLESS_CABAC_DECODER
|
||||
ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
|
||||
ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
|
||||
}else{
|
||||
ff_h264_mlps_state[128-2*i-1]= 1;
|
||||
ff_h264_mlps_state[128-2*i-2]= 0;
|
||||
#else
|
||||
ff_h264_lps_state[2*i+0]= 2*lps_state[i]+0;
|
||||
ff_h264_lps_state[2*i+1]= 2*lps_state[i]+1;
|
||||
}else{
|
||||
ff_h264_lps_state[2*i+0]= 1;
|
||||
ff_h264_lps_state[2*i+1]= 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
#define SIZE 10240
|
||||
|
||||
#include "libavutil/lfg.h"
|
||||
#include "avcodec.h"
|
||||
#include "cabac.h"
|
||||
|
||||
int main(void){
|
||||
CABACContext c;
|
||||
uint8_t b[9*SIZE];
|
||||
uint8_t r[9*SIZE];
|
||||
int i;
|
||||
uint8_t state[10]= {0};
|
||||
AVLFG prng;
|
||||
|
||||
av_lfg_init(&prng, 1);
|
||||
ff_init_cabac_encoder(&c, b, SIZE);
|
||||
ff_init_cabac_states(&c);
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
r[i] = av_lfg_get(&prng) % 7;
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
put_cabac_bypass(&c, r[i]&1);
|
||||
STOP_TIMER("put_cabac_bypass")
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
put_cabac(&c, state, r[i]&1);
|
||||
STOP_TIMER("put_cabac")
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
put_cabac_u(&c, state, r[i], 6, 3, i&1);
|
||||
STOP_TIMER("put_cabac_u")
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
put_cabac_ueg(&c, state, r[i], 3, 0, 1, 2);
|
||||
STOP_TIMER("put_cabac_ueg")
|
||||
}
|
||||
|
||||
put_cabac_terminate(&c, 1);
|
||||
|
||||
ff_init_cabac_decoder(&c, b, SIZE);
|
||||
|
||||
memset(state, 0, sizeof(state));
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
if( (r[i]&1) != get_cabac_bypass(&c) )
|
||||
av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
|
||||
STOP_TIMER("get_cabac_bypass")
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
if( (r[i]&1) != get_cabac(&c, state) )
|
||||
av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
|
||||
STOP_TIMER("get_cabac")
|
||||
}
|
||||
#if 0
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) )
|
||||
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
||||
STOP_TIMER("get_cabac_u")
|
||||
}
|
||||
|
||||
for(i=0; i<SIZE; i++){
|
||||
START_TIMER
|
||||
if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2))
|
||||
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
||||
STOP_TIMER("get_cabac_ueg")
|
||||
}
|
||||
#endif
|
||||
if(!get_cabac_terminate(&c))
|
||||
av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user