* release/0.7: (296 commits) Update version numbers for 0.7.5 vp6: partially propagate huffman tree building errors during coeff model parsing and fix misspelling Check for huffman tree building error in vp6 decoder. Release old pictures after a resolution change in vp5/6 decoder Check for missing reference in vp5/6 decoder. Check for invalid slices offsets in RV30/40 decoder. Check output buffer size in nellymoser decoder. Hack around gcc 4.6 breaking asm using call. Hack around gcc 4.6 breaking asm using call. Fix dxva2 decoding for some H264 samples. (cherry picked from commit bf7dc6b29d785f149f18c39db021413e08735546) Fix dxva2 decoding for some H264 samples. mp3demux: pass on error code on packet read. Check for invalid slice offsets in real decoder. rmdec: Reject invalid deinterleaving parameters Use deinterleavers for demangling audio packets in RealMedia. rv10: Reject slices that does not have the same type as the first one rmdec: use the deinterleaving mode and not the codec when creating audio packets. MAINTAINERS: add my GPG fingerprint. (cherry picked from commit 7882dc10f871bf25a848fe62a152f63814f9c7d1) Support 3IVD in isom, produced by 3ivx DivX Doctor. mpegpsdec: fix reading first mpegps packet (cherry picked from commit b2f230e23dd61112ac090b0c059d87b5f6bcb307) ... Conflicts: Changelog Doxyfile Makefile RELEASE configure doc/general.texi ffmpeg.c ffplay.c libavcodec/dxva2_h264.c libavcodec/h264.c libavcodec/h264_loopfilter.c libavcodec/h264idct_template.c libavcodec/kgv1dec.c libavcodec/mpegvideo.c libavcodec/tableprint.h libavcodec/vp3.c libavdevice/alsa-audio.h libavformat/gxf.c libavformat/mpegts.c libavformat/segafilm.c libavformat/utils.c libavutil/dict.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
390 lines
10 KiB
C
390 lines
10 KiB
C
/*
|
|
* H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
|
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
|
*
|
|
* This file is part of FFmpeg.
|
|
*
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* Context Adaptive Binary Arithmetic Coder.
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "libavutil/common.h"
|
|
#include "get_bits.h"
|
|
#include "cabac.h"
|
|
|
|
static const uint8_t lps_range[64][4]= {
|
|
{128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205},
|
|
{116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166},
|
|
{ 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135},
|
|
{ 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110},
|
|
{ 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89},
|
|
{ 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
|
|
{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59},
|
|
{ 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
|
|
{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39},
|
|
{ 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
|
|
{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25},
|
|
{ 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
|
|
{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17},
|
|
{ 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14},
|
|
{ 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11},
|
|
{ 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2},
|
|
};
|
|
|
|
uint8_t ff_h264_mlps_state[4*64];
|
|
uint8_t ff_h264_lps_range[4*2*64];
|
|
uint8_t ff_h264_lps_state[2*64];
|
|
uint8_t ff_h264_mps_state[2*64];
|
|
|
|
static const uint8_t mps_state[64]= {
|
|
1, 2, 3, 4, 5, 6, 7, 8,
|
|
9,10,11,12,13,14,15,16,
|
|
17,18,19,20,21,22,23,24,
|
|
25,26,27,28,29,30,31,32,
|
|
33,34,35,36,37,38,39,40,
|
|
41,42,43,44,45,46,47,48,
|
|
49,50,51,52,53,54,55,56,
|
|
57,58,59,60,61,62,62,63,
|
|
};
|
|
|
|
static const uint8_t lps_state[64]= {
|
|
0, 0, 1, 2, 2, 4, 4, 5,
|
|
6, 7, 8, 9, 9,11,11,12,
|
|
13,13,15,15,16,16,18,18,
|
|
19,19,21,21,22,22,23,24,
|
|
24,25,26,26,27,27,28,29,
|
|
29,30,30,30,31,32,32,33,
|
|
33,33,34,34,35,35,35,36,
|
|
36,36,37,37,37,38,38,63,
|
|
};
|
|
|
|
const uint8_t ff_h264_norm_shift[512]= {
|
|
9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
|
|
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
|
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param buf_size size of buf in bits
|
|
*/
|
|
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
|
|
init_put_bits(&c->pb, buf, buf_size);
|
|
|
|
c->low= 0;
|
|
c->range= 0x1FE;
|
|
c->outstanding_count= 0;
|
|
#ifdef STRICT_LIMITS
|
|
c->sym_count =0;
|
|
#endif
|
|
|
|
c->pb.bit_left++; //avoids firstBitFlag
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param buf_size size of buf in bits
|
|
*/
|
|
void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
|
|
c->bytestream_start=
|
|
c->bytestream= buf;
|
|
c->bytestream_end= buf + buf_size;
|
|
|
|
#if CABAC_BITS == 16
|
|
c->low = (*c->bytestream++)<<18;
|
|
c->low+= (*c->bytestream++)<<10;
|
|
#else
|
|
c->low = (*c->bytestream++)<<10;
|
|
#endif
|
|
c->low+= ((*c->bytestream++)<<2) + 2;
|
|
c->range= 0x1FE;
|
|
}
|
|
|
|
void ff_init_cabac_states(CABACContext *c){
|
|
int i, j;
|
|
|
|
for(i=0; i<64; i++){
|
|
for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
|
|
ff_h264_lps_range[j*2*64+2*i+0]=
|
|
ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j];
|
|
}
|
|
|
|
ff_h264_mlps_state[128+2*i+0]=
|
|
ff_h264_mps_state[2*i+0]= 2*mps_state[i]+0;
|
|
ff_h264_mlps_state[128+2*i+1]=
|
|
ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1;
|
|
|
|
if( i ){
|
|
ff_h264_lps_state[2*i+0]=
|
|
ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
|
|
ff_h264_lps_state[2*i+1]=
|
|
ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
|
|
}else{
|
|
ff_h264_lps_state[2*i+0]=
|
|
ff_h264_mlps_state[128-2*i-1]= 1;
|
|
ff_h264_lps_state[2*i+1]=
|
|
ff_h264_mlps_state[128-2*i-2]= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef TEST
|
|
#define SIZE 10240
|
|
|
|
#include "libavutil/lfg.h"
|
|
#include "avcodec.h"
|
|
#include "cabac.h"
|
|
|
|
static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
|
|
int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
|
|
|
|
if(bit == ((*state)&1)){
|
|
c->range -= RangeLPS;
|
|
*state= ff_h264_mps_state[*state];
|
|
}else{
|
|
c->low += c->range - RangeLPS;
|
|
c->range = RangeLPS;
|
|
*state= ff_h264_lps_state[*state];
|
|
}
|
|
|
|
renorm_cabac_encoder(c);
|
|
|
|
#ifdef STRICT_LIMITS
|
|
c->symCount++;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @param bit 0 -> write zero bit, !=0 write one bit
|
|
*/
|
|
static void put_cabac_bypass(CABACContext *c, int bit){
|
|
c->low += c->low;
|
|
|
|
if(bit){
|
|
c->low += c->range;
|
|
}
|
|
//FIXME optimize
|
|
if(c->low<0x200){
|
|
put_cabac_bit(c, 0);
|
|
}else if(c->low<0x400){
|
|
c->outstanding_count++;
|
|
c->low -= 0x200;
|
|
}else{
|
|
put_cabac_bit(c, 1);
|
|
c->low -= 0x400;
|
|
}
|
|
|
|
#ifdef STRICT_LIMITS
|
|
c->symCount++;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @return the number of bytes written
|
|
*/
|
|
static int put_cabac_terminate(CABACContext *c, int bit){
|
|
c->range -= 2;
|
|
|
|
if(!bit){
|
|
renorm_cabac_encoder(c);
|
|
}else{
|
|
c->low += c->range;
|
|
c->range= 2;
|
|
|
|
renorm_cabac_encoder(c);
|
|
|
|
assert(c->low <= 0x1FF);
|
|
put_cabac_bit(c, c->low>>9);
|
|
put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
|
|
|
|
flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
|
|
}
|
|
|
|
#ifdef STRICT_LIMITS
|
|
c->symCount++;
|
|
#endif
|
|
|
|
return (put_bits_count(&c->pb)+7)>>3;
|
|
}
|
|
|
|
/**
|
|
* put (truncated) unary binarization.
|
|
*/
|
|
static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
|
|
int i;
|
|
|
|
assert(v <= max);
|
|
|
|
for(i=0; i<v; i++){
|
|
put_cabac(c, state, 1);
|
|
if(i < max_index) state++;
|
|
}
|
|
if(truncated==0 || v<max)
|
|
put_cabac(c, state, 0);
|
|
}
|
|
|
|
/**
|
|
* put unary exp golomb k-th order binarization.
|
|
*/
|
|
static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
|
|
int i;
|
|
|
|
if(v==0)
|
|
put_cabac(c, state, 0);
|
|
else{
|
|
const int sign= v < 0;
|
|
|
|
if(is_signed) v= FFABS(v);
|
|
|
|
if(v<max){
|
|
for(i=0; i<v; i++){
|
|
put_cabac(c, state, 1);
|
|
if(i < max_index) state++;
|
|
}
|
|
|
|
put_cabac(c, state, 0);
|
|
}else{
|
|
int m= 1<<k;
|
|
|
|
for(i=0; i<max; i++){
|
|
put_cabac(c, state, 1);
|
|
if(i < max_index) state++;
|
|
}
|
|
|
|
v -= max;
|
|
while(v >= m){ //FIXME optimize
|
|
put_cabac_bypass(c, 1);
|
|
v-= m;
|
|
m+= m;
|
|
}
|
|
put_cabac_bypass(c, 0);
|
|
while(m>>=1){
|
|
put_cabac_bypass(c, v&m);
|
|
}
|
|
}
|
|
|
|
if(is_signed)
|
|
put_cabac_bypass(c, sign);
|
|
}
|
|
}
|
|
|
|
int main(void){
|
|
CABACContext c;
|
|
uint8_t b[9*SIZE];
|
|
uint8_t r[9*SIZE];
|
|
int i;
|
|
uint8_t state[10]= {0};
|
|
AVLFG prng;
|
|
|
|
av_lfg_init(&prng, 1);
|
|
ff_init_cabac_encoder(&c, b, SIZE);
|
|
ff_init_cabac_states(&c);
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
|
|
else r[i] = (i>>8)&1;
|
|
}
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
put_cabac_bypass(&c, r[i]&1);
|
|
STOP_TIMER("put_cabac_bypass")
|
|
}
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
put_cabac(&c, state, r[i]&1);
|
|
STOP_TIMER("put_cabac")
|
|
}
|
|
|
|
#if 0
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
put_cabac_u(&c, state, r[i], 6, 3, i&1);
|
|
STOP_TIMER("put_cabac_u")
|
|
}
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
put_cabac_ueg(&c, state, r[i], 3, 0, 1, 2);
|
|
STOP_TIMER("put_cabac_ueg")
|
|
}
|
|
#endif
|
|
put_cabac_terminate(&c, 1);
|
|
|
|
ff_init_cabac_decoder(&c, b, SIZE);
|
|
|
|
memset(state, 0, sizeof(state));
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
if( (r[i]&1) != get_cabac_bypass(&c) )
|
|
av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
|
|
STOP_TIMER("get_cabac_bypass")
|
|
}
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
if( (r[i]&1) != get_cabac(&c, state) )
|
|
av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
|
|
STOP_TIMER("get_cabac")
|
|
}
|
|
#if 0
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) )
|
|
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
|
STOP_TIMER("get_cabac_u")
|
|
}
|
|
|
|
for(i=0; i<SIZE; i++){
|
|
START_TIMER
|
|
if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2))
|
|
av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i);
|
|
STOP_TIMER("get_cabac_ueg")
|
|
}
|
|
#endif
|
|
if(!get_cabac_terminate(&c))
|
|
av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
#endif /* TEST */
|