Update avcodec to 20080825 (sorry for the spam, needed to break this up)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27545 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2008-09-15 14:02:50 +00:00
parent ae0c133a58
commit 8c2268fcfc
25 changed files with 21828 additions and 1645 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/*
* DCA compatible decoder
* Copyright (C) 2004 Gildas Bazin
* Copyright (C) 2004 Benjamin Zores
* Copyright (C) 2006 Benjamin Larsson
* Copyright (C) 2007 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 FFMPEG_DCA_H
#define FFMPEG_DCA_H
/** DCA syncwords, also used for bitstream type detection */
#define DCA_MARKER_RAW_BE 0x7FFE8001
#define DCA_MARKER_RAW_LE 0xFE7F0180
#define DCA_MARKER_14B_BE 0x1FFFE800
#define DCA_MARKER_14B_LE 0xFF1F00E8
#endif /* FFMPEG_DCA_H */

View File

@ -0,0 +1,131 @@
/*
* DCA parser
* Copyright (C) 2004 Gildas Bazin
* Copyright (C) 2004 Benjamin Zores
* Copyright (C) 2006 Benjamin Larsson
* Copyright (C) 2007 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 dca_parser.c
*/
#include "parser.h"
#include "dca.h"
typedef struct DCAParseContext {
ParseContext pc;
uint32_t lastmarker;
int size;
int framesize;
} DCAParseContext;
#define IS_MARKER(state, i, buf, buf_size) \
((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \
|| (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \
|| state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
/**
* finds the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
int buf_size)
{
int start_found, i;
uint32_t state;
ParseContext *pc = &pc1->pc;
start_found = pc->frame_start_found;
state = pc->state;
i = 0;
if (!start_found) {
for (i = 0; i < buf_size; i++) {
state = (state << 8) | buf[i];
if (IS_MARKER(state, i, buf, buf_size)) {
if (pc1->lastmarker && state == pc1->lastmarker) {
start_found = 1;
break;
} else if (!pc1->lastmarker) {
start_found = 1;
pc1->lastmarker = state;
break;
}
}
}
}
if (start_found) {
for (; i < buf_size; i++) {
pc1->size++;
state = (state << 8) | buf[i];
if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size) && (!pc1->framesize || pc1->framesize == pc1->size)) {
pc->frame_start_found = 0;
pc->state = -1;
pc1->framesize = pc1->size;
pc1->size = 0;
return i - 3;
}
}
}
pc->frame_start_found = start_found;
pc->state = state;
return END_NOT_FOUND;
}
static av_cold int dca_parse_init(AVCodecParserContext * s)
{
DCAParseContext *pc1 = s->priv_data;
pc1->lastmarker = 0;
return 0;
}
static int dca_parse(AVCodecParserContext * s,
AVCodecContext * avctx,
const uint8_t ** poutbuf, int *poutbuf_size,
const uint8_t * buf, int buf_size)
{
DCAParseContext *pc1 = s->priv_data;
ParseContext *pc = &pc1->pc;
int next;
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
next = buf_size;
} else {
next = dca_find_frame_end(pc1, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
*poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
AVCodecParser dca_parser = {
{CODEC_ID_DTS},
sizeof(DCAParseContext),
dca_parse_init,
dca_parse,
ff_parse_close,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,582 @@
/*
* (c) 2001 Fabrice Bellard
* 2007 Marc Hoffman <marc.hoffman@analog.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 dct-test.c
* DCT test. (c) 2001 Fabrice Bellard.
* Started from sample code by Juan J. Sierralta P.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <math.h>
#include "libavutil/common.h"
#include "simple_idct.h"
#include "faandct.h"
#include "faanidct.h"
#include "i386/idct_xvid.h"
#undef printf
#undef random
void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);};
/* reference fdct/idct */
extern void fdct(DCTELEM *block);
extern void idct(DCTELEM *block);
extern void init_fdct();
extern void ff_mmx_idct(DCTELEM *data);
extern void ff_mmxext_idct(DCTELEM *data);
extern void odivx_idct_c (short *block);
// BFIN
extern void ff_bfin_idct (DCTELEM *block) ;
extern void ff_bfin_fdct (DCTELEM *block) ;
// ALTIVEC
extern void fdct_altivec (DCTELEM *block);
//extern void idct_altivec (DCTELEM *block);?? no routine
struct algo {
const char *name;
enum { FDCT, IDCT } is_idct;
void (* func) (DCTELEM *block);
void (* ref) (DCTELEM *block);
enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM } format;
int mm_support;
};
#ifndef FAAN_POSTSCALE
#define FAAN_SCALE SCALE_PERM
#else
#define FAAN_SCALE NO_PERM
#endif
static int cpu_flags;
struct algo algos[] = {
{"REF-DBL", 0, fdct, fdct, NO_PERM},
{"FAAN", 0, ff_faandct, fdct, FAAN_SCALE},
{"FAANI", 1, ff_faanidct, idct, NO_PERM},
{"IJG-AAN-INT", 0, fdct_ifast, fdct, SCALE_PERM},
{"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, fdct, NO_PERM},
{"REF-DBL", 1, idct, idct, NO_PERM},
{"INT", 1, j_rev_dct, idct, MMX_PERM},
{"SIMPLE-C", 1, ff_simple_idct, idct, NO_PERM},
#ifdef HAVE_MMX
{"MMX", 0, ff_fdct_mmx, fdct, NO_PERM, MM_MMX},
#ifdef HAVE_MMX2
{"MMX2", 0, ff_fdct_mmx2, fdct, NO_PERM, MM_MMXEXT},
#endif
#ifdef CONFIG_GPL
{"LIBMPEG2-MMX", 1, ff_mmx_idct, idct, MMX_PERM, MM_MMX},
{"LIBMPEG2-MMXEXT", 1, ff_mmxext_idct, idct, MMX_PERM, MM_MMXEXT},
#endif
{"SIMPLE-MMX", 1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM, MM_MMX},
{"XVID-MMX", 1, ff_idct_xvid_mmx, idct, NO_PERM, MM_MMX},
{"XVID-MMX2", 1, ff_idct_xvid_mmx2, idct, NO_PERM, MM_MMXEXT},
{"XVID-SSE2", 1, ff_idct_xvid_sse2, idct, SSE2_PERM, MM_SSE2},
#endif
#ifdef HAVE_ALTIVEC
{"altivecfdct", 0, fdct_altivec, fdct, NO_PERM, MM_ALTIVEC},
#endif
#ifdef ARCH_BFIN
{"BFINfdct", 0, ff_bfin_fdct, fdct, NO_PERM},
{"BFINidct", 1, ff_bfin_idct, idct, NO_PERM},
#endif
{ 0 }
};
#define AANSCALE_BITS 12
static const unsigned short 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
};
uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
int64_t gettime(void)
{
struct timeval tv;
gettimeofday(&tv,NULL);
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
#define NB_ITS 20000
#define NB_ITS_SPEED 50000
static short idct_mmx_perm[64];
static short idct_simple_mmx_perm[64]={
0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
};
static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
void idct_mmx_init(void)
{
int i;
/* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
for (i = 0; i < 64; i++) {
idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
// idct_simple_mmx_perm[i] = simple_block_permute_op(i);
}
}
static DCTELEM block[64] __attribute__ ((aligned (16)));
static DCTELEM block1[64] __attribute__ ((aligned (8)));
static DCTELEM block_org[64] __attribute__ ((aligned (8)));
static inline void mmx_emms(void)
{
#ifdef HAVE_MMX
if (cpu_flags & MM_MMX)
asm volatile ("emms\n\t");
#endif
}
void dct_error(const char *name, int is_idct,
void (*fdct_func)(DCTELEM *block),
void (*fdct_ref)(DCTELEM *block), int form, int test)
{
int it, i, scale;
int err_inf, v;
int64_t err2, ti, ti1, it1;
int64_t sysErr[64], sysErrMax=0;
int maxout=0;
int blockSumErrMax=0, blockSumErr;
srandom(0);
err_inf = 0;
err2 = 0;
for(i=0; i<64; i++) sysErr[i]=0;
for(it=0;it<NB_ITS;it++) {
for(i=0;i<64;i++)
block1[i] = 0;
switch(test){
case 0:
for(i=0;i<64;i++)
block1[i] = (random() % 512) -256;
if (is_idct){
fdct(block1);
for(i=0;i<64;i++)
block1[i]>>=3;
}
break;
case 1:{
int num= (random()%10)+1;
for(i=0;i<num;i++)
block1[random()%64] = (random() % 512) -256;
}break;
case 2:
block1[0]= (random()%4096)-2048;
block1[63]= (block1[0]&1)^1;
break;
}
#if 0 // simulate mismatch control
{ int sum=0;
for(i=0;i<64;i++)
sum+=block1[i];
if((sum&1)==0) block1[63]^=1;
}
#endif
for(i=0; i<64; i++)
block_org[i]= block1[i];
if (form == MMX_PERM) {
for(i=0;i<64;i++)
block[idct_mmx_perm[i]] = block1[i];
} else if (form == MMX_SIMPLE_PERM) {
for(i=0;i<64;i++)
block[idct_simple_mmx_perm[i]] = block1[i];
} else if (form == SSE2_PERM) {
for(i=0; i<64; i++)
block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
} else {
for(i=0; i<64; i++)
block[i]= block1[i];
}
#if 0 // simulate mismatch control for tested IDCT but not the ref
{ int sum=0;
for(i=0;i<64;i++)
sum+=block[i];
if((sum&1)==0) block[63]^=1;
}
#endif
fdct_func(block);
mmx_emms();
if (form == SCALE_PERM) {
for(i=0; i<64; i++) {
scale = 8*(1 << (AANSCALE_BITS + 11)) / aanscales[i];
block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
}
}
fdct_ref(block1);
blockSumErr=0;
for(i=0;i<64;i++) {
v = abs(block[i] - block1[i]);
if (v > err_inf)
err_inf = v;
err2 += v * v;
sysErr[i] += block[i] - block1[i];
blockSumErr += v;
if( abs(block[i])>maxout) maxout=abs(block[i]);
}
if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr;
#if 0 // print different matrix pairs
if(blockSumErr){
printf("\n");
for(i=0; i<64; i++){
if((i&7)==0) printf("\n");
printf("%4d ", block_org[i]);
}
for(i=0; i<64; i++){
if((i&7)==0) printf("\n");
printf("%4d ", block[i] - block1[i]);
}
}
#endif
}
for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
#if 1 // dump systematic errors
for(i=0; i<64; i++){
if(i%8==0) printf("\n");
printf("%5d ", (int)sysErr[i]);
}
printf("\n");
#endif
printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
is_idct ? "IDCT" : "DCT",
name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
#if 1 //Speed test
/* speed test */
for(i=0;i<64;i++)
block1[i] = 0;
switch(test){
case 0:
for(i=0;i<64;i++)
block1[i] = (random() % 512) -256;
if (is_idct){
fdct(block1);
for(i=0;i<64;i++)
block1[i]>>=3;
}
break;
case 1:{
case 2:
block1[0] = (random() % 512) -256;
block1[1] = (random() % 512) -256;
block1[2] = (random() % 512) -256;
block1[3] = (random() % 512) -256;
}break;
}
if (form == MMX_PERM) {
for(i=0;i<64;i++)
block[idct_mmx_perm[i]] = block1[i];
} else if(form == MMX_SIMPLE_PERM) {
for(i=0;i<64;i++)
block[idct_simple_mmx_perm[i]] = block1[i];
} else {
for(i=0; i<64; i++)
block[i]= block1[i];
}
ti = gettime();
it1 = 0;
do {
for(it=0;it<NB_ITS_SPEED;it++) {
for(i=0; i<64; i++)
block[i]= block1[i];
// memcpy(block, block1, sizeof(DCTELEM) * 64);
// do not memcpy especially not fastmemcpy because it does movntq !!!
fdct_func(block);
}
it1 += NB_ITS_SPEED;
ti1 = gettime() - ti;
} while (ti1 < 1000000);
mmx_emms();
printf("%s %s: %0.1f kdct/s\n",
is_idct ? "IDCT" : "DCT",
name, (double)it1 * 1000.0 / (double)ti1);
#endif
}
static uint8_t img_dest[64] __attribute__ ((aligned (8)));
static uint8_t img_dest1[64] __attribute__ ((aligned (8)));
void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
{
static int init;
static double c8[8][8];
static double c4[4][4];
double block1[64], block2[64], block3[64];
double s, sum, v;
int i, j, k;
if (!init) {
init = 1;
for(i=0;i<8;i++) {
sum = 0;
for(j=0;j<8;j++) {
s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0);
c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
sum += c8[i][j] * c8[i][j];
}
}
for(i=0;i<4;i++) {
sum = 0;
for(j=0;j<4;j++) {
s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0);
c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
sum += c4[i][j] * c4[i][j];
}
}
}
/* butterfly */
s = 0.5 * sqrt(2.0);
for(i=0;i<4;i++) {
for(j=0;j<8;j++) {
block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s;
block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s;
}
}
/* idct8 on lines */
for(i=0;i<8;i++) {
for(j=0;j<8;j++) {
sum = 0;
for(k=0;k<8;k++)
sum += c8[k][j] * block1[8*i+k];
block2[8*i+j] = sum;
}
}
/* idct4 */
for(i=0;i<8;i++) {
for(j=0;j<4;j++) {
/* top */
sum = 0;
for(k=0;k<4;k++)
sum += c4[k][j] * block2[8*(2*k)+i];
block3[8*(2*j)+i] = sum;
/* bottom */
sum = 0;
for(k=0;k<4;k++)
sum += c4[k][j] * block2[8*(2*k+1)+i];
block3[8*(2*j+1)+i] = sum;
}
}
/* clamp and store the result */
for(i=0;i<8;i++) {
for(j=0;j<8;j++) {
v = block3[8*i+j];
if (v < 0)
v = 0;
else if (v > 255)
v = 255;
dest[i * linesize + j] = (int)rint(v);
}
}
}
void idct248_error(const char *name,
void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block))
{
int it, i, it1, ti, ti1, err_max, v;
srandom(0);
/* just one test to see if code is correct (precision is less
important here) */
err_max = 0;
for(it=0;it<NB_ITS;it++) {
/* XXX: use forward transform to generate values */
for(i=0;i<64;i++)
block1[i] = (random() % 256) - 128;
block1[0] += 1024;
for(i=0; i<64; i++)
block[i]= block1[i];
idct248_ref(img_dest1, 8, block);
for(i=0; i<64; i++)
block[i]= block1[i];
idct248_put(img_dest, 8, block);
for(i=0;i<64;i++) {
v = abs((int)img_dest[i] - (int)img_dest1[i]);
if (v == 255)
printf("%d %d\n", img_dest[i], img_dest1[i]);
if (v > err_max)
err_max = v;
}
#if 0
printf("ref=\n");
for(i=0;i<8;i++) {
int j;
for(j=0;j<8;j++) {
printf(" %3d", img_dest1[i*8+j]);
}
printf("\n");
}
printf("out=\n");
for(i=0;i<8;i++) {
int j;
for(j=0;j<8;j++) {
printf(" %3d", img_dest[i*8+j]);
}
printf("\n");
}
#endif
}
printf("%s %s: err_inf=%d\n",
1 ? "IDCT248" : "DCT248",
name, err_max);
ti = gettime();
it1 = 0;
do {
for(it=0;it<NB_ITS_SPEED;it++) {
for(i=0; i<64; i++)
block[i]= block1[i];
// memcpy(block, block1, sizeof(DCTELEM) * 64);
// do not memcpy especially not fastmemcpy because it does movntq !!!
idct248_put(img_dest, 8, block);
}
it1 += NB_ITS_SPEED;
ti1 = gettime() - ti;
} while (ti1 < 1000000);
mmx_emms();
printf("%s %s: %0.1f kdct/s\n",
1 ? "IDCT248" : "DCT248",
name, (double)it1 * 1000.0 / (double)ti1);
}
void help(void)
{
printf("dct-test [-i] [<test-number>]\n"
"test-number 0 -> test with random matrixes\n"
" 1 -> test with random sparse matrixes\n"
" 2 -> do 3. test from mpeg4 std\n"
"-i test IDCT implementations\n"
"-4 test IDCT248 implementations\n");
}
int main(int argc, char **argv)
{
int test_idct = 0, test_248_dct = 0;
int c,i;
int test=1;
cpu_flags = mm_support();
init_fdct();
idct_mmx_init();
for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
for(i=0;i<MAX_NEG_CROP;i++) {
cropTbl[i] = 0;
cropTbl[i + MAX_NEG_CROP + 256] = 255;
}
for(;;) {
c = getopt(argc, argv, "ih4");
if (c == -1)
break;
switch(c) {
case 'i':
test_idct = 1;
break;
case '4':
test_248_dct = 1;
break;
default :
case 'h':
help();
return 0;
}
}
if(optind <argc) test= atoi(argv[optind]);
printf("ffmpeg DCT/IDCT test\n");
if (test_248_dct) {
idct248_error("SIMPLE-C", ff_simple_idct248_put);
} else {
for (i=0;algos[i].name;i++)
if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test);
}
}
return 0;
}

View File

@ -0,0 +1,88 @@
/*
* Dirac parser
*
* Copyright (c) 2007 Marco Gerards <marco@gnu.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
*/
/**
* @file dirac_parser.c
* Dirac Parser
* @author Marco Gerards <marco@gnu.org>
*/
#include "parser.h"
#define DIRAC_PARSE_INFO_PREFIX 0x42424344
/**
* Finds the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame or -1
*/
static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
{
uint32_t state = pc->state;
int i;
for (i = 0; i < buf_size; i++) {
state = (state << 8) | buf[i];
if (state == DIRAC_PARSE_INFO_PREFIX) {
pc->frame_start_found ^= 1;
if (!pc->frame_start_found) {
pc->state = -1;
return i - 3;
}
}
}
pc->state = state;
return END_NOT_FOUND;
}
static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
next = buf_size;
}else{
next = find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
}
*poutbuf = buf;
*poutbuf_size = buf_size;
return next;
}
AVCodecParser dirac_parser = {
{ CODEC_ID_DIRAC },
sizeof(ParseContext),
NULL,
dirac_parse,
ff_parse_close,
};

View File

