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:
parent
ae0c133a58
commit
8c2268fcfc
1269
src/add-ons/media/plugins/avcodec/libavcodec/dca.c
Normal file
1269
src/add-ons/media/plugins/avcodec/libavcodec/dca.c
Normal file
File diff suppressed because it is too large
Load Diff
34
src/add-ons/media/plugins/avcodec/libavcodec/dca.h
Normal file
34
src/add-ons/media/plugins/avcodec/libavcodec/dca.h
Normal 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 */
|
131
src/add-ons/media/plugins/avcodec/libavcodec/dca_parser.c
Normal file
131
src/add-ons/media/plugins/avcodec/libavcodec/dca_parser.c
Normal 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,
|
||||
};
|
8474
src/add-ons/media/plugins/avcodec/libavcodec/dcadata.h
Normal file
8474
src/add-ons/media/plugins/avcodec/libavcodec/dcadata.h
Normal file
File diff suppressed because it is too large
Load Diff
1076
src/add-ons/media/plugins/avcodec/libavcodec/dcahuff.h
Normal file
1076
src/add-ons/media/plugins/avcodec/libavcodec/dcahuff.h
Normal file
File diff suppressed because it is too large
Load Diff
582
src/add-ons/media/plugins/avcodec/libavcodec/dct-test.c
Normal file
582
src/add-ons/media/plugins/avcodec/libavcodec/dct-test.c
Normal 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;
|
||||
}
|
88
src/add-ons/media/plugins/avcodec/libavcodec/dirac_parser.c
Normal file
88
src/add-ons/media/plugins/avcodec/libavcodec/dirac_parser.c
Normal 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,
|
||||
};
|
445
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.c
Normal file
445
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.c
Normal 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;
|
||||
}
|
51
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.h
Normal file
51
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddata.h
Normal 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 */
|
346
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddec.c
Normal file
346
src/add-ons/media/plugins/avcodec/libavcodec/dnxhddec.c
Normal 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"),
|
||||
};
|
861
src/add-ons/media/plugins/avcodec/libavcodec/dnxhdenc.c
Normal file
861
src/add-ons/media/plugins/avcodec/libavcodec/dnxhdenc.c
Normal 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"),
|
||||
};
|
@ -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");
|
||||
|
365
src/add-ons/media/plugins/avcodec/libavcodec/dsicinav.c
Normal file
365
src/add-ons/media/plugins/avcodec/libavcodec/dsicinav.c
Normal 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
@ -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 */
|
||||
|
@ -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
412
src/add-ons/media/plugins/avcodec/libavcodec/dvbsub.c
Normal file
412
src/add-ons/media/plugins/avcodec/libavcodec/dvbsub.c
Normal 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"),
|
||||
};
|
196
src/add-ons/media/plugins/avcodec/libavcodec/dvbsub_parser.c
Normal file
196
src/add-ons/media/plugins/avcodec/libavcodec/dvbsub_parser.c
Normal 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,
|
||||
};
|
1434
src/add-ons/media/plugins/avcodec/libavcodec/dvbsubdec.c
Normal file
1434
src/add-ons/media/plugins/avcodec/libavcodec/dvbsubdec.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
83
src/add-ons/media/plugins/avcodec/libavcodec/dvdsub_parser.c
Normal file
83
src/add-ons/media/plugins/avcodec/libavcodec/dvdsub_parser.c
Normal 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,
|
||||
};
|
512
src/add-ons/media/plugins/avcodec/libavcodec/dvdsubdec.c
Normal file
512
src/add-ons/media/plugins/avcodec/libavcodec/dvdsubdec.c
Normal 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"),
|
||||
};
|
226
src/add-ons/media/plugins/avcodec/libavcodec/dvdsubenc.c
Normal file
226
src/add-ons/media/plugins/avcodec/libavcodec/dvdsubenc.c
Normal 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"),
|
||||
};
|
332
src/add-ons/media/plugins/avcodec/libavcodec/dxa.c
Normal file
332
src/add-ons/media/plugins/avcodec/libavcodec/dxa.c
Normal 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"),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user