1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "libavcodec/cabac_functions.h" 22cabdff1aSopenharmony_ci#include "libavcodec/cabac.c" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#define SIZE 10240 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#include "libavutil/lfg.h" 27cabdff1aSopenharmony_ci#include "libavcodec/put_bits.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_citypedef struct CABACTestContext { 30cabdff1aSopenharmony_ci CABACContext dec; 31cabdff1aSopenharmony_ci int outstanding_count; 32cabdff1aSopenharmony_ci PutBitContext pb; 33cabdff1aSopenharmony_ci} CABACTestContext; 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_cistatic inline void put_cabac_bit(CABACTestContext *c, int b) 36cabdff1aSopenharmony_ci{ 37cabdff1aSopenharmony_ci put_bits(&c->pb, 1, b); 38cabdff1aSopenharmony_ci for(;c->outstanding_count; c->outstanding_count--){ 39cabdff1aSopenharmony_ci put_bits(&c->pb, 1, 1-b); 40cabdff1aSopenharmony_ci } 41cabdff1aSopenharmony_ci} 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_cistatic inline void renorm_cabac_encoder(CABACTestContext *c) 44cabdff1aSopenharmony_ci{ 45cabdff1aSopenharmony_ci while (c->dec.range < 0x100) { 46cabdff1aSopenharmony_ci //FIXME optimize 47cabdff1aSopenharmony_ci if (c->dec.low < 0x100) { 48cabdff1aSopenharmony_ci put_cabac_bit(c, 0); 49cabdff1aSopenharmony_ci } else if (c->dec.low < 0x200) { 50cabdff1aSopenharmony_ci c->outstanding_count++; 51cabdff1aSopenharmony_ci c->dec.low -= 0x100; 52cabdff1aSopenharmony_ci }else{ 53cabdff1aSopenharmony_ci put_cabac_bit(c, 1); 54cabdff1aSopenharmony_ci c->dec.low -= 0x200; 55cabdff1aSopenharmony_ci } 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci c->dec.range += c->dec.range; 58cabdff1aSopenharmony_ci c->dec.low += c->dec.low; 59cabdff1aSopenharmony_ci } 60cabdff1aSopenharmony_ci} 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_cistatic void put_cabac(CABACTestContext *c, uint8_t * const state, int bit) 63cabdff1aSopenharmony_ci{ 64cabdff1aSopenharmony_ci int RangeLPS = ff_h264_lps_range[2 * (c->dec.range & 0xC0) + *state]; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci if(bit == ((*state)&1)){ 67cabdff1aSopenharmony_ci c->dec.range -= RangeLPS; 68cabdff1aSopenharmony_ci *state = ff_h264_mlps_state[128 + *state]; 69cabdff1aSopenharmony_ci }else{ 70cabdff1aSopenharmony_ci c->dec.low += c->dec.range - RangeLPS; 71cabdff1aSopenharmony_ci c->dec.range = RangeLPS; 72cabdff1aSopenharmony_ci *state= ff_h264_mlps_state[127 - *state]; 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci renorm_cabac_encoder(c); 76cabdff1aSopenharmony_ci} 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci/** 79cabdff1aSopenharmony_ci * @param bit 0 -> write zero bit, !=0 write one bit 80cabdff1aSopenharmony_ci */ 81cabdff1aSopenharmony_cistatic void put_cabac_bypass(CABACTestContext *c, int bit) 82cabdff1aSopenharmony_ci{ 83cabdff1aSopenharmony_ci c->dec.low += c->dec.low; 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci if(bit){ 86cabdff1aSopenharmony_ci c->dec.low += c->dec.range; 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci//FIXME optimize 89cabdff1aSopenharmony_ci if (c->dec.low < 0x200) { 90cabdff1aSopenharmony_ci put_cabac_bit(c, 0); 91cabdff1aSopenharmony_ci } else if (c->dec.low < 0x400) { 92cabdff1aSopenharmony_ci c->outstanding_count++; 93cabdff1aSopenharmony_ci c->dec.low -= 0x200; 94cabdff1aSopenharmony_ci }else{ 95cabdff1aSopenharmony_ci put_cabac_bit(c, 1); 96cabdff1aSopenharmony_ci c->dec.low -= 0x400; 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci} 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci/** 101cabdff1aSopenharmony_ci * 102cabdff1aSopenharmony_ci * @return the number of bytes written 103cabdff1aSopenharmony_ci */ 104cabdff1aSopenharmony_cistatic int put_cabac_terminate(CABACTestContext *c, int bit) 105cabdff1aSopenharmony_ci{ 106cabdff1aSopenharmony_ci c->dec.range -= 2; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_ci if(!bit){ 109cabdff1aSopenharmony_ci renorm_cabac_encoder(c); 110cabdff1aSopenharmony_ci }else{ 111cabdff1aSopenharmony_ci c->dec.low += c->dec.range; 112cabdff1aSopenharmony_ci c->dec.range = 2; 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci renorm_cabac_encoder(c); 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci av_assert0(c->dec.low <= 0x1FF); 117cabdff1aSopenharmony_ci put_cabac_bit(c, c->dec.low >> 9); 118cabdff1aSopenharmony_ci put_bits(&c->pb, 2, ((c->dec.low >> 7) & 3) | 1); 119cabdff1aSopenharmony_ci 120cabdff1aSopenharmony_ci flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci return put_bytes_count(&c->pb, 1); 124cabdff1aSopenharmony_ci} 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci/** 127cabdff1aSopenharmony_ci * @param buf_size size of buf in bits 128cabdff1aSopenharmony_ci */ 129cabdff1aSopenharmony_cistatic void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size) 130cabdff1aSopenharmony_ci{ 131cabdff1aSopenharmony_ci init_put_bits(&c->pb, buf, buf_size); 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci c->dec.low = 0; 134cabdff1aSopenharmony_ci c->dec.range = 0x1FE; 135cabdff1aSopenharmony_ci c->outstanding_count = 0; 136cabdff1aSopenharmony_ci c->pb.bit_left++; //avoids firstBitFlag 137cabdff1aSopenharmony_ci} 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ciint main(void){ 140cabdff1aSopenharmony_ci CABACTestContext c; 141cabdff1aSopenharmony_ci uint8_t b[9*SIZE]; 142cabdff1aSopenharmony_ci uint8_t r[9*SIZE]; 143cabdff1aSopenharmony_ci int i, ret = 0; 144cabdff1aSopenharmony_ci uint8_t state[10]= {0}; 145cabdff1aSopenharmony_ci AVLFG prng; 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci av_lfg_init(&prng, 1); 148cabdff1aSopenharmony_ci init_cabac_encoder(&c, b, SIZE); 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci for(i=0; i<SIZE; i++){ 151cabdff1aSopenharmony_ci if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7; 152cabdff1aSopenharmony_ci else r[i] = (i>>8)&1; 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci for(i=0; i<SIZE; i++){ 156cabdff1aSopenharmony_ci put_cabac_bypass(&c, r[i]&1); 157cabdff1aSopenharmony_ci } 158cabdff1aSopenharmony_ci 159cabdff1aSopenharmony_ci for(i=0; i<SIZE; i++){ 160cabdff1aSopenharmony_ci put_cabac(&c, state, r[i]&1); 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci 163cabdff1aSopenharmony_ci i= put_cabac_terminate(&c, 1); 164cabdff1aSopenharmony_ci b[i++] = av_lfg_get(&prng); 165cabdff1aSopenharmony_ci b[i ] = av_lfg_get(&prng); 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_ci ff_init_cabac_decoder(&c.dec, b, SIZE); 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci memset(state, 0, sizeof(state)); 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci for(i=0; i<SIZE; i++){ 172cabdff1aSopenharmony_ci if ((r[i] & 1) != get_cabac_bypass(&c.dec)) { 173cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i); 174cabdff1aSopenharmony_ci ret = 1; 175cabdff1aSopenharmony_ci } 176cabdff1aSopenharmony_ci } 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci for(i=0; i<SIZE; i++){ 179cabdff1aSopenharmony_ci if ((r[i] & 1) != get_cabac_noinline(&c.dec, state)) { 180cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i); 181cabdff1aSopenharmony_ci ret = 1; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci if (!get_cabac_terminate(&c.dec)) { 185cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n"); 186cabdff1aSopenharmony_ci ret = 1; 187cabdff1aSopenharmony_ci } 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_ci return ret; 190cabdff1aSopenharmony_ci} 191