@ -0,0 +1,445 @@
/*
* VC3/DNxHD data.
* Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot 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 "dnxhddata.h"
static const uint8_t dnxhd_1237_luma_weight[] = {
0, 32, 33, 34, 34, 36, 37, 36,
36, 37, 38, 38, 38, 39, 41, 44,
43, 41, 40, 41, 46, 49, 47, 46,
47, 49, 51, 54, 60, 62, 59, 55,
54, 56, 58, 61, 65, 66, 64, 63,
66, 73, 78, 79, 80, 79, 78, 78,
82, 87, 89, 90, 93, 95, 96, 97,
97, 100, 104, 102, 98, 98, 99, 99,
};
static const uint8_t dnxhd_1237_chroma_weight[] = {
0, 32, 36, 39, 39, 38, 39, 41,
45, 51, 57, 58, 53, 48, 47, 51,
55, 58, 66, 75, 81, 83, 82, 78,
73, 72, 74, 77, 83, 85, 83, 82,
89, 99, 96, 90, 94, 97, 99, 105,
109, 105, 95, 89, 92, 95, 94, 93,
92, 88, 89, 90, 93, 95, 96, 97,
97, 100, 104, 102, 98, 98, 99, 99,
};
static const uint8_t dnxhd_1238_luma_weight[] = {
0, 32, 32, 33, 34, 33, 33, 33,
33, 33, 33, 33, 33, 35, 37, 37,
36, 36, 35, 36, 38, 38, 36, 35,
36, 37, 38, 41, 42, 41, 39, 38,
38, 38, 39, 41, 42, 41, 39, 39,
40, 41, 43, 44, 44, 44, 44, 44,
45, 47, 47, 47, 49, 50, 51, 51,
51, 53, 55, 57, 58, 59, 57, 57,
};
static const uint8_t dnxhd_1238_chroma_weight[] = {
0, 32, 35, 35, 35, 34, 34, 35,
39, 43, 45, 45, 41, 39, 40, 41,
42, 44, 48, 55, 59, 63, 65, 59,
53, 52, 52, 55, 61, 62, 58, 58,
63, 66, 66, 65, 70, 74, 70, 66,
65, 68, 75, 77, 74, 74, 77, 76,
73, 73, 73, 73, 76, 80, 89, 90,
82, 77, 80, 86, 84, 82, 82, 82,
};
static const uint8_t dnxhd_1241_luma_weight[] = {
0, 32, 33, 34, 34, 35, 36, 37,
36, 37, 38, 38, 38, 39, 39, 40,
40, 38, 38, 39, 38, 37, 39, 41,
41, 42, 43, 45, 45, 46, 47, 46,
45, 43, 39, 37, 37, 40, 44, 45,
45, 46, 46, 46, 47, 47, 46, 44,
42, 43, 45, 47, 48, 49, 50, 49,
48, 46, 47, 48, 48, 49, 49, 49,
};
static const uint8_t dnxhd_1241_chroma_weight[] = {
0, 32, 36, 38, 37, 37, 40, 41,
40, 40, 42, 42, 41, 41, 41, 41,
42, 43, 44, 44, 45, 46, 46, 45,
44, 45, 45, 45, 45, 46, 47, 46,
45, 44, 42, 41, 43, 45, 45, 47,
48, 48, 48, 46, 47, 47, 46, 47,
46, 45, 45, 47, 48, 49, 50, 49,
48, 46, 48, 49, 48, 49, 49, 49,
};
static const uint8_t dnxhd_1242_luma_weight[] = {
0, 32, 33, 33, 34, 35, 36, 35,
33, 33, 35, 36, 37, 37, 38, 37,
37, 37, 36, 37, 37, 37, 38, 39,
37, 36, 37, 40, 42, 45, 46, 44,
41, 42, 44, 45, 47, 49, 50, 48,
46, 48, 49, 50, 52, 52, 50, 49,
47, 48, 50, 50, 51, 51, 50, 49,
49, 51, 52, 51, 49, 47, 47, 47,
};
static const uint8_t dnxhd_1242_chroma_weight[] = {
0, 32, 37, 42, 45, 45, 45, 44,
38, 37, 40, 42, 44, 49, 51, 47,
41, 40, 43, 44, 46, 48, 51, 54,
51, 47, 47, 45, 47, 50, 51, 49,
46, 47, 49, 47, 50, 55, 55, 51,
48, 49, 51, 51, 52, 52, 54, 54,
49, 49, 52, 53, 54, 54, 53, 53,
55, 59, 63, 62, 60, 60, 60, 60,
};
static const uint8_t dnxhd_1243_luma_weight[] = {
0, 32, 32, 33, 33, 35, 35, 35,
35, 35, 35, 35, 34, 35, 38, 40,
39, 37, 37, 37, 36, 35, 36, 38,
40, 41, 42, 44, 45, 44, 42, 41,
40, 38, 36, 36, 37, 38, 40, 43,
44, 45, 45, 45, 45, 45, 45, 41,
39, 41, 45, 47, 47, 48, 48, 48,
46, 44, 45, 47, 47, 48, 47, 47,
};
static const uint8_t dnxhd_1243_chroma_weight[] = {
0, 32, 36, 37, 36, 37, 39, 39,
41, 43, 43, 42, 41, 41, 41, 42,
43, 43, 43, 44, 44, 44, 46, 47,
46, 45, 45, 45, 45, 46, 44, 44,
45, 44, 42, 41, 43, 46, 45, 44,
45, 45, 45, 46, 46, 46, 45, 44,
45, 44, 45, 47, 47, 48, 49, 48,
46, 45, 46, 47, 47, 48, 47, 47,
};
static const uint8_t dnxhd_1251_luma_weight[] = {
0, 32, 32, 34, 34, 34, 34, 35,
35, 35, 36, 37, 36, 36, 35, 36,
38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 39, 41, 44, 43, 41, 40,
40, 40, 40, 39, 40, 41, 40, 39,
40, 43, 46, 46, 44, 44, 44, 42,
41, 43, 46, 48, 50, 55, 58, 53,
48, 50, 55, 58, 61, 62, 62, 62,
};
static const uint8_t dnxhd_1251_chroma_weight[] = {
0, 32, 35, 36, 36, 35, 36, 39,
41, 43, 45, 44, 41, 39, 40, 42,
43, 43, 45, 48, 48, 48, 50, 50,
50, 51, 51, 51, 51, 52, 53, 54,
51, 49, 51, 52, 52, 56, 57, 55,
54, 54, 55, 56, 55, 58, 58, 58,
60, 61, 62, 62, 59, 57, 58, 58,
61, 59, 59, 59, 61, 62, 62, 62,
};
static const uint8_t dnxhd_1252_luma_weight[] = {
0, 32, 34, 35, 36, 36, 36, 37,
36, 37, 39, 40, 41, 40, 40, 40,
41, 41, 42, 41, 41, 43, 44, 44,
45, 46, 48, 55, 60, 57, 52, 50,
49, 49, 52, 52, 53, 55, 58, 62,
65, 73, 82, 82, 80, 78, 73, 68,
71, 82, 90, 90, 88, 87, 90, 95,
100, 107, 103, 97, 95, 93, 99, 99,
};
static const uint8_t dnxhd_1252_chroma_weight[] = {
0, 32, 35, 36, 37, 37, 38, 40,
42, 46, 49, 50, 50, 49, 49, 53,
56, 56, 57, 58, 60, 62, 64, 65,
63, 64, 64, 65, 66, 65, 67, 71,
72, 74, 74, 74, 74, 77, 81, 78,
72, 73, 82, 85, 89, 88, 84, 80,
90, 100, 90, 90, 88, 87, 90, 95,
114, 128, 125, 129, 134, 125, 116, 116,
};
static const uint8_t dnxhd_1237_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
static const uint8_t dnxhd_1237_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
static const uint16_t dnxhd_1237_ac_codes[257] = {
0, 1, 4, 5, 12, 26, 27, 56, 57, 58, 59, 120, 121, 244, 245, 246, 247, 248, 498, 499, 500, 501, 502, 1006, 1007, 1008, 1009, 1010, 1011, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 32668, 32669, 32670, 32671, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 65370, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 65379, 65380, 65381, 65382, 65383, 65384, 65385, 65386, 65387, 65388, 65389, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
};
static const uint8_t dnxhd_1237_ac_bits[257] = {
2, 2, 3, 3, 4, 5, 5, 6, 6, 6, 6, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
static const uint8_t dnxhd_1237_ac_level[257] = {
1, 1, 2, 0, 3, 4, 2, 5, 6, 7, 3, 8, 9, 10, 11, 12, 4, 5, 13, 14, 15, 16, 6, 17, 18, 19, 20, 21, 7, 22, 23, 24, 25, 26, 27, 8, 9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35, 36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 1, 22, 23, 24, 25, 26, 27, 62, 63, 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, 63, 64, 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, 63, 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, 63, 64,
};
static const uint8_t dnxhd_1237_ac_run_flag[257] = {
0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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,
};
static const uint8_t dnxhd_1237_ac_index_flag[257] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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,
};
static const uint16_t dnxhd_1237_run_codes[62] = {
0, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 58, 118, 119, 240, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1237_run_bits[62] = {
1, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 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, 10, 10,
};
static const uint8_t dnxhd_1237_run[62] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 53, 57, 58, 59, 60, 61, 62, 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, 54, 55, 56,
};
static const uint8_t dnxhd_1238_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
static const uint8_t dnxhd_1238_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
static const uint16_t dnxhd_1238_ac_codes[257] = {
0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 499, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
};
static const uint8_t dnxhd_1238_ac_bits[257] = {
2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
static const uint8_t dnxhd_1238_ac_level[257] = {
1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 22, 6, 7, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 10, 11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25, 26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 63, 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, 63, 64,
}; /* 0 is EOB */
static const uint8_t dnxhd_1238_ac_run_flag[257] = {
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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,
};
static const uint8_t dnxhd_1238_ac_index_flag[257] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 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, 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, 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,
};
static const uint16_t dnxhd_1238_run_codes[62] = {
0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1238_run_bits[62] = {
1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1238_run[62] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 21, 17, 18, 19, 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,
};
static const uint8_t dnxhd_1241_dc_codes[14] = {
10, 62, 11, 12, 13, 0, 1, 2, 3, 4, 14, 30, 126, 127,
};
static const uint8_t dnxhd_1241_dc_bits[14] = {
4, 6, 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 7, 7,
};
static const uint16_t dnxhd_1241_ac_codes[257] = {
0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 498, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
};
static const uint8_t dnxhd_1241_ac_bits[257] = {
2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
static const uint8_t dnxhd_1241_ac_level[257] = {
1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 7, 22, 23, 24, 25, 26, 27, 28, 29, 8, 9, 30, 31, 32, 33, 34, 35, 36, 37, 38, 10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13, 14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 1, 16, 17, 18, 19, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 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, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 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, 63, 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, 63, 64,
};
static const uint8_t dnxhd_1241_ac_run_flag[257] = {
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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,
};
static const uint8_t dnxhd_1241_ac_index_flag[257] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 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, 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, 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,
};
static const uint16_t dnxhd_1241_run_codes[62] = {
0, 4, 10, 11, 24, 25, 26, 27, 56, 57, 58, 59, 120, 242, 486, 487, 488, 489, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1241_run_bits[62] = {
1, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 8, 9, 9, 9, 9, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1241_run[62] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 17, 19, 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,
};
static const uint8_t dnxhd_1251_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
static const uint8_t dnxhd_1251_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
static const uint16_t dnxhd_1251_ac_codes[257] = {
0, 1, 4, 10, 11, 24, 25, 26, 54, 55, 56, 57, 116, 117, 118, 119, 240, 241, 242, 243, 244, 245, 492, 493, 494, 495, 496, 497, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 8134, 8135, 8136, 8137, 8138, 8139, 8140, 8141, 8142, 8143, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 16314, 16315, 16316, 16317, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 16336, 16337, 16338, 16339, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 32695, 32696, 32697, 32698, 32699, 32700, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
};
static const uint8_t dnxhd_1251_ac_bits[257] = {
2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
static const uint8_t dnxhd_1251_ac_level[257] = {
1, 1, 2, 3, 0, 4, 5, 2, 6, 7, 8, 3, 9, 10, 11, 4, 12, 13, 14, 15, 16, 5, 17, 18, 19, 20, 21, 6, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 4, 5, 6, 7, 8, 15, 16, 17, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18, 19, 20, 21, 22, 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, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 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, 63, 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, 63, 64,
};
static const uint8_t dnxhd_1251_ac_run_flag[257] = {
0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 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,
};
static const uint8_t dnxhd_1251_ac_index_flag[257] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 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, 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, 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,
};
static const uint16_t dnxhd_1251_run_codes[62] = {
0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1251_run_bits[62] = {
1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1251_run[62] = {
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,
};
static const uint8_t dnxhd_1252_dc_codes[12] = {
0, 12, 13, 1, 2, 3, 4, 5, 14, 30, 62, 63,
};
static const uint8_t dnxhd_1252_dc_bits[12] = {
3, 4, 4, 3, 3, 3, 3, 3, 4, 5, 6, 6,
};
static const uint16_t dnxhd_1252_ac_codes[257] = {
0, 1, 4, 10, 11, 12, 26, 27, 56, 57, 58, 118, 119, 120, 242, 243, 244, 245, 246, 247, 496, 497, 498, 499, 500, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 8144, 8145, 8146, 8147, 8148, 8149, 8150, 8151, 8152, 8153, 8154, 8155, 8156, 8157, 8158, 16318, 16319, 16320, 16321, 16322, 16323, 16324, 16325, 16326, 16327, 16328, 16329, 16330, 16331, 16332, 16333, 16334, 16335, 32672, 32673, 32674, 32675, 32676, 32677, 32678, 32679, 32680, 32681, 32682, 32683, 32684, 32685, 32686, 32687, 32688, 32689, 32690, 32691, 32692, 32693, 32694, 65390, 65391, 65392, 65393, 65394, 65395, 65396, 65397, 65398, 65399, 65400, 65401, 65402, 65403, 65404, 65405, 65406, 65407, 65408, 65409, 65410, 65411, 65412, 65413, 65414, 65415, 65416, 65417, 65418, 65419, 65420, 65421, 65422, 65423, 65424, 65425, 65426, 65427, 65428, 65429, 65430, 65431, 65432, 65433, 65434, 65435, 65436, 65437, 65438, 65439, 65440, 65441, 65442, 65443, 65444, 65445, 65446, 65447, 65448, 65449, 65450, 65451, 65452, 65453, 65454, 65455, 65456, 65457, 65458, 65459, 65460, 65461, 65462, 65463, 65464, 65465, 65466, 65467, 65468, 65469, 65470, 65471, 65472, 65473, 65474, 65475, 65476, 65477, 65478, 65479, 65480, 65481, 65482, 65483, 65484, 65485, 65486, 65487, 65488, 65489, 65490, 65491, 65492, 65493, 65494, 65495, 65496, 65497, 65498, 65499, 65500, 65501, 65502, 65503, 65504, 65505, 65506, 65507, 65508, 65509, 65510, 65511, 65512, 65513, 65514, 65515, 65516, 65517, 65518, 65519, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65529, 65530, 65531, 65532, 65533, 65534, 65535,
};
static const uint8_t dnxhd_1252_ac_bits[257] = {
2, 2, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
};
static const uint8_t dnxhd_1252_ac_level[257] = {
1, 1, 2, 3, 2, 0, 4, 5, 6, 7, 3, 8, 9, 10, 11, 12, 13, 14, 4, 5, 15, 16, 17, 18, 6, 19, 20, 21, 22, 23, 24, 7, 8, 25, 26, 27, 28, 29, 30, 31, 32, 9, 10, 33, 34, 35, 36, 37, 38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 1, 2, 3, 17, 18, 19, 20, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 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, 63, 64, 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, 63, 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, 63, 64,
};
static const uint8_t dnxhd_1252_ac_run_flag[257] = {
0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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,
};
static const uint8_t dnxhd_1252_ac_index_flag[257] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 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, 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,
};
static const uint16_t dnxhd_1252_run_codes[62] = {
0, 4, 5, 12, 26, 27, 28, 58, 118, 119, 120, 242, 486, 487, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
};
static const uint8_t dnxhd_1252_run_bits[62] = {
1, 3, 3, 4, 5, 5, 5, 6, 7, 7, 7, 8, 9, 9, 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, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
};
static const uint8_t dnxhd_1252_run[62] = {
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,
};
const CIDEntry ff_dnxhd_cid_table[] = {
{ 1237, 1920, 1080, 0, 606208, 606208, 4, 8,
dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight,
dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag,
dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
{ 115, 120, 145, 240, 290 } },
{ 1238, 1920, 1080, 0, 917504, 917504, 4, 8,
dnxhd_1238_luma_weight, dnxhd_1238_chroma_weight,
dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag,
dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run,
{ 175, 185, 220, 365, 440 } },
{ 1241, 1920, 1080, 1, 917504, 458752, 6, 10,
dnxhd_1241_luma_weight, dnxhd_1241_chroma_weight,
dnxhd_1241_dc_codes, dnxhd_1241_dc_bits,
dnxhd_1241_ac_codes, dnxhd_1241_ac_bits, dnxhd_1241_ac_level,
dnxhd_1241_ac_run_flag, dnxhd_1241_ac_index_flag,
dnxhd_1241_run_codes, dnxhd_1241_run_bits, dnxhd_1241_run,
{ 185, 220 } },
{ 1242, 1920, 1080, 1, 606208, 303104, 4, 8,
dnxhd_1242_luma_weight, dnxhd_1242_chroma_weight,
dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag,
dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
{ 120, 145 } },
{ 1243, 1920, 1080, 1, 917504, 458752, 4, 8,
dnxhd_1243_luma_weight, dnxhd_1243_chroma_weight,
dnxhd_1238_dc_codes, dnxhd_1238_dc_bits,
dnxhd_1238_ac_codes, dnxhd_1238_ac_bits, dnxhd_1238_ac_level,
dnxhd_1238_ac_run_flag, dnxhd_1238_ac_index_flag,
dnxhd_1238_run_codes, dnxhd_1238_run_bits, dnxhd_1238_run,
{ 185, 220 } },
{ 1251, 1280, 720, 0, 458752, 458752, 4, 8,
dnxhd_1251_luma_weight, dnxhd_1251_chroma_weight,
dnxhd_1251_dc_codes, dnxhd_1251_dc_bits,
dnxhd_1251_ac_codes, dnxhd_1251_ac_bits, dnxhd_1251_ac_level,
dnxhd_1251_ac_run_flag, dnxhd_1251_ac_index_flag,
dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run,
{ 90, 110, 175, 220 } },
{ 1252, 1280, 720, 0, 303104, 303104, 4, 8,
dnxhd_1252_luma_weight, dnxhd_1252_chroma_weight,
dnxhd_1252_dc_codes, dnxhd_1252_dc_bits,
dnxhd_1252_ac_codes, dnxhd_1252_ac_bits, dnxhd_1252_ac_level,
dnxhd_1252_ac_run_flag, dnxhd_1252_ac_index_flag,
dnxhd_1252_run_codes, dnxhd_1252_run_bits, dnxhd_1252_run,
{ 60, 75, 115, 145 } },
{ 1253, 1920, 1080, 0, 188416, 188416, 4, 8,
dnxhd_1237_luma_weight, dnxhd_1237_chroma_weight,
dnxhd_1237_dc_codes, dnxhd_1237_dc_bits,
dnxhd_1237_ac_codes, dnxhd_1237_ac_bits, dnxhd_1237_ac_level,
dnxhd_1237_ac_run_flag, dnxhd_1237_ac_index_flag,
dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
{ 36, 45, 75, 90 } },
};
int ff_dnxhd_get_cid_table(int cid)
{
int i;
for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++)
if (ff_dnxhd_cid_table[i].cid == cid)
return i;
return -1;
}
int ff_dnxhd_find_cid(AVCodecContext *avctx)
{
int i, j;
int mbs = avctx->bit_rate/1000000;
if (!mbs)
return 0;
for (i = 0; i < sizeof(ff_dnxhd_cid_table)/sizeof(CIDEntry); i++) {
const CIDEntry *cid = &ff_dnxhd_cid_table[i];
if (cid->width == avctx->width && cid->height == avctx->height &&
cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) &&
cid->bit_depth == 8) { // until 10 bit is supported
for (j = 0; j < sizeof(cid->bit_rates); j++) {
if (cid->bit_rates[j] == mbs)
return cid->cid;
}
}
}
return 0;
}

View File

@ -0,0 +1,51 @@
/*
* VC3/DNxHD decoder.
* Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot 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 FFMPEG_DNXHDDATA_H
#define FFMPEG_DNXHDDATA_H
#include <stdint.h>
#include "avcodec.h"
typedef struct {
int cid;
unsigned int width, height;
int interlaced;
unsigned int frame_size;
unsigned int coding_unit_size;
int index_bits;
int bit_depth;
const uint8_t *luma_weight, *chroma_weight;
const uint8_t *dc_codes, *dc_bits;
const uint16_t *ac_codes;
const uint8_t *ac_bits, *ac_level;
const uint8_t *ac_run_flag, *ac_index_flag;
const uint16_t *run_codes;
const uint8_t *run_bits, *run;
int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s
} CIDEntry;
extern const CIDEntry ff_dnxhd_cid_table[];
int ff_dnxhd_get_cid_table(int cid);
int ff_dnxhd_find_cid(AVCodecContext *avctx);
#endif /* FFMPEG_DNXHDDATA_H */

View File

@ -0,0 +1,346 @@
/*
* VC3/DNxHD decoder.
* Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot 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
*/
//#define TRACE
//#define DEBUG
#include "avcodec.h"
#include "bitstream.h"
#include "dnxhddata.h"
#include "dsputil.h"
typedef struct {
AVCodecContext *avctx;
AVFrame picture;
GetBitContext gb;
int cid; ///< compression id
unsigned int width, height;
unsigned int mb_width, mb_height;
uint32_t mb_scan_index[68]; /* max for 1080p */
int cur_field; ///< current interlaced field
VLC ac_vlc, dc_vlc, run_vlc;
int last_dc[3];
DSPContext dsp;
DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]);
DECLARE_ALIGNED_8(ScanTable, scantable);
const CIDEntry *cid_table;
} DNXHDContext;
#define DNXHD_VLC_BITS 9
#define DNXHD_DC_VLC_BITS 7
static av_cold int dnxhd_decode_init(AVCodecContext *avctx)
{
DNXHDContext *ctx = avctx->priv_data;
ctx->avctx = avctx;
dsputil_init(&ctx->dsp, avctx);
avctx->coded_frame = &ctx->picture;
ctx->picture.type = FF_I_TYPE;
return 0;
}
static int dnxhd_init_vlc(DNXHDContext *ctx, int cid)
{
if (!ctx->cid_table) {
int index;
if ((index = ff_dnxhd_get_cid_table(cid)) < 0) {
av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid);
return -1;
}
ctx->cid_table = &ff_dnxhd_cid_table[index];
init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257,
ctx->cid_table->ac_bits, 1, 1,
ctx->cid_table->ac_codes, 2, 2, 0);
init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, ctx->cid_table->bit_depth+4,
ctx->cid_table->dc_bits, 1, 1,
ctx->cid_table->dc_codes, 1, 1, 0);
init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62,
ctx->cid_table->run_bits, 1, 1,
ctx->cid_table->run_codes, 2, 2, 0);
ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, ff_zigzag_direct);
}
return 0;
}
static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_size, int first_field)
{
static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 };
int i;
if (buf_size < 0x280)
return -1;
if (memcmp(buf, header_prefix, 5)) {
av_log(ctx->avctx, AV_LOG_ERROR, "error in header\n");
return -1;
}
if (buf[5] & 2) { /* interlaced */
ctx->cur_field = buf[5] & 1;
ctx->picture.interlaced_frame = 1;
ctx->picture.top_field_first = first_field ^ ctx->cur_field;
av_log(ctx->avctx, AV_LOG_DEBUG, "interlaced %d, cur field %d\n", buf[5] & 3, ctx->cur_field);
}
ctx->height = AV_RB16(buf + 0x18);
ctx->width = AV_RB16(buf + 0x1a);
dprintf(ctx->avctx, "width %d, heigth %d\n", ctx->width, ctx->height);
if (buf[0x21] & 0x40) {
av_log(ctx->avctx, AV_LOG_ERROR, "10 bit per component\n");
return -1;
}
ctx->cid = AV_RB32(buf + 0x28);
dprintf(ctx->avctx, "compression id %d\n", ctx->cid);
if (dnxhd_init_vlc(ctx, ctx->cid) < 0)
return -1;
if (buf_size < ctx->cid_table->coding_unit_size) {
av_log(ctx->avctx, AV_LOG_ERROR, "incorrect frame size\n");
return -1;
}
ctx->mb_width = ctx->width>>4;
ctx->mb_height = buf[0x16d];
if (ctx->mb_height > 68) {
av_log(ctx->avctx, AV_LOG_ERROR, "mb height too big\n");
return -1;
}
dprintf(ctx->avctx, "mb width %d, mb height %d\n", ctx->mb_width, ctx->mb_height);
for (i = 0; i < ctx->mb_height; i++) {
ctx->mb_scan_index[i] = AV_RB32(buf + 0x170 + (i<<2));
dprintf(ctx->avctx, "mb scan index %d\n", ctx->mb_scan_index[i]);
if (buf_size < ctx->mb_scan_index[i] + 0x280) {
av_log(ctx->avctx, AV_LOG_ERROR, "invalid mb scan index\n");
return -1;
}
}
return 0;
}
static int dnxhd_decode_dc(DNXHDContext *ctx)
{
int len;
len = get_vlc2(&ctx->gb, ctx->dc_vlc.table, DNXHD_DC_VLC_BITS, 1);
return len ? get_xbits(&ctx->gb, len) : 0;
}
static void dnxhd_decode_dct_block(DNXHDContext *ctx, DCTELEM *block, int n, int qscale)
{
int i, j, index, index2;
int level, component, sign;
const uint8_t *weigth_matrix;
if (n&2) {
component = 1 + (n&1);
weigth_matrix = ctx->cid_table->chroma_weight;
} else {
component = 0;
weigth_matrix = ctx->cid_table->luma_weight;
}
ctx->last_dc[component] += dnxhd_decode_dc(ctx);
block[0] = ctx->last_dc[component];
//av_log(ctx->avctx, AV_LOG_DEBUG, "dc %d\n", block[0]);
for (i = 1; ; i++) {
index = get_vlc2(&ctx->gb, ctx->ac_vlc.table, DNXHD_VLC_BITS, 2);
//av_log(ctx->avctx, AV_LOG_DEBUG, "index %d\n", index);
level = ctx->cid_table->ac_level[index];
if (!level) { /* EOB */
//av_log(ctx->avctx, AV_LOG_DEBUG, "EOB\n");
return;
}
sign = get_sbits(&ctx->gb, 1);
if (ctx->cid_table->ac_index_flag[index]) {
level += get_bits(&ctx->gb, ctx->cid_table->index_bits)<<6;
}
if (ctx->cid_table->ac_run_flag[index]) {
index2 = get_vlc2(&ctx->gb, ctx->run_vlc.table, DNXHD_VLC_BITS, 2);
i += ctx->cid_table->run[index2];
}
if (i > 63) {
av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);
return;
}
j = ctx->scantable.permutated[i];
//av_log(ctx->avctx, AV_LOG_DEBUG, "j %d\n", j);
//av_log(ctx->avctx, AV_LOG_DEBUG, "level %d, weigth %d\n", level, weigth_matrix[i]);
level = (2*level+1) * qscale * weigth_matrix[i];
if (ctx->cid_table->bit_depth == 10) {
if (weigth_matrix[i] != 8)
level += 8;
level >>= 4;
} else {
if (weigth_matrix[i] != 32)
level += 32;
level >>= 6;
}
//av_log(NULL, AV_LOG_DEBUG, "i %d, j %d, end level %d\n", i, j, level);
block[j] = (level^sign) - sign;
}
}
static int dnxhd_decode_macroblock(DNXHDContext *ctx, int x, int y)
{
int dct_linesize_luma = ctx->picture.linesize[0];
int dct_linesize_chroma = ctx->picture.linesize[1];
uint8_t *dest_y, *dest_u, *dest_v;
int dct_offset;
int qscale, i;
ctx->dsp.clear_blocks(ctx->blocks[0]);
ctx->dsp.clear_blocks(ctx->blocks[2]); // FIXME change clear blocks to take block amount
qscale = get_bits(&ctx->gb, 11);
skip_bits1(&ctx->gb);
//av_log(ctx->avctx, AV_LOG_DEBUG, "qscale %d\n", qscale);
for (i = 0; i < 8; i++) {
dnxhd_decode_dct_block(ctx, ctx->blocks[i], i, qscale);
}
if (ctx->picture.interlaced_frame) {
dct_linesize_luma <<= 1;
dct_linesize_chroma <<= 1;
}
dest_y = ctx->picture.data[0] + ((y * dct_linesize_luma) << 4) + (x << 4);
dest_u = ctx->picture.data[1] + ((y * dct_linesize_chroma) << 4) + (x << 3);
dest_v = ctx->picture.data[2] + ((y * dct_linesize_chroma) << 4) + (x << 3);
if (ctx->cur_field) {
dest_y += ctx->picture.linesize[0];
dest_u += ctx->picture.linesize[1];
dest_v += ctx->picture.linesize[2];
}
dct_offset = dct_linesize_luma << 3;
ctx->dsp.idct_put(dest_y, dct_linesize_luma, ctx->blocks[0]);
ctx->dsp.idct_put(dest_y + 8, dct_linesize_luma, ctx->blocks[1]);
ctx->dsp.idct_put(dest_y + dct_offset, dct_linesize_luma, ctx->blocks[4]);
ctx->dsp.idct_put(dest_y + dct_offset + 8, dct_linesize_luma, ctx->blocks[5]);
if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
dct_offset = dct_linesize_chroma << 3;
ctx->dsp.idct_put(dest_u, dct_linesize_chroma, ctx->blocks[2]);
ctx->dsp.idct_put(dest_v, dct_linesize_chroma, ctx->blocks[3]);
ctx->dsp.idct_put(dest_u + dct_offset, dct_linesize_chroma, ctx->blocks[6]);
ctx->dsp.idct_put(dest_v + dct_offset, dct_linesize_chroma, ctx->blocks[7]);
}
return 0;
}
static int dnxhd_decode_macroblocks(DNXHDContext *ctx, const uint8_t *buf, int buf_size)
{
int x, y;
for (y = 0; y < ctx->mb_height; y++) {
ctx->last_dc[0] =
ctx->last_dc[1] =
ctx->last_dc[2] = 1<<(ctx->cid_table->bit_depth+2); // for levels +2^(bitdepth-1)
init_get_bits(&ctx->gb, buf + ctx->mb_scan_index[y], (buf_size - ctx->mb_scan_index[y]) << 3);
for (x = 0; x < ctx->mb_width; x++) {
//START_TIMER;
dnxhd_decode_macroblock(ctx, x, y);
//STOP_TIMER("decode macroblock");
}
}
return 0;
}
static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
DNXHDContext *ctx = avctx->priv_data;
AVFrame *picture = data;
int first_field = 1;
dprintf(avctx, "frame size %d\n", buf_size);
decode_coding_unit:
if (dnxhd_decode_header(ctx, buf, buf_size, first_field) < 0)
return -1;
avctx->pix_fmt = PIX_FMT_YUV422P;
if (avcodec_check_dimensions(avctx, ctx->width, ctx->height))
return -1;
avcodec_set_dimensions(avctx, ctx->width, ctx->height);
if (first_field) {
if (ctx->picture.data[0])
avctx->release_buffer(avctx, &ctx->picture);
if (avctx->get_buffer(avctx, &ctx->picture) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
}
dnxhd_decode_macroblocks(ctx, buf + 0x280, buf_size - 0x280);
if (first_field && ctx->picture.interlaced_frame) {
buf += ctx->cid_table->coding_unit_size;
buf_size -= ctx->cid_table->coding_unit_size;
first_field = 0;
goto decode_coding_unit;
}
*picture = ctx->picture;
*data_size = sizeof(AVPicture);
return buf_size;
}
static av_cold int dnxhd_decode_close(AVCodecContext *avctx)
{
DNXHDContext *ctx = avctx->priv_data;
if (ctx->picture.data[0])
avctx->release_buffer(avctx, &ctx->picture);
free_vlc(&ctx->ac_vlc);
free_vlc(&ctx->dc_vlc);
free_vlc(&ctx->run_vlc);
return 0;
}
AVCodec dnxhd_decoder = {
"dnxhd",
CODEC_TYPE_VIDEO,
CODEC_ID_DNXHD,
sizeof(DNXHDContext),
dnxhd_decode_init,
NULL,
dnxhd_decode_close,
dnxhd_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
};

View File

@ -0,0 +1,861 @@
/*
* VC3/DNxHD encoder
* Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
*
* VC-3 encoder funded by the British Broadcasting Corporation
*
* 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
#define RC_VARIANCE 1 // use variance or ssd for fast rc
#include "avcodec.h"
#include "dsputil.h"
#include "mpegvideo.h"
#include "dnxhddata.h"
typedef struct {
uint16_t mb;
int value;
} RCCMPEntry;
typedef struct {
int ssd;
int bits;
} RCEntry;
int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
typedef struct DNXHDEncContext {
MpegEncContext m; ///< Used for quantization dsp functions
AVFrame frame;
int cid;
const CIDEntry *cid_table;
uint8_t *msip; ///< Macroblock Scan Indexes Payload
uint32_t *slice_size;
struct DNXHDEncContext *thread[MAX_THREADS];
unsigned dct_y_offset;
unsigned dct_uv_offset;
int interlaced;
int cur_field;
DECLARE_ALIGNED_16(DCTELEM, blocks[8][64]);
int (*qmatrix_c) [64];
int (*qmatrix_l) [64];
uint16_t (*qmatrix_l16)[2][64];
uint16_t (*qmatrix_c16)[2][64];
unsigned frame_bits;
uint8_t *src[3];
uint32_t *vlc_codes;
uint8_t *vlc_bits;
uint16_t *run_codes;
uint8_t *run_bits;
/** Rate control */
unsigned slice_bits;
unsigned qscale;
unsigned lambda;
unsigned thread_size;
uint16_t *mb_bits;
uint8_t *mb_qscale;
RCCMPEntry *mb_cmp;
RCEntry (*mb_rc)[8160];
} DNXHDEncContext;
#define LAMBDA_FRAC_BITS 10
static int dnxhd_init_vlc(DNXHDEncContext *ctx)
{
int i, j, level, run;
int max_level = 1<<(ctx->cid_table->bit_depth+2);
CHECKED_ALLOCZ(ctx->vlc_codes, max_level*4*sizeof(*ctx->vlc_codes));
CHECKED_ALLOCZ(ctx->vlc_bits, max_level*4*sizeof(*ctx->vlc_bits));
CHECKED_ALLOCZ(ctx->run_codes, 63*2);
CHECKED_ALLOCZ(ctx->run_bits, 63);
ctx->vlc_codes += max_level*2;
ctx->vlc_bits += max_level*2;
for (level = -max_level; level < max_level; level++) {
for (run = 0; run < 2; run++) {
int index = (level<<1)|run;
int sign, offset = 0, alevel = level;
MASK_ABS(sign, alevel);
if (alevel > 64) {
offset = (alevel-1)>>6;
alevel -= offset<<6;
}
for (j = 0; j < 257; j++) {
if (ctx->cid_table->ac_level[j] == alevel &&
(!offset || (ctx->cid_table->ac_index_flag[j] && offset)) &&
(!run || (ctx->cid_table->ac_run_flag [j] && run))) {
assert(!ctx->vlc_codes[index]);
if (alevel) {
ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1);
ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1;
} else {
ctx->vlc_codes[index] = ctx->cid_table->ac_codes[j];
ctx->vlc_bits [index] = ctx->cid_table->ac_bits [j];
}
break;
}
}
assert(!alevel || j < 257);
if (offset) {
ctx->vlc_codes[index] = (ctx->vlc_codes[index]<<ctx->cid_table->index_bits)|offset;
ctx->vlc_bits [index]+= ctx->cid_table->index_bits;
}
}
}
for (i = 0; i < 62; i++) {
int run = ctx->cid_table->run[i];
assert(run < 63);
ctx->run_codes[run] = ctx->cid_table->run_codes[i];
ctx->run_bits [run] = ctx->cid_table->run_bits[i];
}
return 0;
fail:
return -1;
}
static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias)
{
// init first elem to 1 to avoid div by 0 in convert_matrix
uint16_t weight_matrix[64] = {1,}; // convert_matrix needs uint16_t*
int qscale, i;
CHECKED_ALLOCZ(ctx->qmatrix_l, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
CHECKED_ALLOCZ(ctx->qmatrix_c, (ctx->m.avctx->qmax+1) * 64 * sizeof(int));
CHECKED_ALLOCZ(ctx->qmatrix_l16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t));
CHECKED_ALLOCZ(ctx->qmatrix_c16, (ctx->m.avctx->qmax+1) * 64 * 2 * sizeof(uint16_t));
for (i = 1; i < 64; i++) {
int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
weight_matrix[j] = ctx->cid_table->luma_weight[i];
}
ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_l, ctx->qmatrix_l16, weight_matrix,
ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
for (i = 1; i < 64; i++) {
int j = ctx->m.dsp.idct_permutation[ff_zigzag_direct[i]];
weight_matrix[j] = ctx->cid_table->chroma_weight[i];
}
ff_convert_matrix(&ctx->m.dsp, ctx->qmatrix_c, ctx->qmatrix_c16, weight_matrix,
ctx->m.intra_quant_bias, 1, ctx->m.avctx->qmax, 1);
for (qscale = 1; qscale <= ctx->m.avctx->qmax; qscale++) {
for (i = 0; i < 64; i++) {
ctx->qmatrix_l [qscale] [i] <<= 2; ctx->qmatrix_c [qscale] [i] <<= 2;
ctx->qmatrix_l16[qscale][0][i] <<= 2; ctx->qmatrix_l16[qscale][1][i] <<= 2;
ctx->qmatrix_c16[qscale][0][i] <<= 2; ctx->qmatrix_c16[qscale][1][i] <<= 2;
}
}
return 0;
fail:
return -1;
}
static int dnxhd_init_rc(DNXHDEncContext *ctx)
{
CHECKED_ALLOCZ(ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry));
if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD)
CHECKED_ALLOCZ(ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry));
ctx->frame_bits = (ctx->cid_table->coding_unit_size - 640 - 4) * 8;
ctx->qscale = 1;
ctx->lambda = 2<<LAMBDA_FRAC_BITS; // qscale 2
return 0;
fail:
return -1;
}
static int dnxhd_encode_init(AVCodecContext *avctx)
{
DNXHDEncContext *ctx = avctx->priv_data;
int i, index;
ctx->cid = ff_dnxhd_find_cid(avctx);
if (!ctx->cid || avctx->pix_fmt != PIX_FMT_YUV422P) {
av_log(avctx, AV_LOG_ERROR, "video parameters incompatible with DNxHD\n");
return -1;
}
av_log(avctx, AV_LOG_DEBUG, "cid %d\n", ctx->cid);
index = ff_dnxhd_get_cid_table(ctx->cid);
ctx->cid_table = &ff_dnxhd_cid_table[index];
ctx->m.avctx = avctx;
ctx->m.mb_intra = 1;
ctx->m.h263_aic = 1;
dsputil_init(&ctx->m.dsp, avctx);
ff_dct_common_init(&ctx->m);
if (!ctx->m.dct_quantize)
ctx->m.dct_quantize = dct_quantize_c;
ctx->m.mb_height = (avctx->height + 15) / 16;
ctx->m.mb_width = (avctx->width + 15) / 16;
if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
ctx->interlaced = 1;
ctx->m.mb_height /= 2;
}
ctx->m.mb_num = ctx->m.mb_height * ctx->m.mb_width;
if (avctx->intra_quant_bias != FF_DEFAULT_QUANT_BIAS)
ctx->m.intra_quant_bias = avctx->intra_quant_bias;
if (dnxhd_init_qmat(ctx, ctx->m.intra_quant_bias, 0) < 0) // XXX tune lbias/cbias
return -1;
if (dnxhd_init_vlc(ctx) < 0)
return -1;
if (dnxhd_init_rc(ctx) < 0)
return -1;
CHECKED_ALLOCZ(ctx->slice_size, ctx->m.mb_height*sizeof(uint32_t));
CHECKED_ALLOCZ(ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t));
CHECKED_ALLOCZ(ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t));
ctx->frame.key_frame = 1;
ctx->frame.pict_type = FF_I_TYPE;
ctx->m.avctx->coded_frame = &ctx->frame;
if (avctx->thread_count > MAX_THREADS || (avctx->thread_count > ctx->m.mb_height)) {
av_log(avctx, AV_LOG_ERROR, "too many threads\n");
return -1;
}
ctx->thread[0] = ctx;
for (i = 1; i < avctx->thread_count; i++) {
ctx->thread[i] = av_malloc(sizeof(DNXHDEncContext));
memcpy(ctx->thread[i], ctx, sizeof(DNXHDEncContext));
}
for (i = 0; i < avctx->thread_count; i++) {
ctx->thread[i]->m.start_mb_y = (ctx->m.mb_height*(i ) + avctx->thread_count/2) / avctx->thread_count;
ctx->thread[i]->m.end_mb_y = (ctx->m.mb_height*(i+1) + avctx->thread_count/2) / avctx->thread_count;
}
return 0;
fail: //for CHECKED_ALLOCZ
return -1;
}
static int dnxhd_write_header(AVCodecContext *avctx, uint8_t *buf)
{
DNXHDEncContext *ctx = avctx->priv_data;
const uint8_t header_prefix[5] = { 0x00,0x00,0x02,0x80,0x01 };
memcpy(buf, header_prefix, 5);
buf[5] = ctx->interlaced ? ctx->cur_field+2 : 0x01;
buf[6] = 0x80; // crc flag off
buf[7] = 0xa0; // reserved
AV_WB16(buf + 0x18, avctx->height); // ALPF
AV_WB16(buf + 0x1a, avctx->width); // SPL
AV_WB16(buf + 0x1d, avctx->height); // NAL
buf[0x21] = 0x38; // FIXME 8 bit per comp
buf[0x22] = 0x88 + (ctx->frame.interlaced_frame<<2);
AV_WB32(buf + 0x28, ctx->cid); // CID
buf[0x2c] = ctx->interlaced ? 0 : 0x80;
buf[0x5f] = 0x01; // UDL
buf[0x167] = 0x02; // reserved
AV_WB16(buf + 0x16a, ctx->m.mb_height * 4 + 4); // MSIPS
buf[0x16d] = ctx->m.mb_height; // Ns
buf[0x16f] = 0x10; // reserved
ctx->msip = buf + 0x170;
return 0;
}
static av_always_inline void dnxhd_encode_dc(DNXHDEncContext *ctx, int diff)
{
int nbits;
if (diff < 0) {
nbits = av_log2_16bit(-2*diff);
diff--;
} else {
nbits = av_log2_16bit(2*diff);
}
put_bits(&ctx->m.pb, ctx->cid_table->dc_bits[nbits] + nbits,
(ctx->cid_table->dc_codes[nbits]<<nbits) + (diff & ((1 << nbits) - 1)));
}
static av_always_inline void dnxhd_encode_block(DNXHDEncContext *ctx, DCTELEM *block, int last_index, int n)
{
int last_non_zero = 0;
int slevel, i, j;
dnxhd_encode_dc(ctx, block[0] - ctx->m.last_dc[n]);
ctx->m.last_dc[n] = block[0];
for (i = 1; i <= last_index; i++) {
j = ctx->m.intra_scantable.permutated[i];
slevel = block[j];
if (slevel) {
int run_level = i - last_non_zero - 1;
int rlevel = (slevel<<1)|!!run_level;
put_bits(&ctx->m.pb, ctx->vlc_bits[rlevel], ctx->vlc_codes[rlevel]);
if (run_level)
put_bits(&ctx->m.pb, ctx->run_bits[run_level], ctx->run_codes[run_level]);
last_non_zero = i;
}
}
put_bits(&ctx->m.pb, ctx->vlc_bits[0], ctx->vlc_codes[0]); // EOB
}
static av_always_inline void dnxhd_unquantize_c(DNXHDEncContext *ctx, DCTELEM *block, int n, int qscale, int last_index)
{
const uint8_t *weight_matrix;
int level;
int i;
weight_matrix = (n&2) ? ctx->cid_table->chroma_weight : ctx->cid_table->luma_weight;
for (i = 1; i <= last_index; i++) {
int j = ctx->m.intra_scantable.permutated[i];
level = block[j];
if (level) {
if (level < 0) {
level = (1-2*level) * qscale * weight_matrix[i];
if (weight_matrix[i] != 32)
level += 32;
level >>= 6;
level = -level;
} else {
level = (2*level+1) * qscale * weight_matrix[i];
if (weight_matrix[i] != 32)
level += 32;
level >>= 6;
}
block[j] = level;
}
}
}
static av_always_inline int dnxhd_ssd_block(DCTELEM *qblock, DCTELEM *block)
{
int score = 0;
int i;
for (i = 0; i < 64; i++)
score += (block[i]-qblock[i])*(block[i]-qblock[i]);
return score;
}
static av_always_inline int dnxhd_calc_ac_bits(DNXHDEncContext *ctx, DCTELEM *block, int last_index)
{
int last_non_zero = 0;
int bits = 0;
int i, j, level;
for (i = 1; i <= last_index; i++) {
j = ctx->m.intra_scantable.permutated[i];
level = block[j];
if (level) {
int run_level = i - last_non_zero - 1;
bits += ctx->vlc_bits[(level<<1)|!!run_level]+ctx->run_bits[run_level];
last_non_zero = i;
}
}
return bits;
}
static av_always_inline void dnxhd_get_pixels_4x8(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
{
int i;
for (i = 0; i < 4; i++) {
block[0] = pixels[0];
block[1] = pixels[1];
block[2] = pixels[2];
block[3] = pixels[3];
block[4] = pixels[4];
block[5] = pixels[5];
block[6] = pixels[6];
block[7] = pixels[7];
pixels += line_size;
block += 8;
}
memcpy(block , block- 8, sizeof(*block)*8);
memcpy(block+ 8, block-16, sizeof(*block)*8);
memcpy(block+16, block-24, sizeof(*block)*8);
memcpy(block+24, block-32, sizeof(*block)*8);
}
static av_always_inline void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)
{
const uint8_t *ptr_y = ctx->thread[0]->src[0] + ((mb_y << 4) * ctx->m.linesize) + (mb_x << 4);
const uint8_t *ptr_u = ctx->thread[0]->src[1] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
const uint8_t *ptr_v = ctx->thread[0]->src[2] + ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << 3);
DSPContext *dsp = &ctx->m.dsp;
dsp->get_pixels(ctx->blocks[0], ptr_y , ctx->m.linesize);
dsp->get_pixels(ctx->blocks[1], ptr_y + 8, ctx->m.linesize);
dsp->get_pixels(ctx->blocks[2], ptr_u , ctx->m.uvlinesize);
dsp->get_pixels(ctx->blocks[3], ptr_v , ctx->m.uvlinesize);
if (mb_y+1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {
if (ctx->interlaced) {
dnxhd_get_pixels_4x8(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
dnxhd_get_pixels_4x8(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
dnxhd_get_pixels_4x8(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
dnxhd_get_pixels_4x8(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
} else
memset(ctx->blocks[4], 0, 4*64*sizeof(DCTELEM));
} else {
dsp->get_pixels(ctx->blocks[4], ptr_y + ctx->dct_y_offset , ctx->m.linesize);
dsp->get_pixels(ctx->blocks[5], ptr_y + ctx->dct_y_offset + 8, ctx->m.linesize);
dsp->get_pixels(ctx->blocks[6], ptr_u + ctx->dct_uv_offset , ctx->m.uvlinesize);
dsp->get_pixels(ctx->blocks[7], ptr_v + ctx->dct_uv_offset , ctx->m.uvlinesize);
}
}
static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
{
if (i&2) {
ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
ctx->m.q_intra_matrix = ctx->qmatrix_c;
return 1 + (i&1);
} else {
ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
ctx->m.q_intra_matrix = ctx->qmatrix_l;
return 0;
}
}
static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg)
{
DNXHDEncContext *ctx = arg;
int mb_y, mb_x;
int qscale = ctx->thread[0]->qscale;
for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
ctx->m.last_dc[0] =
ctx->m.last_dc[1] =
ctx->m.last_dc[2] = 1024;
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
int ssd = 0;
int ac_bits = 0;
int dc_bits = 0;
int i;
dnxhd_get_blocks(ctx, mb_x, mb_y);
for (i = 0; i < 8; i++) {
DECLARE_ALIGNED_16(DCTELEM, block[64]);
DCTELEM *src_block = ctx->blocks[i];
int overflow, nbits, diff, last_index;
int n = dnxhd_switch_matrix(ctx, i);
memcpy(block, src_block, sizeof(block));
last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
diff = block[0] - ctx->m.last_dc[n];
if (diff < 0) nbits = av_log2_16bit(-2*diff);
else nbits = av_log2_16bit( 2*diff);
dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
ctx->m.last_dc[n] = block[0];
if (avctx->mb_decision == FF_MB_DECISION_RD || !RC_VARIANCE) {
dnxhd_unquantize_c(ctx, block, i, qscale, last_index);
ctx->m.dsp.idct(block);
ssd += dnxhd_ssd_block(block, src_block);
}
}
ctx->mb_rc[qscale][mb].ssd = ssd;
ctx->mb_rc[qscale][mb].bits = ac_bits+dc_bits+12+8*ctx->vlc_bits[0];
}
}
return 0;
}
static int dnxhd_encode_thread(AVCodecContext *avctx, void *arg)
{
DNXHDEncContext *ctx = arg;
int mb_y, mb_x;
for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
ctx->m.last_dc[0] =
ctx->m.last_dc[1] =
ctx->m.last_dc[2] = 1024;
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
int qscale = ctx->mb_qscale[mb];
int i;
put_bits(&ctx->m.pb, 12, qscale<<1);
dnxhd_get_blocks(ctx, mb_x, mb_y);
for (i = 0; i < 8; i++) {
DCTELEM *block = ctx->blocks[i];
int last_index, overflow;
int n = dnxhd_switch_matrix(ctx, i);
last_index = ctx->m.dct_quantize((MpegEncContext*)ctx, block, i, qscale, &overflow);
//START_TIMER;
dnxhd_encode_block(ctx, block, last_index, n);
//STOP_TIMER("encode_block");
}
}
if (put_bits_count(&ctx->m.pb)&31)
put_bits(&ctx->m.pb, 32-(put_bits_count(&ctx->m.pb)&31), 0);
}
flush_put_bits(&ctx->m.pb);
return 0;
}
static void dnxhd_setup_threads_slices(DNXHDEncContext *ctx, uint8_t *buf)
{
int mb_y, mb_x;
int i, offset = 0;
for (i = 0; i < ctx->m.avctx->thread_count; i++) {
int thread_size = 0;
for (mb_y = ctx->thread[i]->m.start_mb_y; mb_y < ctx->thread[i]->m.end_mb_y; mb_y++) {
ctx->slice_size[mb_y] = 0;
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
ctx->slice_size[mb_y] += ctx->mb_bits[mb];
}
ctx->slice_size[mb_y] = (ctx->slice_size[mb_y]+31)&~31;
ctx->slice_size[mb_y] >>= 3;
thread_size += ctx->slice_size[mb_y];
}
init_put_bits(&ctx->thread[i]->m.pb, buf + 640 + offset, thread_size);
offset += thread_size;
}
}
static int dnxhd_mb_var_thread(AVCodecContext *avctx, void *arg)
{
DNXHDEncContext *ctx = arg;
int mb_y, mb_x;
for (mb_y = ctx->m.start_mb_y; mb_y < ctx->m.end_mb_y; mb_y++) {
for (mb_x = 0; mb_x < ctx->m.mb_width; mb_x++) {
unsigned mb = mb_y * ctx->m.mb_width + mb_x;
uint8_t *pix = ctx->thread[0]->src[0] + ((mb_y<<4) * ctx->m.linesize) + (mb_x<<4);
int sum = ctx->m.dsp.pix_sum(pix, ctx->m.linesize);
int varc = (ctx->m.dsp.pix_norm1(pix, ctx->m.linesize) - (((unsigned)(sum*sum))>>8)+128)>>8;
ctx->mb_cmp[mb].value = varc;
ctx->mb_cmp[mb].mb = mb;
}
}
return 0;
}
static int dnxhd_encode_rdo(AVCodecContext *avctx, DNXHDEncContext *ctx)
{
int lambda, up_step, down_step;
int last_lower = INT_MAX, last_higher = 0;
int x, y, q;
for (q = 1; q < avctx->qmax; q++) {
ctx->qscale = q;
avctx->execute(avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
}
up_step = down_step = 2<<LAMBDA_FRAC_BITS;
lambda = ctx->lambda;
for (;;) {
int bits = 0;
int end = 0;
if (lambda == last_higher) {
lambda++;
end = 1; // need to set final qscales/bits
}
for (y = 0; y < ctx->m.mb_height; y++) {
for (x = 0; x < ctx->m.mb_width; x++) {
unsigned min = UINT_MAX;
int qscale = 1;
int mb = y*ctx->m.mb_width+x;
for (q = 1; q < avctx->qmax; q++) {
unsigned score = ctx->mb_rc[q][mb].bits*lambda+(ctx->mb_rc[q][mb].ssd<<LAMBDA_FRAC_BITS);
if (score < min) {
min = score;
qscale = q;
}
}
bits += ctx->mb_rc[qscale][mb].bits;
ctx->mb_qscale[mb] = qscale;
ctx->mb_bits[mb] = ctx->mb_rc[qscale][mb].bits;
}
bits = (bits+31)&~31; // padding
if (bits > ctx->frame_bits)
break;
}
//dprintf(ctx->m.avctx, "lambda %d, up %u, down %u, bits %d, frame %d\n",
// lambda, last_higher, last_lower, bits, ctx->frame_bits);
if (end) {
if (bits > ctx->frame_bits)
return -1;
break;
}
if (bits < ctx->frame_bits) {
last_lower = FFMIN(lambda, last_lower);
if (last_higher != 0)
lambda = (lambda+last_higher)>>1;
else
lambda -= down_step;
down_step *= 5; // XXX tune ?
up_step = 1<<LAMBDA_FRAC_BITS;
lambda = FFMAX(1, lambda);
if (lambda == last_lower)
break;
} else {
last_higher = FFMAX(lambda, last_higher);
if (last_lower != INT_MAX)
lambda = (lambda+last_lower)>>1;
else
lambda += up_step;
up_step *= 5;
down_step = 1<<LAMBDA_FRAC_BITS;
}
}
//dprintf(ctx->m.avctx, "out lambda %d\n", lambda);
ctx->lambda = lambda;
return 0;
}
static int dnxhd_find_qscale(DNXHDEncContext *ctx)
{
int bits = 0;
int up_step = 1;
int down_step = 1;
int last_higher = 0;
int last_lower = INT_MAX;
int qscale;
int x, y;
qscale = ctx->qscale;
for (;;) {
bits = 0;
ctx->qscale = qscale;
// XXX avoid recalculating bits
ctx->m.avctx->execute(ctx->m.avctx, dnxhd_calc_bits_thread, (void**)&ctx->thread[0], NULL, ctx->m.avctx->thread_count);
for (y = 0; y < ctx->m.mb_height; y++) {
for (x = 0; x < ctx->m.mb_width; x++)
bits += ctx->mb_rc[qscale][y*ctx->m.mb_width+x].bits;
bits = (bits+31)&~31; // padding
if (bits > ctx->frame_bits)
break;
}
//dprintf(ctx->m.avctx, "%d, qscale %d, bits %d, frame %d, higher %d, lower %d\n",
// ctx->m.avctx->frame_number, qscale, bits, ctx->frame_bits, last_higher, last_lower);
if (bits < ctx->frame_bits) {
if (qscale == 1)
return 1;
if (last_higher == qscale - 1) {
qscale = last_higher;
break;
}
last_lower = FFMIN(qscale, last_lower);
if (last_higher != 0)
qscale = (qscale+last_higher)>>1;
else
qscale -= down_step++;
if (qscale < 1)
qscale = 1;
up_step = 1;
} else {
if (last_lower == qscale + 1)
break;
last_higher = FFMAX(qscale, last_higher);
if (last_lower != INT_MAX)
qscale = (qscale+last_lower)>>1;
else
qscale += up_step++;
down_step = 1;
if (qscale >= ctx->m.avctx->qmax)
return -1;
}
}
//dprintf(ctx->m.avctx, "out qscale %d\n", qscale);
ctx->qscale = qscale;
return 0;
}
static int dnxhd_rc_cmp(const void *a, const void *b)
{
return ((const RCCMPEntry *)b)->value - ((const RCCMPEntry *)a)->value;
}
static int dnxhd_encode_fast(AVCodecContext *avctx, DNXHDEncContext *ctx)
{
int max_bits = 0;
int ret, x, y;
if ((ret = dnxhd_find_qscale(ctx)) < 0)
return -1;
for (y = 0; y < ctx->m.mb_height; y++) {
for (x = 0; x < ctx->m.mb_width; x++) {
int mb = y*ctx->m.mb_width+x;
int delta_bits;
ctx->mb_qscale[mb] = ctx->qscale;
ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale][mb].bits;
max_bits += ctx->mb_rc[ctx->qscale][mb].bits;
if (!RC_VARIANCE) {
delta_bits = ctx->mb_rc[ctx->qscale][mb].bits-ctx->mb_rc[ctx->qscale+1][mb].bits;
ctx->mb_cmp[mb].mb = mb;
ctx->mb_cmp[mb].value = delta_bits ?
((ctx->mb_rc[ctx->qscale][mb].ssd-ctx->mb_rc[ctx->qscale+1][mb].ssd)*100)/delta_bits
: INT_MIN; //avoid increasing qscale
}
}
max_bits += 31; //worst padding
}
if (!ret) {
if (RC_VARIANCE)
avctx->execute(avctx, dnxhd_mb_var_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
qsort(ctx->mb_cmp, ctx->m.mb_num, sizeof(RCEntry), dnxhd_rc_cmp);
for (x = 0; x < ctx->m.mb_num && max_bits > ctx->frame_bits; x++) {
int mb = ctx->mb_cmp[x].mb;
max_bits -= ctx->mb_rc[ctx->qscale][mb].bits - ctx->mb_rc[ctx->qscale+1][mb].bits;
ctx->mb_qscale[mb] = ctx->qscale+1;
ctx->mb_bits[mb] = ctx->mb_rc[ctx->qscale+1][mb].bits;
}
}
return 0;
}
static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame)
{
int i;
for (i = 0; i < 3; i++) {
ctx->frame.data[i] = frame->data[i];
ctx->frame.linesize[i] = frame->linesize[i];
}
for (i = 0; i < ctx->m.avctx->thread_count; i++) {
ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<<ctx->interlaced;
ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<<ctx->interlaced;
ctx->thread[i]->dct_y_offset = ctx->m.linesize *8;
ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8;
}
ctx->frame.interlaced_frame = frame->interlaced_frame;
ctx->cur_field = frame->interlaced_frame && !frame->top_field_first;
}
static int dnxhd_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, const void *data)
{
DNXHDEncContext *ctx = avctx->priv_data;
int first_field = 1;
int offset, i, ret;
if (buf_size < ctx->cid_table->frame_size) {
av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n");
return -1;
}
dnxhd_load_picture(ctx, data);
encode_coding_unit:
for (i = 0; i < 3; i++) {
ctx->src[i] = ctx->frame.data[i];
if (ctx->interlaced && ctx->cur_field)
ctx->src[i] += ctx->frame.linesize[i];
}
dnxhd_write_header(avctx, buf);
if (avctx->mb_decision == FF_MB_DECISION_RD)
ret = dnxhd_encode_rdo(avctx, ctx);
else
ret = dnxhd_encode_fast(avctx, ctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "picture could not fit ratecontrol constraints\n");
return -1;
}
dnxhd_setup_threads_slices(ctx, buf);
offset = 0;
for (i = 0; i < ctx->m.mb_height; i++) {
AV_WB32(ctx->msip + i * 4, offset);
offset += ctx->slice_size[i];
assert(!(ctx->slice_size[i] & 3));
}
avctx->execute(avctx, dnxhd_encode_thread, (void**)&ctx->thread[0], NULL, avctx->thread_count);
AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
if (ctx->interlaced && first_field) {
first_field = 0;
ctx->cur_field ^= 1;
buf += ctx->cid_table->coding_unit_size;
buf_size -= ctx->cid_table->coding_unit_size;
goto encode_coding_unit;
}
ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA;
return ctx->cid_table->frame_size;
}
static int dnxhd_encode_end(AVCodecContext *avctx)
{
DNXHDEncContext *ctx = avctx->priv_data;
int max_level = 1<<(ctx->cid_table->bit_depth+2);
int i;
av_free(ctx->vlc_codes-max_level*2);
av_free(ctx->vlc_bits -max_level*2);
av_freep(&ctx->run_codes);
av_freep(&ctx->run_bits);
av_freep(&ctx->mb_bits);
av_freep(&ctx->mb_qscale);
av_freep(&ctx->mb_rc);
av_freep(&ctx->mb_cmp);
av_freep(&ctx->slice_size);
av_freep(&ctx->qmatrix_c);
av_freep(&ctx->qmatrix_l);
av_freep(&ctx->qmatrix_c16);
av_freep(&ctx->qmatrix_l16);
for (i = 1; i < avctx->thread_count; i++)
av_freep(&ctx->thread[i]);
return 0;
}
AVCodec dnxhd_encoder = {
"dnxhd",
CODEC_TYPE_VIDEO,
CODEC_ID_DNXHD,
sizeof(DNXHDEncContext),
dnxhd_encode_init,
dnxhd_encode_picture,
dnxhd_encode_end,
.pix_fmts = (enum PixelFormat[]){PIX_FMT_YUV422P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
};

View File

@ -2,19 +2,21 @@
* Assorted DPCM codecs
* Copyright (c) 2003 The ffmpeg Project.
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@ -24,6 +26,7 @@
* Xan DPCM decoder by Mario Brito (mbrito@student.dei.uc.pt)
* for more information on the specific data formats, visit:
* http://www.pcisys.net/~melanson/codecs/simpleaudio.html
* SOL DPCMs implemented by Konstantin Shishkov
*
* Note about using the Xan DPCM decoder: Xan DPCM is used in AVI files
* found in the Wing Commander IV computer game. These AVI files contain
@ -39,18 +42,13 @@
typedef struct DPCMContext {
int channels;
short roq_square_array[256];
long sample[2];//for SOL_DPCM
const int *sol_table;//for SOL_DPCM
} DPCMContext;
#define SATURATE_S16(x) if (x < -32768) x = -32768; \
else if (x > 32767) x = 32767;
#define SE_16BIT(x) if (x & 0x8000) x -= 0x10000;
#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \
(((uint8_t*)(x))[2] << 16) | \
(((uint8_t*)(x))[1] << 8) | \
((uint8_t*)(x))[0])
static int interplay_delta_table[] = {
static const int interplay_delta_table[] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
@ -86,13 +84,40 @@ static int interplay_delta_table[] = {
};
static int dpcm_decode_init(AVCodecContext *avctx)
static const int sol_table_old[16] =
{ 0x0, 0x1, 0x2 , 0x3, 0x6, 0xA, 0xF, 0x15,
-0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0};
static const int sol_table_new[16] =
{ 0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15};
static const int sol_table_16[128] = {
0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
};
static av_cold int dpcm_decode_init(AVCodecContext *avctx)
{
DPCMContext *s = avctx->priv_data;
int i;
short square;
s->channels = avctx->channels;
s->sample[0] = s->sample[1] = 0;
switch(avctx->codec->id) {
@ -105,16 +130,37 @@ static int dpcm_decode_init(AVCodecContext *avctx)
}
break;
case CODEC_ID_SOL_DPCM:
switch(avctx->codec_tag){
case 1:
s->sol_table=sol_table_old;
s->sample[0] = s->sample[1] = 0x80;
break;
case 2:
s->sol_table=sol_table_new;
s->sample[0] = s->sample[1] = 0x80;
break;
case 3:
s->sol_table=sol_table_16;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
return -1;
}
break;
default:
break;
}
avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
static int dpcm_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
const uint8_t *buf, int buf_size)
{
DPCMContext *s = avctx->priv_data;
int in, out = 0;
@ -128,11 +174,15 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
if (!buf_size)
return 0;
// almost every DPCM variant expands one byte of data into two
if(*data_size/2 < buf_size)
return -1;
switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM:
if (s->channels == 1)
predictor[0] = LE_16(&buf[6]);
predictor[0] = AV_RL16(&buf[6]);
else {
predictor[0] = buf[7] << 8;
predictor[1] = buf[6] << 8;
@ -143,7 +193,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
/* decode the samples */
for (in = 8, out = 0; in < buf_size; in++, out++) {
predictor[channel_number] += s->roq_square_array[buf[in]];
SATURATE_S16(predictor[channel_number]);
predictor[channel_number] = av_clip_int16(predictor[channel_number]);
output_samples[out] = predictor[channel_number];
/* toggle channel */
@ -153,12 +203,12 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
case CODEC_ID_INTERPLAY_DPCM:
in = 6; /* skip over the stream mask and stream length */
predictor[0] = LE_16(&buf[in]);
predictor[0] = AV_RL16(&buf[in]);
in += 2;
SE_16BIT(predictor[0])
output_samples[out++] = predictor[0];
if (s->channels == 2) {
predictor[1] = LE_16(&buf[in]);
predictor[1] = AV_RL16(&buf[in]);
in += 2;
SE_16BIT(predictor[1])
output_samples[out++] = predictor[1];
@ -166,7 +216,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
while (in < buf_size) {
predictor[channel_number] += interplay_delta_table[buf[in++]];
SATURATE_S16(predictor[channel_number]);
predictor[channel_number] = av_clip_int16(predictor[channel_number]);
output_samples[out++] = predictor[channel_number];
/* toggle channel */
@ -178,11 +228,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
case CODEC_ID_XAN_DPCM:
in = 0;
shift[0] = shift[1] = 4;
predictor[0] = LE_16(&buf[in]);
predictor[0] = AV_RL16(&buf[in]);
in += 2;
SE_16BIT(predictor[0]);
if (s->channels == 2) {
predictor[1] = LE_16(&buf[in]);
predictor[1] = AV_RL16(&buf[in]);
in += 2;
SE_16BIT(predictor[1]);
}
@ -201,48 +251,64 @@ static int dpcm_decode_frame(AVCodecContext *avctx,
diff >>= shift[channel_number];
predictor[channel_number] += diff;
SATURATE_S16(predictor[channel_number]);
predictor[channel_number] = av_clip_int16(predictor[channel_number]);
output_samples[out++] = predictor[channel_number];
/* toggle channel */
channel_number ^= s->channels - 1;
}
break;
case CODEC_ID_SOL_DPCM:
in = 0;
if (avctx->codec_tag != 3) {
if(*data_size/4 < buf_size)
return -1;
while (in < buf_size) {
int n1, n2;
n1 = (buf[in] >> 4) & 0xF;
n2 = buf[in++] & 0xF;
s->sample[0] += s->sol_table[n1];
if (s->sample[0] < 0) s->sample[0] = 0;
if (s->sample[0] > 255) s->sample[0] = 255;
output_samples[out++] = (s->sample[0] - 128) << 8;
s->sample[s->channels - 1] += s->sol_table[n2];
if (s->sample[s->channels - 1] < 0) s->sample[s->channels - 1] = 0;
if (s->sample[s->channels - 1] > 255) s->sample[s->channels - 1] = 255;
output_samples[out++] = (s->sample[s->channels - 1] - 128) << 8;
}
} else {
while (in < buf_size) {
int n;
n = buf[in++];
if (n & 0x80) s->sample[channel_number] -= s->sol_table[n & 0x7F];
else s->sample[channel_number] += s->sol_table[n & 0x7F];
s->sample[channel_number] = av_clip_int16(s->sample[channel_number]);
output_samples[out++] = s->sample[channel_number];
/* toggle channel */
channel_number ^= s->channels - 1;
}
}
break;
}
*data_size = out * sizeof(short);
return buf_size;
}
AVCodec roq_dpcm_decoder = {
"roq_dpcm",
CODEC_TYPE_AUDIO,
CODEC_ID_ROQ_DPCM,
sizeof(DPCMContext),
dpcm_decode_init,
NULL,
NULL,
dpcm_decode_frame,
#define DPCM_DECODER(id, name, long_name_) \
AVCodec name ## _decoder = { \
#name, \
CODEC_TYPE_AUDIO, \
id, \
sizeof(DPCMContext), \
dpcm_decode_init, \
NULL, \
NULL, \
dpcm_decode_frame, \
.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
};
AVCodec interplay_dpcm_decoder = {
"interplay_dpcm",
CODEC_TYPE_AUDIO,
CODEC_ID_INTERPLAY_DPCM,
sizeof(DPCMContext),
dpcm_decode_init,
NULL,
NULL,
dpcm_decode_frame,
};
AVCodec xan_dpcm_decoder = {
"xan_dpcm",
CODEC_TYPE_AUDIO,
CODEC_ID_XAN_DPCM,
sizeof(DPCMContext),
dpcm_decode_init,
NULL,
NULL,
dpcm_decode_frame,
};
DPCM_DECODER(CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "Interplay DPCM");
DPCM_DECODER(CODEC_ID_ROQ_DPCM, roq_dpcm, "id RoQ DPCM");
DPCM_DECODER(CODEC_ID_SOL_DPCM, sol_dpcm, "Sol DPCM");
DPCM_DECODER(CODEC_ID_XAN_DPCM, xan_dpcm, "Xan DPCM");

View File

@ -0,0 +1,365 @@
/*
* Delphine Software International CIN Audio/Video Decoders
* Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.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
*/
/**
* @file dsicinav.c
* Delphine Software International CIN audio/video decoders
*/
#include "avcodec.h"
#include "bytestream.h"
typedef enum CinVideoBitmapIndex {
CIN_CUR_BMP = 0, /* current */
CIN_PRE_BMP = 1, /* previous */
CIN_INT_BMP = 2 /* intermediate */
} CinVideoBitmapIndex;
typedef struct CinVideoContext {
AVCodecContext *avctx;
AVFrame frame;
unsigned int bitmap_size;
uint32_t palette[256];
uint8_t *bitmap_table[3];
} CinVideoContext;
typedef struct CinAudioContext {
AVCodecContext *avctx;
int initial_decode_frame;
int delta;
} CinAudioContext;
/* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
static const int16_t cinaudio_delta16_table[256] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, -30210, -27853, -25680, -23677, -21829,
-20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
-10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951,
-5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107,
-2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622,
-1495, -1379, -1271, -1172, -1080, -996, -918, -847,
-781, -720, -663, -612, -564, -520, -479, -442,
-407, -376, -346, -319, -294, -271, -250, -230,
-212, -196, -181, -166, -153, -141, -130, -120,
-111, -102, -94, -87, -80, -74, -68, -62,
-58, -53, -49, -45, -41, -38, -35, -32,
-30, -27, -25, -23, -21, -20, -18, -17,
-15, -14, -13, -12, -11, -10, -9, -8,
-7, -6, -5, -4, -3, -2, -1, 0,
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
17, 18, 20, 21, 23, 25, 27, 30,
32, 35, 38, 41, 45, 49, 53, 58,
62, 68, 74, 80, 87, 94, 102, 111,
120, 130, 141, 153, 166, 181, 196, 212,
230, 250, 271, 294, 319, 346, 376, 407,
442, 479, 520, 564, 612, 663, 720, 781,
847, 918, 996, 1080, 1172, 1271, 1379, 1495,
1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865,
3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487,
5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508,
11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126,
21829, 23677, 25680, 27853, 30210, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
{
CinVideoContext *cin = avctx->priv_data;
unsigned int i;
cin->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
cin->frame.data[0] = NULL;
cin->bitmap_size = avctx->width * avctx->height;
for (i = 0; i < 3; ++i) {
cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
if (!cin->bitmap_table[i])
av_log(avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
}
return 0;
}
static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
{
while (size--)
*dst++ += *src++;
}
static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
int b, huff_code = 0;
unsigned char huff_code_table[15];
unsigned char *dst_cur = dst;
unsigned char *dst_end = dst + dst_size;
const unsigned char *src_end = src + src_size;
memcpy(huff_code_table, src, 15); src += 15; src_size -= 15;
while (src < src_end) {
huff_code = *src++;
if ((huff_code >> 4) == 15) {
b = huff_code << 4;
huff_code = *src++;
*dst_cur++ = b | (huff_code >> 4);
} else
*dst_cur++ = huff_code_table[huff_code >> 4];
if (dst_cur >= dst_end)
break;
huff_code &= 15;
if (huff_code == 15) {
*dst_cur++ = *src++;
} else
*dst_cur++ = huff_code_table[huff_code];
if (dst_cur >= dst_end)
break;
}
return dst_cur - dst;
}
static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
uint16_t cmd;
int i, sz, offset, code;
unsigned char *dst_end = dst + dst_size;
const unsigned char *src_end = src + src_size;
while (src < src_end && dst < dst_end) {
code = *src++;
for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
if (code & (1 << i)) {
*dst++ = *src++;
} else {
cmd = AV_RL16(src); src += 2;
offset = cmd >> 4;
sz = (cmd & 0xF) + 2;
/* don't use memcpy/memmove here as the decoding routine (ab)uses */
/* buffer overlappings to repeat bytes in the destination */
sz = FFMIN(sz, dst_end - dst);
while (sz--) {
*dst = *(dst - offset - 1);
++dst;
}
}
}
}
}
static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
{
int len, code;
unsigned char *dst_end = dst + dst_size;
const unsigned char *src_end = src + src_size;
while (src < src_end && dst < dst_end) {
code = *src++;
if (code & 0x80) {
len = code - 0x7F;
memset(dst, *src++, FFMIN(len, dst_end - dst));
} else {
len = code + 1;
memcpy(dst, src, FFMIN(len, dst_end - dst));
src += len;
}
dst += len;
}
}
static int cinvideo_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
CinVideoContext *cin = avctx->priv_data;
int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size;
cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &cin->frame)) {
av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n");
return -1;
}
palette_type = buf[0];
palette_colors_count = AV_RL16(buf+1);
bitmap_frame_type = buf[3];
buf += 4;
bitmap_frame_size = buf_size - 4;
/* handle palette */
if (palette_type == 0) {
for (i = 0; i < palette_colors_count; ++i) {
cin->palette[i] = bytestream_get_le24(&buf);
bitmap_frame_size -= 3;
}
} else {
for (i = 0; i < palette_colors_count; ++i) {
cin->palette[buf[0]] = AV_RL24(buf+1);
buf += 4;
bitmap_frame_size -= 4;
}
}
memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
cin->frame.palette_has_changed = 1;
/* note: the decoding routines below assumes that surface.width = surface.pitch */
switch (bitmap_frame_type) {
case 9:
cin_decode_rle(buf, bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 34:
cin_decode_rle(buf, bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 35:
cin_decode_huffman(buf, bitmap_frame_size,
cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 36:
bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 37:
cin_decode_huffman(buf, bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 38:
cin_decode_lzss(buf, bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
case 39:
cin_decode_lzss(buf, bitmap_frame_size,
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP],
cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
break;
}
for (y = 0; y < cin->avctx->height; ++y)
memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
cin->avctx->width);
FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
*data_size = sizeof(AVFrame);
*(AVFrame *)data = cin->frame;
return buf_size;
}
static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
{
CinVideoContext *cin = avctx->priv_data;
int i;
if (cin->frame.data[0])
avctx->release_buffer(avctx, &cin->frame);
for (i = 0; i < 3; ++i)
av_free(cin->bitmap_table[i]);
return 0;
}
static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
{
CinAudioContext *cin = avctx->priv_data;
cin->avctx = avctx;
cin->initial_decode_frame = 1;
cin->delta = 0;
avctx->sample_fmt = SAMPLE_FMT_S16;
return 0;
}
static int cinaudio_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
CinAudioContext *cin = avctx->priv_data;
const uint8_t *src = buf;
int16_t *samples = (int16_t *)data;
buf_size = FFMIN(buf_size, *data_size/2);
if (cin->initial_decode_frame) {
cin->initial_decode_frame = 0;
cin->delta = (int16_t)AV_RL16(src); src += 2;
*samples++ = cin->delta;
buf_size -= 2;
}
while (buf_size > 0) {
cin->delta += cinaudio_delta16_table[*src++];
cin->delta = av_clip_int16(cin->delta);
*samples++ = cin->delta;
--buf_size;
}
*data_size = (uint8_t *)samples - (uint8_t *)data;
return src - buf;
}
AVCodec dsicinvideo_decoder = {
"dsicinvideo",
CODEC_TYPE_VIDEO,
CODEC_ID_DSICINVIDEO,
sizeof(CinVideoContext),
cinvideo_decode_init,
NULL,
cinvideo_decode_end,
cinvideo_decode_frame,
CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
};
AVCodec dsicinaudio_decoder = {
"dsicinaudio",
CODEC_TYPE_AUDIO,
CODEC_ID_DSICINAUDIO,
sizeof(CinAudioContext),
cinaudio_decode_init,
NULL,
NULL,
cinaudio_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
};

File diff suppressed because it is too large Load Diff

View File

@ -3,19 +3,21 @@
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
*
* This library is free software; you can redistribute it and/or
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@ -25,16 +27,17 @@
* absolutely necessary to call emms_c() between dsp & float/double code
*/
#ifndef DSPUTIL_H
#define DSPUTIL_H
#ifndef FFMPEG_DSPUTIL_H
#define FFMPEG_DSPUTIL_H
#include "common.h"
#include "avcodec.h"
//#define DEBUG
/* dct code */
typedef short DCTELEM;
typedef int DWTELEM;
typedef short IDWTELEM;
void fdct_ifast (DCTELEM *data);
void fdct_ifast248 (DCTELEM *data);
@ -42,11 +45,29 @@ void ff_jpeg_fdct_islow (DCTELEM *data);
void ff_fdct248_islow (DCTELEM *data);
void j_rev_dct (DCTELEM *data);
void j_rev_dct4 (DCTELEM *data);
void j_rev_dct2 (DCTELEM *data);
void j_rev_dct1 (DCTELEM *data);
void ff_wmv2_idct_c(DCTELEM *data);
void ff_fdct_mmx(DCTELEM *block);
void ff_fdct_mmx2(DCTELEM *block);
void ff_fdct_sse2(DCTELEM *block);
void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride);
void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride);
void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride);
void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride);
void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block);
void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block);
void ff_vector_fmul_add_add_c(float *dst, const float *src0, const float *src1,
const float *src2, int src3, int blocksize, int step);
void ff_vector_fmul_window_c(float *dst, const float *src0, const float *src1,
const float *win, float add_bias, int len);
void ff_float_to_int16_c(int16_t *dst, const float *src, long len);
void ff_float_to_int16_interleave_c(int16_t *dst, const float **src, long len, int channels);
/* encoding scans */
extern const uint8_t ff_alternate_horizontal_scan[64];
extern const uint8_t ff_alternate_vertical_scan[64];
@ -54,19 +75,35 @@ extern const uint8_t ff_zigzag_direct[64];
extern const uint8_t ff_zigzag248_direct[64];
/* pixel operations */
#define MAX_NEG_CROP 384
#define MAX_NEG_CROP 1024
/* temporary */
extern uint32_t squareTbl[512];
extern uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
extern uint32_t ff_squareTbl[512];
extern uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];
/* VP3 DSP functions */
void ff_vp3_idct_c(DCTELEM *block/* align 16*/);
void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
/* 1/2^n downscaling functions from imgconvert.c */
void ff_img_copy_plane(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink22(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink44(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_shrink88(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
void ff_gmc_c(uint8_t *dst, uint8_t *src, int stride, int h, int ox, int oy,
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
/* minimum alignment rules ;)
if u notice errors in the align stuff, need more alignment for some asm code for some cpu
or need to use a function with less aligned data then send a mail to the ffmpeg-dev list, ...
If you notice errors in the align stuff, need more alignment for some ASM code
for some CPU or need to use a function with less aligned data then send a mail
to the ffmpeg-devel mailing list, ...
!warning these alignments might not match reallity, (missing attribute((align)) stuff somewhere possible)
i (michael) didnt check them, these are just the alignents which i think could be reached easily ...
!warning These alignments might not match reality, (missing attribute((align))
stuff somewhere possible).
I (Michael) did not check them, these are just the alignments which I think
could be reached easily ...
!future video codecs might need functions with less strict alignment
*/
@ -86,6 +123,8 @@ typedef void (*op_pixels_func)(uint8_t *block/*align width (8 or 16)*/, const ui
typedef void (*tpel_mc_func)(uint8_t *block/*align width (8 or 16)*/, const uint8_t *pixels/*align 1*/, int line_size, int w, int h);
typedef void (*qpel_mc_func)(uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);
typedef void (*h264_chroma_mc_func)(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
typedef void (*h264_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int offset);
typedef void (*h264_biweight_func)(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offset);
#define DEF_OLD_QPEL(name)\
void ff_put_ ## name (uint8_t *dst/*align width (8 or 16)*/, uint8_t *src/*align 1*/, int stride);\
@ -113,10 +152,32 @@ static void a(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
/* motion estimation */
// h is limited to {width/2, width, 2*width} but never larger than 16 and never smaller then 2
// allthough currently h<4 is not used as functions with width <8 are not used and neither implemented
// although currently h<4 is not used as functions with width <8 are neither used nor implemented
typedef int (*me_cmp_func)(void /*MpegEncContext*/ *s, uint8_t *blk1/*align width (8 or 16)*/, uint8_t *blk2/*align 1*/, int line_size, int h)/* __attribute__ ((const))*/;
// for snow slices
typedef struct slice_buffer_s slice_buffer;
/**
* Scantable.
*/
typedef struct ScanTable{
const uint8_t *scantable;
uint8_t permutated[64];
uint8_t raster_end[64];
#ifdef ARCH_POWERPC
/** Used by dct_quantize_altivec to find last-non-zero */
DECLARE_ALIGNED(16, uint8_t, inverse[64]);
#endif
} ScanTable;
void ff_init_scantable(uint8_t *, ScanTable *st, const uint8_t *src_scantable);
void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize,
int block_w, int block_h,
int src_x, int src_y, int w, int h);
/**
* DSPContext.
*/
@ -125,7 +186,11 @@ typedef struct DSPContext {
void (*get_pixels)(DCTELEM *block/*align 16*/, const uint8_t *pixels/*align 8*/, int line_size);
void (*diff_pixels)(DCTELEM *block/*align 16*/, const uint8_t *s1/*align 8*/, const uint8_t *s2/*align 8*/, int stride);
void (*put_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*put_signed_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels_clamped)(const DCTELEM *block/*align 16*/, uint8_t *pixels/*align 8*/, int line_size);
void (*add_pixels8)(uint8_t *pixels, DCTELEM *block, int line_size);
void (*add_pixels4)(uint8_t *pixels, DCTELEM *block, int line_size);
int (*sum_abs_dctelem)(DCTELEM *block/*align 16*/);
/**
* translational global motion compensation.
*/
@ -134,12 +199,12 @@ typedef struct DSPContext {
* global motion compensation.
*/
void (*gmc )(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int ox, int oy,
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
int dxx, int dxy, int dyx, int dyy, int shift, int r, int width, int height);
void (*clear_blocks)(DCTELEM *blocks/*align 16*/);
int (*pix_sum)(uint8_t * pix, int line_size);
int (*pix_norm1)(uint8_t * pix, int line_size);
// 16x16 8x8 4x4 2x2 16x8 8x4 4x2 8x16 4x8 2x4
me_cmp_func sad[5]; /* identical to pix_absAxA except additional void * */
me_cmp_func sse[5];
me_cmp_func hadamard8_diff[5];
@ -149,16 +214,25 @@ typedef struct DSPContext {
me_cmp_func rd[5];
me_cmp_func vsad[5];
me_cmp_func vsse[5];
me_cmp_func nsse[5];
me_cmp_func w53[5];
me_cmp_func w97[5];
me_cmp_func dct_max[5];
me_cmp_func dct264_sad[5];
me_cmp_func me_pre_cmp[5];
me_cmp_func me_cmp[5];
me_cmp_func me_sub_cmp[5];
me_cmp_func mb_cmp[5];
me_cmp_func ildct_cmp[5]; //only width 16 used
me_cmp_func frame_skip_cmp[5]; //only width 8 used
int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2,
int size);
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
* this is an array[4][4] of motion compensation funcions for 4
* this is an array[4][4] of motion compensation functions for 4
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
@ -170,7 +244,7 @@ typedef struct DSPContext {
/**
* Halfpel motion compensation with rounding (a+b+1)>>1.
* This is an array[4][4] of motion compensation functions for 4
* This is an array[4][4] of motion compensation functions for 4
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b+1)>>1
@ -182,7 +256,7 @@ typedef struct DSPContext {
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
* this is an array[2][4] of motion compensation funcions for 2
* this is an array[2][4] of motion compensation functions for 2
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination where the result is stored
@ -190,11 +264,11 @@ typedef struct DSPContext {
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func put_no_rnd_pixels_tab[2][4];
op_pixels_func put_no_rnd_pixels_tab[4][4];
/**
* Halfpel motion compensation with no rounding (a+b)>>1.
* this is an array[2][4] of motion compensation funcions for 2
* this is an array[2][4] of motion compensation functions for 2
* horizontal blocksizes (8,16) and the 4 halfpel positions<br>
* *pixels_tab[ 0->16xH 1->8xH ][ xhalfpel + 2*yhalfpel ]
* @param block destination into which the result is averaged (a+b)>>1
@ -202,11 +276,14 @@ typedef struct DSPContext {
* @param line_size number of bytes in a horizontal line of block
* @param h height
*/
op_pixels_func avg_no_rnd_pixels_tab[2][4];
op_pixels_func avg_no_rnd_pixels_tab[4][4];
void (*put_no_rnd_pixels_l2[2])(uint8_t *block/*align width (8 or 16)*/, const uint8_t *a/*align 1*/, const uint8_t *b/*align 1*/, int line_size, int h);
/**
* Thirdpel motion compensation with rounding (a+b+1)>>1.
* this is an array[12] of motion compensation funcions for the 9 thirdpel positions<br>
* this is an array[12] of motion compensation functions for the 9 thirdpe
* positions<br>
* *pixels_tab[ xthirdpel + 4*ythirdpel ]
* @param block destination where the result is stored
* @param pixels source
@ -221,51 +298,107 @@ typedef struct DSPContext {
qpel_mc_func put_no_rnd_qpel_pixels_tab[2][16];
qpel_mc_func avg_no_rnd_qpel_pixels_tab[2][16];
qpel_mc_func put_mspel_pixels_tab[8];
/**
* h264 Chram MC
* h264 Chroma MC
*/
h264_chroma_mc_func put_h264_chroma_pixels_tab[3];
/* This is really one func used in VC-1 decoding */
h264_chroma_mc_func put_no_rnd_h264_chroma_pixels_tab[3];
h264_chroma_mc_func avg_h264_chroma_pixels_tab[3];
qpel_mc_func put_h264_qpel_pixels_tab[3][16];
qpel_mc_func avg_h264_qpel_pixels_tab[3][16];
qpel_mc_func put_h264_qpel_pixels_tab[4][16];
qpel_mc_func avg_h264_qpel_pixels_tab[4][16];
qpel_mc_func put_2tap_qpel_pixels_tab[4][16];
qpel_mc_func avg_2tap_qpel_pixels_tab[4][16];
h264_weight_func weight_h264_pixels_tab[10];
h264_biweight_func biweight_h264_pixels_tab[10];
/* AVS specific */
qpel_mc_func put_cavs_qpel_pixels_tab[2][16];
qpel_mc_func avg_cavs_qpel_pixels_tab[2][16];
void (*cavs_filter_lv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
void (*cavs_filter_lh)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
void (*cavs_filter_cv)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
void (*cavs_filter_ch)(uint8_t *pix, int stride, int alpha, int beta, int tc, int bs1, int bs2);
void (*cavs_idct8_add)(uint8_t *dst, DCTELEM *block, int stride);
me_cmp_func pix_abs[2][4];
/* huffyuv specific */
void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w);
void (*add_bytes_l2)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 16*/, int w);
void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w);
/**
* subtract huffyuv's variant of median prediction
* note, this might read from src1[-1], src2[-1]
*/
void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top);
void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w);
/* this might write to dst[w] */
void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp);
void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);
void (*h264_v_loop_filter_luma)(uint8_t *pix/*align 16*/, int stride, int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_luma)(uint8_t *pix/*align 4 */, int stride, int alpha, int beta, int8_t *tc0);
/* v/h_loop_filter_luma_intra: align 16 */
void (*h264_v_loop_filter_chroma)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta, int8_t *tc0);
void (*h264_h_loop_filter_chroma)(uint8_t *pix/*align 4*/, int stride, int alpha, int beta, int8_t *tc0);
void (*h264_v_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta);
void (*h264_h_loop_filter_chroma_intra)(uint8_t *pix/*align 8*/, int stride, int alpha, int beta);
// h264_loop_filter_strength: simd only. the C version is inlined in h264.c
void (*h264_loop_filter_strength)(int16_t bS[2][4][4], uint8_t nnz[40], int8_t ref[2][40], int16_t mv[2][40][2],
int bidir, int edges, int step, int mask_mv0, int mask_mv1, int field);
void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale);
void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale);
void (*h261_loop_filter)(uint8_t *src, int stride);
void (*x8_v_loop_filter)(uint8_t *src, int stride, int qscale);
void (*x8_h_loop_filter)(uint8_t *src, int stride, int qscale);
/* assume len is a multiple of 4, and arrays are 16-byte aligned */
void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize);
void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len);
/* no alignment needed */
void (*flac_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc);
/* assume len is a multiple of 8, and arrays are 16-byte aligned */
void (*vector_fmul)(float *dst, const float *src, int len);
void (*vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len);
/* assume len is a multiple of 8, and src arrays are 16-byte aligned */
void (*vector_fmul_add_add)(float *dst, const float *src0, const float *src1, const float *src2, int src3, int len, int step);
/* assume len is a multiple of 4, and arrays are 16-byte aligned */
void (*vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, float add_bias, int len);
/* assume len is a multiple of 8, and arrays are 16-byte aligned */
void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
/* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767]
* simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */
void (*float_to_int16)(int16_t *dst, const float *src, long len);
void (*float_to_int16_interleave)(int16_t *dst, const float **src, long len, int channels);
/* (I)DCT */
void (*fdct)(DCTELEM *block/* align 16*/);
void (*fdct248)(DCTELEM *block/* align 16*/);
/* IDCT really*/
void (*idct)(DCTELEM *block/* align 16*/);
/**
* block -> idct -> clip to unsigned 8 bit -> dest.
* (-1392, 0, 0, ...) -> idct -> (-174, -174, ...) -> put -> (0, 0, ...)
* @param line_size size in bytes of a horizotal line of dest
* @param line_size size in bytes of a horizontal line of dest
*/
void (*idct_put)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
/**
* block -> idct -> add dest -> clip to unsigned 8 bit -> dest.
* @param line_size size in bytes of a horizotal line of dest
* @param line_size size in bytes of a horizontal line of dest
*/
void (*idct_add)(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/);
/**
* idct input permutation.
* several optimized IDCTs need a permutated input (relative to the normal order of the reference
@ -284,12 +417,74 @@ typedef struct DSPContext {
#define FF_LIBMPEG2_IDCT_PERM 2
#define FF_SIMPLE_IDCT_PERM 3
#define FF_TRANSPOSE_IDCT_PERM 4
#define FF_PARTTRANS_IDCT_PERM 5
#define FF_SSE2_IDCT_PERM 6
int (*try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale);
void (*add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale);
#define BASIS_SHIFT 16
#define RECON_SHIFT 6
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w);
#define EDGE_WIDTH 16
/* h264 functions */
void (*h264_idct_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride);
void (*h264_idct8_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride);
void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride);
void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride);
void (*h264_dct)(DCTELEM block[4][4]);
/* snow wavelet */
void (*vertical_compose97i)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width);
void (*horizontal_compose97i)(IDWTELEM *b, int width);
void (*inner_add_yblock)(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8);
void (*prefetch)(void *mem, int stride, int h);
void (*shrink[4])(uint8_t *dst, int dst_wrap, const uint8_t *src, int src_wrap, int width, int height);
/* vc1 functions */
void (*vc1_inv_trans_8x8)(DCTELEM *b);
void (*vc1_inv_trans_8x4)(uint8_t *dest, int line_size, DCTELEM *block);
void (*vc1_inv_trans_4x8)(uint8_t *dest, int line_size, DCTELEM *block);
void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block);
void (*vc1_v_overlap)(uint8_t* src, int stride);
void (*vc1_h_overlap)(uint8_t* src, int stride);
/* put 8x8 block with bicubic interpolation and quarterpel precision
* last argument is actually round value instead of height
*/
op_pixels_func put_vc1_mspel_pixels_tab[16];
/* intrax8 functions */
void (*x8_spatial_compensation[12])(uint8_t *src , uint8_t *dst, int linesize);
void (*x8_setup_spatial_compensation)(uint8_t *src, uint8_t *dst, int linesize,
int * range, int * sum, int edges);
/* ape functions */
/**
* Add contents of the second vector to the first one.
* @param len length of vectors, should be multiple of 16
*/
void (*add_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len);
/**
* Add contents of the second vector to the first one.
* @param len length of vectors, should be multiple of 16
*/
void (*sub_int16)(int16_t *v1/*align 16*/, int16_t *v2, int len);
/**
* Calculate scalar product of two vectors.
* @param len length of vectors, should be multiple of 16
* @param shift number of bits to discard from product
*/
int32_t (*scalarproduct_int16)(int16_t *v1, int16_t *v2/*align 16*/, int len, int shift);
} DSPContext;
void dsputil_static_init(void);
void dsputil_init(DSPContext* p, AVCodecContext *avctx);
int ff_check_alignment(void);
/**
* permute block according to permuatation.
* @param last last non zero element in scantable order
@ -298,7 +493,7 @@ void ff_block_permute(DCTELEM *block, uint8_t *permutation, const uint8_t *scant
void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type);
#define BYTE_VEC32(c) ((c)*0x01010101UL)
#define BYTE_VEC32(c) ((c)*0x01010101UL)
static inline uint32_t rnd_avg32(uint32_t a, uint32_t b)
{
@ -310,6 +505,30 @@ static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
return (a & b) + (((a ^ b) & ~BYTE_VEC32(0x01)) >> 1);
}
static inline int get_penalty_factor(int lambda, int lambda2, int type){
switch(type&0xFF){
default:
case FF_CMP_SAD:
return lambda>>FF_LAMBDA_SHIFT;
case FF_CMP_DCT:
return (3*lambda)>>(FF_LAMBDA_SHIFT+1);
case FF_CMP_W53:
return (4*lambda)>>(FF_LAMBDA_SHIFT);
case FF_CMP_W97:
return (2*lambda)>>(FF_LAMBDA_SHIFT);
case FF_CMP_SATD:
case FF_CMP_DCT264:
return (2*lambda)>>FF_LAMBDA_SHIFT;
case FF_CMP_RD:
case FF_CMP_PSNR:
case FF_CMP_SSE:
case FF_CMP_NSSE:
return lambda2>>FF_LAMBDA_SHIFT;
case FF_CMP_BIT:
return 1;
}
}
/**
* Empty mmx state.
* this must be called between any dsp function and float/double code.
@ -321,6 +540,18 @@ static inline uint32_t no_rnd_avg32(uint32_t a, uint32_t b)
one or more MultiMedia extension */
int mm_support(void);
void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_bfin(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_vis(DSPContext* c, AVCodecContext *avctx);
#define DECLARE_ALIGNED_16(t, v) DECLARE_ALIGNED(16, t, v)
#if defined(HAVE_MMX)
#undef emms_c
@ -330,15 +561,19 @@ int mm_support(void);
#define MM_MMXEXT 0x0002 /* SSE integer functions or AMD MMX ext */
#define MM_SSE 0x0008 /* SSE functions */
#define MM_SSE2 0x0010 /* PIV SSE2 functions */
#define MM_3DNOWEXT 0x0020 /* AMD 3DNowExt */
#define MM_SSE3 0x0040 /* Prescott SSE3 functions */
#define MM_SSSE3 0x0080 /* Conroe SSSE3 functions */
extern int mm_flags;
void add_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
void put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
void put_signed_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels, int line_size);
static inline void emms(void)
{
__asm __volatile ("emms;":::"memory");
asm volatile ("emms;":::"memory");
}
@ -348,31 +583,18 @@ static inline void emms(void)
emms();\
}
#define __align8 __attribute__ ((aligned (8)))
void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx);
void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx);
#elif defined(ARCH_ARMV4L)
/* This is to use 4 bytes read to the IDCT pointers for some 'zero'
line ptimizations */
#define __align8 __attribute__ ((aligned (4)))
#define MM_IWMMXT 0x0100 /* XScale IWMMXT */
void dsputil_init_armv4l(DSPContext* c, AVCodecContext *avctx);
extern int mm_flags;
#elif defined(HAVE_MLIB)
/* SPARC/VIS IDCT needs 8-byte aligned DCT blocks */
#define __align8 __attribute__ ((aligned (8)))
void dsputil_init_mlib(DSPContext* c, AVCodecContext *avctx);
#elif defined(ARCH_ALPHA)
#define __align8 __attribute__ ((aligned (8)))
void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
#ifdef HAVE_NEON
# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v)
# define STRIDE_ALIGN 16
#endif
#elif defined(ARCH_POWERPC)
@ -380,55 +602,28 @@ void dsputil_init_alpha(DSPContext* c, AVCodecContext *avctx);
extern int mm_flags;
#if defined(HAVE_ALTIVEC) && !defined(CONFIG_DARWIN)
#define pixel altivec_pixel
#include <altivec.h>
#undef pixel
#endif
#define __align8 __attribute__ ((aligned (16)))
void dsputil_init_ppc(DSPContext* c, AVCodecContext *avctx);
#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v)
#define STRIDE_ALIGN 16
#elif defined(HAVE_MMI)
#define __align8 __attribute__ ((aligned (16)))
void dsputil_init_mmi(DSPContext* c, AVCodecContext *avctx);
#elif defined(ARCH_SH4)
#define __align8 __attribute__ ((aligned (8)))
void dsputil_init_sh4(DSPContext* c, AVCodecContext *avctx);
#define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(16, t, v)
#define STRIDE_ALIGN 16
#else
#define __align8
#define mm_flags 0
#define mm_support() 0
#endif
#ifdef __GNUC__
#ifndef DECLARE_ALIGNED_8
# define DECLARE_ALIGNED_8(t, v) DECLARE_ALIGNED(8, t, v)
#endif
struct unaligned_64 { uint64_t l; } __attribute__((packed));
struct unaligned_32 { uint32_t l; } __attribute__((packed));
struct unaligned_16 { uint16_t l; } __attribute__((packed));
#define LD16(a) (((const struct unaligned_16 *) (a))->l)
#define LD32(a) (((const struct unaligned_32 *) (a))->l)
#define LD64(a) (((const struct unaligned_64 *) (a))->l)
#define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b)
#else /* __GNUC__ */
#define LD16(a) (*((uint16_t*)(a)))
#define LD32(a) (*((uint32_t*)(a)))
#define LD64(a) (*((uint64_t*)(a)))
#define ST32(a, b) *((uint32_t*)(a)) = (b)
#endif /* !__GNUC__ */
#ifndef STRIDE_ALIGN
# define STRIDE_ALIGN 8
#endif
/* PSNR */
void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3],
@ -441,6 +636,8 @@ void get_psnr(uint8_t *orig_image[3], uint8_t *coded_image[3],
FFTSample type */
typedef float FFTSample;
struct MDCTContext;
typedef struct FFTComplex {
FFTSample re, im;
} FFTComplex;
@ -451,20 +648,31 @@ typedef struct FFTContext {
uint16_t *revtab;
FFTComplex *exptab;
FFTComplex *exptab1; /* only used by SSE code */
FFTComplex *tmp_buf;
void (*fft_permute)(struct FFTContext *s, FFTComplex *z);
void (*fft_calc)(struct FFTContext *s, FFTComplex *z);
void (*imdct_calc)(struct MDCTContext *s, FFTSample *output, const FFTSample *input);
void (*imdct_half)(struct MDCTContext *s, FFTSample *output, const FFTSample *input);
} FFTContext;
int fft_init(FFTContext *s, int nbits, int inverse);
void fft_permute(FFTContext *s, FFTComplex *z);
void fft_calc_c(FFTContext *s, FFTComplex *z);
void fft_calc_sse(FFTContext *s, FFTComplex *z);
void fft_calc_altivec(FFTContext *s, FFTComplex *z);
int ff_fft_init(FFTContext *s, int nbits, int inverse);
void ff_fft_permute_c(FFTContext *s, FFTComplex *z);
void ff_fft_permute_sse(FFTContext *s, FFTComplex *z);
void ff_fft_calc_c(FFTContext *s, FFTComplex *z);
void ff_fft_calc_sse(FFTContext *s, FFTComplex *z);
void ff_fft_calc_3dn(FFTContext *s, FFTComplex *z);
void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z);
void ff_fft_calc_altivec(FFTContext *s, FFTComplex *z);
static inline void fft_calc(FFTContext *s, FFTComplex *z)
static inline void ff_fft_permute(FFTContext *s, FFTComplex *z)
{
s->fft_permute(s, z);
}
static inline void ff_fft_calc(FFTContext *s, FFTComplex *z)
{
s->fft_calc(s, z);
}
void fft_end(FFTContext *s);
void ff_fft_end(FFTContext *s);
/* MDCT computation */
@ -477,20 +685,55 @@ typedef struct MDCTContext {
FFTContext fft;
} MDCTContext;
static inline void ff_imdct_calc(MDCTContext *s, FFTSample *output, const FFTSample *input)
{
s->fft.imdct_calc(s, output, input);
}
static inline void ff_imdct_half(MDCTContext *s, FFTSample *output, const FFTSample *input)
{
s->fft.imdct_half(s, output, input);
}
/**
* Generate a Kaiser-Bessel Derived Window.
* @param window pointer to half window
* @param alpha determines window shape
* @param n size of half window
*/
void ff_kbd_window_init(float *window, float alpha, int n);
/**
* Generate a sine window.
* @param window pointer to half window
* @param n size of half window
*/
void ff_sine_window_init(float *window, int n);
extern float ff_sine_128 [ 128];
extern float ff_sine_256 [ 256];
extern float ff_sine_512 [ 512];
extern float ff_sine_1024[1024];
extern float ff_sine_2048[2048];
extern float *ff_sine_windows[5];
int ff_mdct_init(MDCTContext *s, int nbits, int inverse);
void ff_imdct_calc(MDCTContext *s, FFTSample *output,
const FFTSample *input, FFTSample *tmp);
void ff_mdct_calc(MDCTContext *s, FFTSample *out,
const FFTSample *input, FFTSample *tmp);
void ff_imdct_calc_c(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_c(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_calc_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_3dn(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_calc_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_3dn2(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_calc_sse(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_imdct_half_sse(MDCTContext *s, FFTSample *output, const FFTSample *input);
void ff_mdct_calc(MDCTContext *s, FFTSample *out, const FFTSample *input);
void ff_mdct_end(MDCTContext *s);
#define WARPER8_16(name8, name16)\
#define WRAPPER8_16(name8, name16)\
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
return name8(s, dst , src , stride, h)\
+name8(s, dst+8 , src+8 , stride, h);\
}
#define WARPER8_16_SQ(name8, name16)\
#define WRAPPER8_16_SQ(name8, name16)\
static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int stride, int h){\
int score=0;\
score +=name8(s, dst , src , stride, 8);\
@ -504,19 +747,81 @@ static int name16(void /*MpegEncContext*/ *s, uint8_t *dst, uint8_t *src, int st
return score;\
}
#ifndef HAVE_LRINTF
/* XXX: add ISOC specific test to avoid specific BSD testing. */
/* better than nothing implementation. */
/* btw, rintf() is existing on fbsd too -- alex */
static inline long int lrintf(float x)
{
#ifdef CONFIG_WIN32
/* XXX: incorrect, but make it compile */
return (int)(x);
#else
return (int)(rint(x));
#endif
}
#endif
#endif
static inline void copy_block2(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN16(dst , AV_RN16(src ));
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block4(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN32(dst , AV_RN32(src ));
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block8(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN32(dst , AV_RN32(src ));
AV_WN32(dst+4 , AV_RN32(src+4 ));
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block9(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN32(dst , AV_RN32(src ));
AV_WN32(dst+4 , AV_RN32(src+4 ));
dst[8]= src[8];
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block16(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN32(dst , AV_RN32(src ));
AV_WN32(dst+4 , AV_RN32(src+4 ));
AV_WN32(dst+8 , AV_RN32(src+8 ));
AV_WN32(dst+12, AV_RN32(src+12));
dst+=dstStride;
src+=srcStride;
}
}
static inline void copy_block17(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
{
int i;
for(i=0; i<h; i++)
{
AV_WN32(dst , AV_RN32(src ));
AV_WN32(dst+4 , AV_RN32(src+4 ));
AV_WN32(dst+8 , AV_RN32(src+8 ));
AV_WN32(dst+12, AV_RN32(src+12));
dst[16]= src[16];
dst+=dstStride;
src+=srcStride;
}
}
#endif /* FFMPEG_DSPUTIL_H */

View File

@ -0,0 +1,50 @@
/*
* 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 int dump_extradata(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size, int keyframe){
int cmd= args ? *args : 0;
/* cast to avoid warning about discarding qualifiers */
if(avctx->extradata){
if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER) && cmd=='a')
||(keyframe && (cmd=='k' || !cmd))
||(cmd=='e')
/*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
int size= buf_size + avctx->extradata_size;
*poutbuf_size= size;
*poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
return 1;
}
}
return 0;
}
AVBitStreamFilter dump_extradata_bsf={
"dump_extra",
0,
dump_extradata,
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,412 @@
/*
* DVB subtitle encoding for ffmpeg
* Copyright (c) 2005 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"
#include "bytestream.h"
#include "colorspace.h"
typedef struct DVBSubtitleContext {
int hide_state;
int object_version;
} DVBSubtitleContext;
#define PUTBITS2(val)\
{\
bitbuf |= (val) << bitcnt;\
bitcnt -= 2;\
if (bitcnt < 0) {\
bitcnt = 6;\
*q++ = bitbuf;\
bitbuf = 0;\
}\
}
static void dvb_encode_rle2(uint8_t **pq,
const uint8_t *bitmap, int linesize,
int w, int h)
{
uint8_t *q;
unsigned int bitbuf;
int bitcnt;
int x, y, len, x1, v, color;
q = *pq;
for(y = 0; y < h; y++) {
*q++ = 0x10;
bitbuf = 0;
bitcnt = 6;
x = 0;
while (x < w) {
x1 = x;
color = bitmap[x1++];
while (x1 < w && bitmap[x1] == color)
x1++;
len = x1 - x;
if (color == 0 && len == 2) {
PUTBITS2(0);
PUTBITS2(0);
PUTBITS2(1);
} else if (len >= 3 && len <= 10) {
v = len - 3;
PUTBITS2(0);
PUTBITS2((v >> 2) | 2);
PUTBITS2(v & 3);
PUTBITS2(color);
} else if (len >= 12 && len <= 27) {
v = len - 12;
PUTBITS2(0);
PUTBITS2(0);
PUTBITS2(2);
PUTBITS2(v >> 2);
PUTBITS2(v & 3);
PUTBITS2(color);
} else if (len >= 29) {
/* length = 29 ... 284 */
if (len > 284)
len = 284;
v = len - 29;
PUTBITS2(0);
PUTBITS2(0);
PUTBITS2(3);
PUTBITS2((v >> 6));
PUTBITS2((v >> 4) & 3);
PUTBITS2((v >> 2) & 3);
PUTBITS2(v & 3);
PUTBITS2(color);
} else {
PUTBITS2(color);
if (color == 0) {
PUTBITS2(1);
}
len = 1;
}
x += len;
}
/* end of line */
PUTBITS2(0);
PUTBITS2(0);
PUTBITS2(0);
if (bitcnt != 6) {
*q++ = bitbuf;
}
*q++ = 0xf0;
bitmap += linesize;
}
*pq = q;
}
#define PUTBITS4(val)\
{\
bitbuf |= (val) << bitcnt;\
bitcnt -= 4;\
if (bitcnt < 0) {\
bitcnt = 4;\
*q++ = bitbuf;\
bitbuf = 0;\
}\
}
/* some DVB decoders only implement 4 bits/pixel */
static void dvb_encode_rle4(uint8_t **pq,
const uint8_t *bitmap, int linesize,
int w, int h)
{
uint8_t *q;
unsigned int bitbuf;
int bitcnt;
int x, y, len, x1, v, color;
q = *pq;
for(y = 0; y < h; y++) {
*q++ = 0x11;
bitbuf = 0;
bitcnt = 4;
x = 0;
while (x < w) {
x1 = x;
color = bitmap[x1++];
while (x1 < w && bitmap[x1] == color)
x1++;
len = x1 - x;
if (color == 0 && len == 2) {
PUTBITS4(0);
PUTBITS4(0xd);
} else if (color == 0 && (len >= 3 && len <= 9)) {
PUTBITS4(0);
PUTBITS4(len - 2);
} else if (len >= 4 && len <= 7) {
PUTBITS4(0);
PUTBITS4(8 + len - 4);
PUTBITS4(color);
} else if (len >= 9 && len <= 24) {
PUTBITS4(0);
PUTBITS4(0xe);
PUTBITS4(len - 9);
PUTBITS4(color);
} else if (len >= 25) {
if (len > 280)
len = 280;
v = len - 25;
PUTBITS4(0);
PUTBITS4(0xf);
PUTBITS4(v >> 4);
PUTBITS4(v & 0xf);
PUTBITS4(color);
} else {
PUTBITS4(color);
if (color == 0) {
PUTBITS4(0xc);
}
len = 1;
}
x += len;
}
/* end of line */
PUTBITS4(0);
PUTBITS4(0);
if (bitcnt != 4) {
*q++ = bitbuf;
}
*q++ = 0xf0;
bitmap += linesize;
}
*pq = q;
}
static int encode_dvb_subtitles(DVBSubtitleContext *s,
uint8_t *outbuf, AVSubtitle *h)
{
uint8_t *q, *pseg_len;
int page_id, region_id, clut_id, object_id, i, bpp_index, page_state;
q = outbuf;
page_id = 1;
if (h->num_rects == 0 || h->rects == NULL)
return -1;
*q++ = 0x00; /* subtitle_stream_id */
/* page composition segment */
*q++ = 0x0f; /* sync_byte */
*q++ = 0x10; /* segment_type */
bytestream_put_be16(&q, page_id);
pseg_len = q;
q += 2; /* segment length */
*q++ = 30; /* page_timeout (seconds) */
if (s->hide_state)
page_state = 0; /* normal case */
else
page_state = 2; /* mode change */
/* page_version = 0 + page_state */
*q++ = s->object_version | (page_state << 2) | 3;
for (region_id = 0; region_id < h->num_rects; region_id++) {
*q++ = region_id;
*q++ = 0xff; /* reserved */
bytestream_put_be16(&q, h->rects[region_id].x); /* left pos */
bytestream_put_be16(&q, h->rects[region_id].y); /* top pos */
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
if (!s->hide_state) {
for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
/* CLUT segment */
if (h->rects[clut_id].nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[clut_id].nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
return -1;
}
*q++ = 0x0f; /* sync byte */
*q++ = 0x12; /* CLUT definition segment */
bytestream_put_be16(&q, page_id);
pseg_len = q;
q += 2; /* segment length */
*q++ = clut_id;
*q++ = (0 << 4) | 0xf; /* version = 0 */
for(i = 0; i < h->rects[clut_id].nb_colors; i++) {
*q++ = i; /* clut_entry_id */
*q++ = (1 << (7 - bpp_index)) | (0xf << 1) | 1; /* 2 bits/pixel full range */
{
int a, r, g, b;
a = (h->rects[clut_id].rgba_palette[i] >> 24) & 0xff;
r = (h->rects[clut_id].rgba_palette[i] >> 16) & 0xff;
g = (h->rects[clut_id].rgba_palette[i] >> 8) & 0xff;
b = (h->rects[clut_id].rgba_palette[i] >> 0) & 0xff;
*q++ = RGB_TO_Y_CCIR(r, g, b);
*q++ = RGB_TO_V_CCIR(r, g, b, 0);
*q++ = RGB_TO_U_CCIR(r, g, b, 0);
*q++ = 255 - a;
}
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
}
}
for (region_id = 0; region_id < h->num_rects; region_id++) {
/* region composition segment */
if (h->rects[region_id].nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[region_id].nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
return -1;
}
*q++ = 0x0f; /* sync_byte */
*q++ = 0x11; /* segment_type */
bytestream_put_be16(&q, page_id);
pseg_len = q;
q += 2; /* segment length */
*q++ = region_id;
*q++ = (s->object_version << 4) | (0 << 3) | 0x07; /* version , no fill */
bytestream_put_be16(&q, h->rects[region_id].w); /* region width */
bytestream_put_be16(&q, h->rects[region_id].h); /* region height */
*q++ = ((1 + bpp_index) << 5) | ((1 + bpp_index) << 2) | 0x03;
*q++ = region_id; /* clut_id == region_id */
*q++ = 0; /* 8 bit fill colors */
*q++ = 0x03; /* 4 bit and 2 bit fill colors */
if (!s->hide_state) {
bytestream_put_be16(&q, region_id); /* object_id == region_id */
*q++ = (0 << 6) | (0 << 4);
*q++ = 0;
*q++ = 0xf0;
*q++ = 0;
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
}
if (!s->hide_state) {
for (object_id = 0; object_id < h->num_rects; object_id++) {
/* Object Data segment */
if (h->rects[object_id].nb_colors <= 4) {
/* 2 bpp, some decoders do not support it correctly */
bpp_index = 0;
} else if (h->rects[object_id].nb_colors <= 16) {
/* 4 bpp, standard encoding */
bpp_index = 1;
} else {
return -1;
}
*q++ = 0x0f; /* sync byte */
*q++ = 0x13;
bytestream_put_be16(&q, page_id);
pseg_len = q;
q += 2; /* segment length */
bytestream_put_be16(&q, object_id);
*q++ = (s->object_version << 4) | (0 << 2) | (0 << 1) | 1; /* version = 0,
onject_coding_method,
non_modifying_color_flag */
{
uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
void (*dvb_encode_rle)(uint8_t **pq,
const uint8_t *bitmap, int linesize,
int w, int h);
ptop_field_len = q;
q += 2;
pbottom_field_len = q;
q += 2;
if (bpp_index == 0)
dvb_encode_rle = dvb_encode_rle2;
else
dvb_encode_rle = dvb_encode_rle4;
top_ptr = q;
dvb_encode_rle(&q, h->rects[object_id].bitmap, h->rects[object_id].w * 2,
h->rects[object_id].w, h->rects[object_id].h >> 1);
bottom_ptr = q;
dvb_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
h->rects[object_id].w * 2, h->rects[object_id].w,
h->rects[object_id].h >> 1);
bytestream_put_be16(&ptop_field_len, bottom_ptr - top_ptr);
bytestream_put_be16(&pbottom_field_len, q - bottom_ptr);
}
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
}
}
/* end of display set segment */
*q++ = 0x0f; /* sync_byte */
*q++ = 0x80; /* segment_type */
bytestream_put_be16(&q, page_id);
pseg_len = q;
q += 2; /* segment length */
bytestream_put_be16(&pseg_len, q - pseg_len - 2);
*q++ = 0xff; /* end of PES data */
s->object_version = (s->object_version + 1) & 0xf;
s->hide_state = !s->hide_state;
return q - outbuf;
}
static int dvbsub_encode(AVCodecContext *avctx,
unsigned char *buf, int buf_size, void *data)
{
DVBSubtitleContext *s = avctx->priv_data;
AVSubtitle *sub = data;
int ret;
ret = encode_dvb_subtitles(s, buf, sub);
return ret;
}
AVCodec dvbsub_encoder = {
"dvbsub",
CODEC_TYPE_SUBTITLE,
CODEC_ID_DVB_SUBTITLE,
sizeof(DVBSubtitleContext),
NULL,
dvbsub_encode,
.long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
};

View File

@ -0,0 +1,196 @@
/*
* DVB subtitle parser for FFmpeg
* Copyright (c) 2005 Ian Caulfield.
*
* 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 "bitstream.h"
//#define DEBUG
//#define DEBUG_PACKET_CONTENTS
/* Parser (mostly) copied from dvdsub.c */
#define PARSE_BUF_SIZE (65536)
/* parser definition */
typedef struct DVBSubParseContext {
uint8_t *packet_buf;
int packet_start;
int packet_index;
int in_packet;
} DVBSubParseContext;
static av_cold int dvbsub_parse_init(AVCodecParserContext *s)
{
DVBSubParseContext *pc = s->priv_data;
pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
return 0;
}
static int dvbsub_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
DVBSubParseContext *pc = s->priv_data;
uint8_t *p, *p_end;
int len, buf_pos = 0;
#ifdef DEBUG
av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n",
s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);
#endif
#ifdef DEBUG_PACKET_CONTENTS
int i;
for (i=0; i < buf_size; i++)
{
av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
if (i % 16 == 15)
av_log(avctx, AV_LOG_INFO, "\n");
}
if (i % 16 != 0)
av_log(avctx, AV_LOG_INFO, "\n");
#endif
*poutbuf = NULL;
*poutbuf_size = 0;
s->fetch_timestamp = 1;
if (s->last_pts != s->pts && s->pts != AV_NOPTS_VALUE) /* Start of a new packet */
{
if (pc->packet_index != pc->packet_start)
{
#ifdef DEBUG
av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n",
pc->packet_index - pc->packet_start);
#endif
}
pc->packet_start = 0;
pc->packet_index = 0;
if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {
#ifdef DEBUG
av_log(avctx, AV_LOG_INFO, "Bad packet header\n");
#endif
return -1;
}
buf_pos = 2;
pc->in_packet = 1;
} else {
if (pc->packet_start != 0)
{
if (pc->packet_index != pc->packet_start)
{
memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,
pc->packet_index - pc->packet_start);
pc->packet_index -= pc->packet_start;
pc->packet_start = 0;
} else {
pc->packet_start = 0;
pc->packet_index = 0;
}
}
}
if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)
return -1;
/* if not currently in a packet, discard data */
if (pc->in_packet == 0)
return buf_size;
memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);
pc->packet_index += buf_size - buf_pos;
p = pc->packet_buf;
p_end = pc->packet_buf + pc->packet_index;
while (p < p_end)
{
if (*p == 0x0f)
{
if (p + 6 <= p_end)
{
len = AV_RB16(p + 4);
if (p + len + 6 <= p_end)
{
*poutbuf_size += len + 6;
p += len + 6;
} else
break;
} else
break;
} else if (*p == 0xff) {
if (p + 1 < p_end)
{
#ifdef DEBUG
av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
#endif
}
pc->packet_index = p - pc->packet_buf;
pc->in_packet = 0;
break;
} else {
av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");
pc->packet_index = p - pc->packet_buf;
pc->in_packet = 0;
break;
}
}
if (*poutbuf_size > 0)
{
*poutbuf = pc->packet_buf;
pc->packet_start = *poutbuf_size;
}
if (s->pts == AV_NOPTS_VALUE)
s->pts = s->last_pts;
return buf_size;
}
static av_cold void dvbsub_parse_close(AVCodecParserContext *s)
{
DVBSubParseContext *pc = s->priv_data;
av_freep(&pc->packet_buf);
}
AVCodecParser dvbsub_parser = {
{ CODEC_ID_DVB_SUBTITLE },
sizeof(DVBSubParseContext),
dvbsub_parse_init,
dvbsub_parse,
dvbsub_parse_close,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,83 @@
/*
* DVD subtitle decoding for ffmpeg
* Copyright (c) 2005 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"
/* parser definition */
typedef struct DVDSubParseContext {
uint8_t *packet;
int packet_len;
int packet_index;
} DVDSubParseContext;
static int dvdsub_parse_init(AVCodecParserContext *s)
{
return 0;
}
static int dvdsub_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
DVDSubParseContext *pc = s->priv_data;
if (pc->packet_index == 0) {
if (buf_size < 2)
return 0;
pc->packet_len = AV_RB16(buf);
if (pc->packet_len == 0) /* HD-DVD subpicture packet */
pc->packet_len = AV_RB32(buf+2);
av_freep(&pc->packet);
pc->packet = av_malloc(pc->packet_len);
}
if (pc->packet) {
if (pc->packet_index + buf_size <= pc->packet_len) {
memcpy(pc->packet + pc->packet_index, buf, buf_size);
pc->packet_index += buf_size;
if (pc->packet_index >= pc->packet_len) {
*poutbuf = pc->packet;
*poutbuf_size = pc->packet_len;
pc->packet_index = 0;
return buf_size;
}
} else {
/* erroneous size */
pc->packet_index = 0;
}
}
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
static void dvdsub_parse_close(AVCodecParserContext *s)
{
DVDSubParseContext *pc = s->priv_data;
av_freep(&pc->packet);
}
AVCodecParser dvdsub_parser = {
{ CODEC_ID_DVD_SUBTITLE },
sizeof(DVDSubParseContext),
dvdsub_parse_init,
dvdsub_parse,
dvdsub_parse_close,
};

View File

@ -0,0 +1,512 @@
/*
* DVD subtitle decoding for ffmpeg
* Copyright (c) 2005 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"
#include "bitstream.h"
#include "colorspace.h"
#include "dsputil.h"
//#define DEBUG
static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
{
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
uint8_t r, g, b;
int i, y, cb, cr;
int r_add, g_add, b_add;
for (i = num_values; i > 0; i--) {
y = *ycbcr++;
cb = *ycbcr++;
cr = *ycbcr++;
YUV_TO_RGB1_CCIR(cb, cr);
YUV_TO_RGB2_CCIR(r, g, b, y);
*rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b;
}
}
static int decode_run_2bit(GetBitContext *gb, int *color)
{
unsigned int v, t;
v = 0;
for (t = 1; v < t && t <= 0x40; t <<= 2)
v = (v << 4) | get_bits(gb, 4);
*color = v & 3;
if (v < 4) { /* Code for fill rest of line */
return INT_MAX;
}
return v >> 2;
}
static int decode_run_8bit(GetBitContext *gb, int *color)
{
int len;
int has_run = get_bits1(gb);
if (get_bits1(gb))
*color = get_bits(gb, 8);
else
*color = get_bits(gb, 2);
if (has_run) {
if (get_bits1(gb)) {
len = get_bits(gb, 7);
if (len == 0)
len = INT_MAX;
else
len += 9;
} else
len = get_bits(gb, 3) + 2;
} else
len = 1;
return len;
}
static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
const uint8_t *buf, int start, int buf_size, int is_8bit)
{
GetBitContext gb;
int bit_len;
int x, y, len, color;
uint8_t *d;
bit_len = (buf_size - start) * 8;
init_get_bits(&gb, buf + start, bit_len);
x = 0;
y = 0;
d = bitmap;
for(;;) {
if (get_bits_count(&gb) > bit_len)
return -1;
if (is_8bit)
len = decode_run_8bit(&gb, &color);
else
len = decode_run_2bit(&gb, &color);
len = FFMIN(len, w - x);
memset(d + x, color, len);
x += len;
if (x >= w) {
y++;
if (y >= h)
break;
d += linesize;
x = 0;
/* byte align */
align_get_bits(&gb);
}
}
return 0;
}
static void guess_palette(uint32_t *rgba_palette,
uint8_t *colormap,
uint8_t *alpha,
uint32_t subtitle_color)
{
uint8_t color_used[16];
int nb_opaque_colors, i, level, j, r, g, b;
for(i = 0; i < 4; i++)
rgba_palette[i] = 0;
memset(color_used, 0, 16);
nb_opaque_colors = 0;
for(i = 0; i < 4; i++) {
if (alpha[i] != 0 && !color_used[colormap[i]]) {
color_used[colormap[i]] = 1;
nb_opaque_colors++;
}
}
if (nb_opaque_colors == 0)
return;
j = nb_opaque_colors;
memset(color_used, 0, 16);
for(i = 0; i < 4; i++) {
if (alpha[i] != 0) {
if (!color_used[colormap[i]]) {
level = (0xff * j) / nb_opaque_colors;
r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);
color_used[colormap[i]] = (i + 1);
j--;
} else {
rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
((alpha[i] * 17) << 24);
}
}
}
}
#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
static int decode_dvd_subtitles(AVSubtitle *sub_header,
const uint8_t *buf, int buf_size)
{
int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
int big_offsets, offset_size, is_8bit = 0;
const uint8_t *yuv_palette = 0;
uint8_t colormap[4], alpha[256];
int date;
int i;
int is_menu = 0;
if (buf_size < 10)
return -1;
sub_header->rects = NULL;
sub_header->num_rects = 0;
sub_header->start_display_time = 0;
sub_header->end_display_time = 0;
if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */
big_offsets = 1;
offset_size = 4;
cmd_pos = 6;
} else {
big_offsets = 0;
offset_size = 2;
cmd_pos = 2;
}
cmd_pos = READ_OFFSET(buf + cmd_pos);
while ((cmd_pos + 2 + offset_size) < buf_size) {
date = AV_RB16(buf + cmd_pos);
next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "cmd_pos=0x%04x next=0x%04x date=%d\n",
cmd_pos, next_cmd_pos, date);
#endif
pos = cmd_pos + 2 + offset_size;
offset1 = -1;
offset2 = -1;
x1 = y1 = x2 = y2 = 0;
while (pos < buf_size) {
cmd = buf[pos++];
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "cmd=%02x\n", cmd);
#endif
switch(cmd) {
case 0x00:
/* menu subpicture */
is_menu = 1;
break;
case 0x01:
/* set start date */
sub_header->start_display_time = (date << 10) / 90;
break;
case 0x02:
/* set end date */
sub_header->end_display_time = (date << 10) / 90;
break;
case 0x03:
/* set colormap */
if ((buf_size - pos) < 2)
goto fail;
colormap[3] = buf[pos] >> 4;
colormap[2] = buf[pos] & 0x0f;
colormap[1] = buf[pos + 1] >> 4;
colormap[0] = buf[pos + 1] & 0x0f;
pos += 2;
break;
case 0x04:
/* set alpha */
if ((buf_size - pos) < 2)
goto fail;
alpha[3] = buf[pos] >> 4;
alpha[2] = buf[pos] & 0x0f;
alpha[1] = buf[pos + 1] >> 4;
alpha[0] = buf[pos + 1] & 0x0f;
pos += 2;
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
#endif
break;
case 0x05:
case 0x85:
if ((buf_size - pos) < 6)
goto fail;
x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);
x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];
y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);
y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];
if (cmd & 0x80)
is_8bit = 1;
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "x1=%d x2=%d y1=%d y2=%d\n",
x1, x2, y1, y2);
#endif
pos += 6;
break;
case 0x06:
if ((buf_size - pos) < 4)
goto fail;
offset1 = AV_RB16(buf + pos);
offset2 = AV_RB16(buf + pos + 2);
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
#endif
pos += 4;
break;
case 0x86:
if ((buf_size - pos) < 8)
goto fail;
offset1 = AV_RB32(buf + pos);
offset2 = AV_RB32(buf + pos + 4);
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
#endif
pos += 8;
break;
case 0x83:
/* HD set palette */
if ((buf_size - pos) < 768)
goto fail;
yuv_palette = buf + pos;
pos += 768;
break;
case 0x84:
/* HD set contrast (alpha) */
if ((buf_size - pos) < 256)
goto fail;
for (i = 0; i < 256; i++)
alpha[i] = 0xFF - buf[pos+i];
pos += 256;
break;
case 0xff:
goto the_end;
default:
#ifdef DEBUG
av_log(NULL, AV_LOG_INFO, "unrecognised subpicture command 0x%x\n", cmd);
#endif
goto the_end;
}
}
the_end:
if (offset1 >= 0) {
int w, h;
uint8_t *bitmap;
/* decode the bitmap */
w = x2 - x1 + 1;
if (w < 0)
w = 0;
h = y2 - y1;
if (h < 0)
h = 0;
if (w > 0 && h > 0) {
if (sub_header->rects != NULL) {
for (i = 0; i < sub_header->num_rects; i++) {
av_free(sub_header->rects[i].bitmap);
av_free(sub_header->rects[i].rgba_palette);
}
av_freep(&sub_header->rects);
sub_header->num_rects = 0;
}
bitmap = av_malloc(w * h);
sub_header->rects = av_mallocz(sizeof(AVSubtitleRect));
sub_header->num_rects = 1;
sub_header->rects[0].bitmap = bitmap;
decode_rle(bitmap, w * 2, w, (h + 1) / 2,
buf, offset1, buf_size, is_8bit);
decode_rle(bitmap + w, w * 2, w, h / 2,
buf, offset2, buf_size, is_8bit);
if (is_8bit) {
if (yuv_palette == 0)
goto fail;
sub_header->rects[0].rgba_palette = av_malloc(256 * 4);
sub_header->rects[0].nb_colors = 256;
yuv_a_to_rgba(yuv_palette, alpha, sub_header->rects[0].rgba_palette, 256);
} else {
sub_header->rects[0].rgba_palette = av_malloc(4 * 4);
sub_header->rects[0].nb_colors = 4;
guess_palette(sub_header->rects[0].rgba_palette,
colormap, alpha, 0xffff00);
}
sub_header->rects[0].x = x1;
sub_header->rects[0].y = y1;
sub_header->rects[0].w = w;
sub_header->rects[0].h = h;
sub_header->rects[0].linesize = w;
}
}
if (next_cmd_pos == cmd_pos)
break;
cmd_pos = next_cmd_pos;
}
if (sub_header->num_rects > 0)
return is_menu;
fail:
if (sub_header->rects != NULL) {
for (i = 0; i < sub_header->num_rects; i++) {
av_free(sub_header->rects[i].bitmap);
av_free(sub_header->rects[i].rgba_palette);
}
av_freep(&sub_header->rects);
sub_header->num_rects = 0;
}
return -1;
}
static int is_transp(const uint8_t *buf, int pitch, int n,
const uint8_t *transp_color)
{
int i;
for(i = 0; i < n; i++) {
if (!transp_color[*buf])
return 0;
buf += pitch;
}
return 1;
}
/* return 0 if empty rectangle, 1 if non empty */
static int find_smallest_bounding_rectangle(AVSubtitle *s)
{
uint8_t transp_color[256];
int y1, y2, x1, x2, y, w, h, i;
uint8_t *bitmap;
if (s->num_rects == 0 || s->rects == NULL || s->rects[0].w <= 0 || s->rects[0].h <= 0)
return 0;
memset(transp_color, 0, 256);
for(i = 0; i < s->rects[0].nb_colors; i++) {
if ((s->rects[0].rgba_palette[i] >> 24) == 0)
transp_color[i] = 1;
}
y1 = 0;
while (y1 < s->rects[0].h && is_transp(s->rects[0].bitmap + y1 * s->rects[0].linesize,
1, s->rects[0].w, transp_color))
y1++;
if (y1 == s->rects[0].h) {
av_freep(&s->rects[0].bitmap);
s->rects[0].w = s->rects[0].h = 0;
return 0;
}
y2 = s->rects[0].h - 1;
while (y2 > 0 && is_transp(s->rects[0].bitmap + y2 * s->rects[0].linesize, 1,
s->rects[0].w, transp_color))
y2--;
x1 = 0;
while (x1 < (s->rects[0].w - 1) && is_transp(s->rects[0].bitmap + x1, s->rects[0].linesize,
s->rects[0].h, transp_color))
x1++;
x2 = s->rects[0].w - 1;
while (x2 > 0 && is_transp(s->rects[0].bitmap + x2, s->rects[0].linesize, s->rects[0].h,
transp_color))
x2--;
w = x2 - x1 + 1;
h = y2 - y1 + 1;
bitmap = av_malloc(w * h);
if (!bitmap)
return 1;
for(y = 0; y < h; y++) {
memcpy(bitmap + w * y, s->rects[0].bitmap + x1 + (y1 + y) * s->rects[0].linesize, w);
}
av_freep(&s->rects[0].bitmap);
s->rects[0].bitmap = bitmap;
s->rects[0].linesize = w;
s->rects[0].w = w;
s->rects[0].h = h;
s->rects[0].x += x1;
s->rects[0].y += y1;
return 1;
}
#ifdef DEBUG
#undef fprintf
#undef perror
#undef exit
static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
uint32_t *rgba_palette)
{
int x, y, v;
FILE *f;
f = fopen(filename, "w");
if (!f) {
perror(filename);
exit(1);
}
fprintf(f, "P6\n"
"%d %d\n"
"%d\n",
w, h, 255);
for(y = 0; y < h; y++) {
for(x = 0; x < w; x++) {
v = rgba_palette[bitmap[y * w + x]];
putc((v >> 16) & 0xff, f);
putc((v >> 8) & 0xff, f);
putc((v >> 0) & 0xff, f);
}
}
fclose(f);
}
#endif
static int dvdsub_decode(AVCodecContext *avctx,
void *data, int *data_size,
const uint8_t *buf, int buf_size)
{
AVSubtitle *sub = (void *)data;
int is_menu;
is_menu = decode_dvd_subtitles(sub, buf, buf_size);
if (is_menu < 0) {
no_subtitle:
*data_size = 0;
return buf_size;
}
if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
goto no_subtitle;
#if defined(DEBUG)
av_log(NULL, AV_LOG_INFO, "start=%d ms end =%d ms\n",
sub->start_display_time,
sub->end_display_time);
ppm_save("/tmp/a.ppm", sub->rects[0].bitmap,
sub->rects[0].w, sub->rects[0].h, sub->rects[0].rgba_palette);
#endif
*data_size = 1;
return buf_size;
}
AVCodec dvdsub_decoder = {
"dvdsub",
CODEC_TYPE_SUBTITLE,
CODEC_ID_DVD_SUBTITLE,
0,
NULL,
NULL,
NULL,
dvdsub_decode,
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
};

View File

@ -0,0 +1,226 @@
/*
* DVD subtitle encoding for ffmpeg
* Copyright (c) 2005 Wolfram Gloger.
*
* 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"
#undef NDEBUG
#include <assert.h>
// ncnt is the nibble counter
#define PUTNIBBLE(val)\
do {\
if (ncnt++ & 1)\
*q++ = bitbuf | ((val) & 0x0f);\
else\
bitbuf = (val) << 4;\
} while(0)
static void dvd_encode_rle(uint8_t **pq,
const uint8_t *bitmap, int linesize,
int w, int h,
const int cmap[256])
{
uint8_t *q;
unsigned int bitbuf = 0;
int ncnt;
int x, y, len, color;
q = *pq;
for (y = 0; y < h; ++y) {
ncnt = 0;
for(x = 0; x < w; x += len) {
color = bitmap[x];
for (len=1; x+len < w; ++len)
if (bitmap[x+len] != color)
break;
color = cmap[color];
assert(color < 4);
if (len < 0x04) {
PUTNIBBLE((len << 2)|color);
} else if (len < 0x10) {
PUTNIBBLE(len >> 2);
PUTNIBBLE((len << 2)|color);
} else if (len < 0x40) {
PUTNIBBLE(0);
PUTNIBBLE(len >> 2);
PUTNIBBLE((len << 2)|color);
} else if (x+len == w) {
PUTNIBBLE(0);
PUTNIBBLE(0);
PUTNIBBLE(0);
PUTNIBBLE(color);
} else {
if (len > 0xff)
len = 0xff;
PUTNIBBLE(0);
PUTNIBBLE(len >> 6);
PUTNIBBLE(len >> 2);
PUTNIBBLE((len << 2)|color);
}
}
/* end of line */
if (ncnt & 1)
PUTNIBBLE(0);
bitmap += linesize;
}
*pq = q;
}
static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
const AVSubtitle *h)
{
uint8_t *q, *qq;
int object_id;
int offset1[20], offset2[20];
int i, imax, color, alpha, rects = h->num_rects;
unsigned long hmax;
unsigned long hist[256];
int cmap[256];
if (rects == 0 || h->rects == NULL)
return -1;
if (rects > 20)
rects = 20;
// analyze bitmaps, compress to 4 colors
for (i=0; i<256; ++i) {
hist[i] = 0;
cmap[i] = 0;
}
for (object_id = 0; object_id < rects; object_id++)
for (i=0; i<h->rects[object_id].w*h->rects[object_id].h; ++i) {
color = h->rects[object_id].bitmap[i];
// only count non-transparent pixels
alpha = h->rects[object_id].rgba_palette[color] >> 24;
hist[color] += alpha;
}
for (color=3;; --color) {
hmax = 0;
imax = 0;
for (i=0; i<256; ++i)
if (hist[i] > hmax) {
imax = i;
hmax = hist[i];
}
if (hmax == 0)
break;
if (color == 0)
color = 3;
av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n",
imax, hist[imax], color);
cmap[imax] = color;
hist[imax] = 0;
}
// encode data block
q = outbuf + 4;
for (object_id = 0; object_id < rects; object_id++) {
offset1[object_id] = q - outbuf;
// worst case memory requirement: 1 nibble per pixel..
if ((q - outbuf) + h->rects[object_id].w*h->rects[object_id].h/2
+ 17*rects + 21 > outbuf_size) {
av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
return -1;
}
dvd_encode_rle(&q, h->rects[object_id].bitmap,
h->rects[object_id].w*2,
h->rects[object_id].w, h->rects[object_id].h >> 1,
cmap);
offset2[object_id] = q - outbuf;
dvd_encode_rle(&q, h->rects[object_id].bitmap + h->rects[object_id].w,
h->rects[object_id].w*2,
h->rects[object_id].w, h->rects[object_id].h >> 1,
cmap);
}
// set data packet size
qq = outbuf + 2;
bytestream_put_be16(&qq, q - outbuf);
// send start display command
bytestream_put_be16(&q, (h->start_display_time*90) >> 10);
bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2);
*q++ = 0x03; // palette - 4 nibbles
*q++ = 0x03; *q++ = 0x7f;
*q++ = 0x04; // alpha - 4 nibbles
*q++ = 0xf0; *q++ = 0x00;
//*q++ = 0x0f; *q++ = 0xff;
// XXX not sure if more than one rect can really be encoded..
// 12 bytes per rect
for (object_id = 0; object_id < rects; object_id++) {
int x2 = h->rects[object_id].x + h->rects[object_id].w - 1;
int y2 = h->rects[object_id].y + h->rects[object_id].h - 1;
*q++ = 0x05;
// x1 x2 -> 6 nibbles
*q++ = h->rects[object_id].x >> 4;
*q++ = (h->rects[object_id].x << 4) | ((x2 >> 8) & 0xf);
*q++ = x2;
// y1 y2 -> 6 nibbles
*q++ = h->rects[object_id].y >> 4;
*q++ = (h->rects[object_id].y << 4) | ((y2 >> 8) & 0xf);
*q++ = y2;
*q++ = 0x06;
// offset1, offset2
bytestream_put_be16(&q, offset1[object_id]);
bytestream_put_be16(&q, offset2[object_id]);
}
*q++ = 0x01; // start command
*q++ = 0xff; // terminating command
// send stop display command last
bytestream_put_be16(&q, (h->end_display_time*90) >> 10);
bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);
*q++ = 0x02; // set end
*q++ = 0xff; // terminating command
qq = outbuf;
bytestream_put_be16(&qq, q - outbuf);
av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf);
return q - outbuf;
}
static int dvdsub_encode(AVCodecContext *avctx,
unsigned char *buf, int buf_size, void *data)
{
//DVDSubtitleContext *s = avctx->priv_data;
AVSubtitle *sub = data;
int ret;
ret = encode_dvd_subtitles(buf, buf_size, sub);
return ret;
}
AVCodec dvdsub_encoder = {
"dvdsub",
CODEC_TYPE_SUBTITLE,
CODEC_ID_DVD_SUBTITLE,
0,
NULL,
dvdsub_encode,
.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
};

View File

@ -0,0 +1,332 @@
/*
* Feeble Files/ScummVM DXA decoder
* Copyright (c) 2007 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 dxa.c
* DXA Video decoder
*/
#include <stdio.h>
#include <stdlib.h>
#include "avcodec.h"
#include <zlib.h>
/*
* Decoder context
*/
typedef struct DxaDecContext {
AVCodecContext *avctx;
AVFrame pic, prev;
int dsize;
uint8_t *decomp_buf;
uint32_t pal[256];
} DxaDecContext;
static const int shift1[6] = { 0, 8, 8, 8, 4, 4 };
static const int shift2[6] = { 0, 0, 8, 4, 0, 4 };
static int decode_13(AVCodecContext *avctx, DxaDecContext *c, uint8_t* dst, uint8_t *src, uint8_t *ref)
{
uint8_t *code, *data, *mv, *msk, *tmp, *tmp2;
int i, j, k;
int type, x, y, d, d2;
int stride = c->pic.linesize[0];
uint32_t mask;
code = src + 12;
data = code + ((avctx->width * avctx->height) >> 4);
mv = data + AV_RB32(src + 0);
msk = mv + AV_RB32(src + 4);
for(j = 0; j < avctx->height; j += 4){
for(i = 0; i < avctx->width; i += 4){
tmp = dst + i;
tmp2 = ref + i;
type = *code++;
switch(type){
case 4: // motion compensation
x = (*mv) >> 4; if(x & 8) x = 8 - x;
y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
tmp2 += x + y*stride;
case 0: // skip
case 5: // skip in method 12
for(y = 0; y < 4; y++){
memcpy(tmp, tmp2, 4);
tmp += stride;
tmp2 += stride;
}
break;
case 1: // masked change
case 10: // masked change with only half of pixels changed
case 11: // cases 10-15 are for method 12 only
case 12:
case 13:
case 14:
case 15:
if(type == 1){
mask = AV_RB16(msk);
msk += 2;
}else{
type -= 10;
mask = ((msk[0] & 0xF0) << shift1[type]) | ((msk[0] & 0xF) << shift2[type]);
msk++;
}
for(y = 0; y < 4; y++){
for(x = 0; x < 4; x++){
tmp[x] = (mask & 0x8000) ? *data++ : tmp2[x];
mask <<= 1;
}
tmp += stride;
tmp2 += stride;
}
break;
case 2: // fill block
for(y = 0; y < 4; y++){
memset(tmp, data[0], 4);
tmp += stride;
}
data++;
break;
case 3: // raw block
for(y = 0; y < 4; y++){
memcpy(tmp, data, 4);
data += 4;
tmp += stride;
}
break;
case 8: // subblocks - method 13 only
mask = *msk++;
for(k = 0; k < 4; k++){
d = ((k & 1) << 1) + ((k & 2) * stride);
d2 = ((k & 1) << 1) + ((k & 2) * stride);
tmp2 = ref + i + d2;
switch(mask & 0xC0){
case 0x80: // motion compensation
x = (*mv) >> 4; if(x & 8) x = 8 - x;
y = (*mv++) & 0xF; if(y & 8) y = 8 - y;
tmp2 += x + y*stride;
case 0x00: // skip
tmp[d + 0 ] = tmp2[0];
tmp[d + 1 ] = tmp2[1];
tmp[d + 0 + stride] = tmp2[0 + stride];
tmp[d + 1 + stride] = tmp2[1 + stride];
break;
case 0x40: // fill
tmp[d + 0 ] = data[0];
tmp[d + 1 ] = data[0];
tmp[d + 0 + stride] = data[0];
tmp[d + 1 + stride] = data[0];
data++;
break;
case 0xC0: // raw
tmp[d + 0 ] = *data++;
tmp[d + 1 ] = *data++;
tmp[d + 0 + stride] = *data++;
tmp[d + 1 + stride] = *data++;
break;
}
mask <<= 2;
}
break;
case 32: // vector quantization - 2 colors
mask = AV_RB16(msk);
msk += 2;
for(y = 0; y < 4; y++){
for(x = 0; x < 4; x++){
tmp[x] = data[mask & 1];
mask >>= 1;
}
tmp += stride;
tmp2 += stride;
}
data += 2;
break;
case 33: // vector quantization - 3 or 4 colors
case 34:
mask = AV_RB32(msk);
msk += 4;
for(y = 0; y < 4; y++){
for(x = 0; x < 4; x++){
tmp[x] = data[mask & 3];
mask >>= 2;
}
tmp += stride;
tmp2 += stride;
}
data += type - 30;
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown opcode %d\n", type);
return -1;
}
}
dst += stride * 4;
ref += stride * 4;
}
return 0;
}
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
{
DxaDecContext * const c = avctx->priv_data;
uint8_t *outptr, *srcptr, *tmpptr;
unsigned long dsize;
int i, j, compr;
int stride;
int orig_buf_size = buf_size;
int pc = 0;
/* make the palette available on the way out */
if(buf[0]=='C' && buf[1]=='M' && buf[2]=='A' && buf[3]=='P'){
int r, g, b;
buf += 4;
for(i = 0; i < 256; i++){
r = *buf++;
g = *buf++;
b = *buf++;
c->pal[i] = (r << 16) | (g << 8) | b;
}
pc = 1;
buf_size -= 768+4;
}
if(avctx->get_buffer(avctx, &c->pic) < 0){
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
c->pic.palette_has_changed = pc;
outptr = c->pic.data[0];
srcptr = c->decomp_buf;
tmpptr = c->prev.data[0];
stride = c->pic.linesize[0];
if(buf[0]=='N' && buf[1]=='U' && buf[2]=='L' && buf[3]=='L')
compr = -1;
else
compr = buf[4];
dsize = c->dsize;
if((compr != 4 && compr != -1) && uncompress(c->decomp_buf, &dsize, buf + 9, buf_size - 9) != Z_OK){
av_log(avctx, AV_LOG_ERROR, "Uncompress failed!\n");
return -1;
}
switch(compr){
case -1:
c->pic.key_frame = 0;
c->pic.pict_type = FF_P_TYPE;
if(c->prev.data[0])
memcpy(c->pic.data[0], c->prev.data[0], c->pic.linesize[0] * avctx->height);
else{ // Should happen only when first frame is 'NULL'
memset(c->pic.data[0], 0, c->pic.linesize[0] * avctx->height);
c->pic.key_frame = 1;
c->pic.pict_type = FF_I_TYPE;
}
break;
case 2:
case 3:
case 4:
case 5:
c->pic.key_frame = !(compr & 1);
c->pic.pict_type = (compr & 1) ? FF_P_TYPE : FF_I_TYPE;
for(j = 0; j < avctx->height; j++){
if(compr & 1){
for(i = 0; i < avctx->width; i++)
outptr[i] = srcptr[i] ^ tmpptr[i];
tmpptr += stride;
}else
memcpy(outptr, srcptr, avctx->width);
outptr += stride;
srcptr += avctx->width;
}
break;
case 12: // ScummVM coding
case 13:
c->pic.key_frame = 0;
c->pic.pict_type = FF_P_TYPE;
decode_13(avctx, c, c->pic.data[0], srcptr, c->prev.data[0]);
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unknown/unsupported compression type %d\n", buf[4]);
return -1;
}
FFSWAP(AVFrame, c->pic, c->prev);
if(c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
*data_size = sizeof(AVFrame);
*(AVFrame*)data = c->prev;
/* always report that the buffer was completely consumed */
return orig_buf_size;
}
static av_cold int decode_init(AVCodecContext *avctx)
{
DxaDecContext * const c = avctx->priv_data;
c->avctx = avctx;
avctx->pix_fmt = PIX_FMT_PAL8;
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
return -1;
}
c->dsize = avctx->width * avctx->height * 2;
if((c->decomp_buf = av_malloc(c->dsize)) == NULL) {
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
return -1;
}
return 0;
}
static av_cold int decode_end(AVCodecContext *avctx)
{
DxaDecContext * const c = avctx->priv_data;
av_freep(&c->decomp_buf);
if(c->prev.data[0])
avctx->release_buffer(avctx, &c->prev);
if(c->pic.data[0])
avctx->release_buffer(avctx, &c->pic);
return 0;
}
AVCodec dxa_decoder = {
"dxa",
CODEC_TYPE_VIDEO,
CODEC_ID_DXA,
sizeof(DxaDecContext),
decode_init,
NULL,
decode_end,
decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Feeble Files/ScummVM DXA"),
};