Commit d268bed2 authored by Oskar Arvidsson's avatar Oskar Arvidsson Committed by Michael Niedermayer

Add support for higher QP values in h264.

In high bit depth, the QP values may now be up to (51 + 6*(bit_depth-8)).

Preparatory patch for high bit depth h264 decoding support.
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 436c4523
......@@ -45,12 +45,12 @@
//#undef NDEBUG
#include <assert.h>
static const uint8_t rem6[52]={
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
static const uint8_t rem6[QP_MAX_MAX+1]={
0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
};
static const uint8_t div6[52]={
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8,
static const uint8_t div6[QP_MAX_MAX+1]={
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,10,10,10,10,
};
static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
......@@ -769,6 +769,7 @@ static void free_tables(H264Context *h, int free_rbsp){
static void init_dequant8_coeff_table(H264Context *h){
int i,q,x;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
h->dequant8_coeff[0] = h->dequant8_buffer[0];
h->dequant8_coeff[1] = h->dequant8_buffer[1];
......@@ -778,7 +779,7 @@ static void init_dequant8_coeff_table(H264Context *h){
break;
}
for(q=0; q<52; q++){
for(q=0; q<max_qp+1; q++){
int shift = div6[q];
int idx = rem6[q];
for(x=0; x<64; x++)
......@@ -791,6 +792,7 @@ static void init_dequant8_coeff_table(H264Context *h){
static void init_dequant4_coeff_table(H264Context *h){
int i,j,q,x;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
for(i=0; i<6; i++ ){
h->dequant4_coeff[i] = h->dequant4_buffer[i];
for(j=0; j<i; j++){
......@@ -802,7 +804,7 @@ static void init_dequant4_coeff_table(H264Context *h){
if(j<i)
continue;
for(q=0; q<52; q++){
for(q=0; q<max_qp+1; q++){
int shift = div6[q] + 2;
int idx = rem6[q];
for(x=0; x<16; x++)
......@@ -1003,6 +1005,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){
ff_h264_decode_init_vlc();
h->sps.bit_depth_luma = 8;
h->pixel_size = 1;
h->thread_context[0] = h;
......@@ -1771,7 +1774,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){
for(i=16; i<16+8; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i];
ff_svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[s->qscale + 12] - 12, 2);
ff_svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, ff_h264_chroma_qp[0][s->qscale + 12] - 12, 2);
}
}
}
......@@ -2589,7 +2592,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->last_qscale_diff = 0;
tmp = h->pps.init_qp + get_se_golomb(&s->gb);
if(tmp>51){
if(tmp>51+6*(h->sps.bit_depth_luma-8)){
av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
return -1;
}
......
......@@ -108,6 +108,7 @@
*/
#define DELAYED_PIC_REF 4
#define QP_MAX_MAX (51 + 2*6) // The maximum supported qp
/* NAL unit types */
enum {
......@@ -354,8 +355,8 @@ typedef struct H264Context{
*/
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?
uint32_t dequant4_buffer[6][52][16]; //FIXME should these be moved down?
uint32_t dequant8_buffer[2][52][64];
uint32_t dequant4_buffer[6][QP_MAX_MAX+1][16]; //FIXME should these be moved down?
uint32_t dequant8_buffer[2][QP_MAX_MAX+1][64];
uint32_t (*dequant4_coeff[6])[16];
uint32_t (*dequant8_coeff[2])[64];
......@@ -603,7 +604,7 @@ typedef struct H264Context{
}H264Context;
extern const uint8_t ff_h264_chroma_qp[52];
extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_MAX+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
/**
* Decode SEI
......
......@@ -689,13 +689,14 @@ void ff_h264_init_cabac_states(H264Context *h) {
MpegEncContext * const s = &h->s;
int i;
const int8_t (*tab)[2];
const int slice_qp = av_clip(s->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
if( h->slice_type_nos == FF_I_TYPE ) tab = cabac_context_init_I;
else tab = cabac_context_init_PB[h->cabac_init_idc];
/* calculate pre-state */
for( i= 0; i < 460; i++ ) {
int pre = 2*(((tab[i][0] * s->qscale) >>4 ) + tab[i][1]) - 127;
int pre = 2*(((tab[i][0] * slice_qp) >>4 ) + tab[i][1]) - 127;
pre^= pre>>31;
if(pre > 124)
......@@ -1630,11 +1631,12 @@ decode_intra_mb:
if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){
int val = 1;
int ctx= 2;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {
ctx= 3;
val++;
if(val > 102){ //prevent infinite loop
if(val > 2*max_qp){ //prevent infinite loop
av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);
return -1;
}
......@@ -1646,9 +1648,9 @@ decode_intra_mb:
val= -((val + 1)>>1);
h->last_qscale_diff = val;
s->qscale += val;
if(((unsigned)s->qscale) > 51){
if(s->qscale<0) s->qscale+= 52;
else s->qscale-= 52;
if(((unsigned)s->qscale) > max_qp){
if(s->qscale<0) s->qscale+= max_qp+1;
else s->qscale-= max_qp+1;
}
h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
......
......@@ -921,6 +921,7 @@ decode_intra_mb:
int dquant;
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;
const uint8_t *scan, *scan8x8;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
if(IS_INTERLACED(mb_type)){
scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
......@@ -934,10 +935,10 @@ decode_intra_mb:
s->qscale += dquant;
if(((unsigned)s->qscale) > 51){
if(s->qscale<0) s->qscale+= 52;
else s->qscale-= 52;
if(((unsigned)s->qscale) > 51){
if(((unsigned)s->qscale) > max_qp){
if(s->qscale<0) s->qscale+= max_qp+1;
else s->qscale-= max_qp+1;
if(((unsigned)s->qscale) > max_qp){
av_log(h->s.avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, s->mb_x, s->mb_y);
return -1;
}
......
......@@ -57,11 +57,32 @@ static const AVRational pixel_aspect[17]={
{2, 1},
};
const uint8_t ff_h264_chroma_qp[52]={
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,
12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37,
37,38,38,38,39,39,39,39
#define QP(qP,depth) ( (qP)+6*((depth)-8) )
#define CHROMA_QP_TABLE_END(d) \
QP(0,d), QP(1,d), QP(2,d), QP(3,d), QP(4,d), QP(5,d),\
QP(6,d), QP(7,d), QP(8,d), QP(9,d), QP(10,d), QP(11,d),\
QP(12,d), QP(13,d), QP(14,d), QP(15,d), QP(16,d), QP(17,d),\
QP(18,d), QP(19,d), QP(20,d), QP(21,d), QP(22,d), QP(23,d),\
QP(24,d), QP(25,d), QP(26,d), QP(27,d), QP(28,d), QP(29,d),\
QP(29,d), QP(30,d), QP(31,d), QP(32,d), QP(32,d), QP(33,d),\
QP(34,d), QP(34,d), QP(35,d), QP(35,d), QP(36,d), QP(36,d),\
QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\
QP(39,d), QP(39,d), QP(39,d), QP(39,d)
const uint8_t ff_h264_chroma_qp[3][QP_MAX_MAX+1] = {
{
CHROMA_QP_TABLE_END(8)
},
{
0, 1, 2, 3, 4, 5,
CHROMA_QP_TABLE_END(9)
},
{
0, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11,
CHROMA_QP_TABLE_END(10)
},
};
static const uint8_t default_scaling4[2][16]={
......@@ -419,17 +440,19 @@ fail:
}
static void
build_qp_table(PPS *pps, int t, int index)
build_qp_table(PPS *pps, int t, int index, const int depth)
{
int i;
for(i = 0; i < 52; i++)
pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[av_clip(i + index, 0, 51)];
const int max_qp = 51 + 6*(depth-8);
for(i = 0; i < max_qp+1; i++)
pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)];
}
int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
MpegEncContext * const s = &h->s;
unsigned int pps_id= get_ue_golomb(&s->gb);
PPS *pps;
const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
if(pps_id >= MAX_PPS_COUNT) {
av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
......@@ -494,8 +517,8 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
pps->weighted_pred= get_bits1(&s->gb);
pps->weighted_bipred_idc= get_bits(&s->gb, 2);
pps->init_qp= get_se_golomb(&s->gb) + 26;
pps->init_qs= get_se_golomb(&s->gb) + 26;
pps->init_qp= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
pps->init_qs= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);
pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
pps->constrained_intra_pred= get_bits1(&s->gb);
......@@ -514,8 +537,8 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
pps->chroma_qp_index_offset[1]= pps->chroma_qp_index_offset[0];
}
build_qp_table(pps, 0, pps->chroma_qp_index_offset[0]);
build_qp_table(pps, 1, pps->chroma_qp_index_offset[1]);
build_qp_table(pps, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma);
build_qp_table(pps, 1, pps->chroma_qp_index_offset[1], h->sps.bit_depth_luma);
if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
pps->chroma_qp_diff= 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment