Commit fcc0224e authored by Oskar Arvidsson's avatar Oskar Arvidsson Committed by Ronald S. Bultje

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 avatarRonald S. Bultje <rsbultje@gmail.com>
parent 6e3ef511
...@@ -44,12 +44,12 @@ ...@@ -44,12 +44,12 @@
//#undef NDEBUG //#undef NDEBUG
#include <assert.h> #include <assert.h>
static const uint8_t rem6[52]={ static const uint8_t rem6[QP_MAX_NUM+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, 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]={ static const uint8_t div6[QP_MAX_NUM+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, 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[] = { static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
...@@ -658,6 +658,7 @@ static void free_tables(H264Context *h, int free_rbsp){ ...@@ -658,6 +658,7 @@ static void free_tables(H264Context *h, int free_rbsp){
static void init_dequant8_coeff_table(H264Context *h){ static void init_dequant8_coeff_table(H264Context *h){
int i,q,x; 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[0] = h->dequant8_buffer[0];
h->dequant8_coeff[1] = h->dequant8_buffer[1]; h->dequant8_coeff[1] = h->dequant8_buffer[1];
...@@ -667,7 +668,7 @@ static void init_dequant8_coeff_table(H264Context *h){ ...@@ -667,7 +668,7 @@ static void init_dequant8_coeff_table(H264Context *h){
break; break;
} }
for(q=0; q<52; q++){ for(q=0; q<max_qp+1; q++){
int shift = div6[q]; int shift = div6[q];
int idx = rem6[q]; int idx = rem6[q];
for(x=0; x<64; x++) for(x=0; x<64; x++)
...@@ -680,6 +681,7 @@ static void init_dequant8_coeff_table(H264Context *h){ ...@@ -680,6 +681,7 @@ static void init_dequant8_coeff_table(H264Context *h){
static void init_dequant4_coeff_table(H264Context *h){ static void init_dequant4_coeff_table(H264Context *h){
int i,j,q,x; int i,j,q,x;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
for(i=0; i<6; i++ ){ for(i=0; i<6; i++ ){
h->dequant4_coeff[i] = h->dequant4_buffer[i]; h->dequant4_coeff[i] = h->dequant4_buffer[i];
for(j=0; j<i; j++){ for(j=0; j<i; j++){
...@@ -691,7 +693,7 @@ static void init_dequant4_coeff_table(H264Context *h){ ...@@ -691,7 +693,7 @@ static void init_dequant4_coeff_table(H264Context *h){
if(j<i) if(j<i)
continue; continue;
for(q=0; q<52; q++){ for(q=0; q<max_qp+1; q++){
int shift = div6[q] + 2; int shift = div6[q] + 2;
int idx = rem6[q]; int idx = rem6[q];
for(x=0; x<16; x++) for(x=0; x<16; x++)
...@@ -893,6 +895,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ ...@@ -893,6 +895,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){
ff_h264_decode_init_vlc(); ff_h264_decode_init_vlc();
h->pixel_shift = 0; h->pixel_shift = 0;
h->sps.bit_depth_luma = 8;
h->thread_context[0] = h; h->thread_context[0] = h;
h->outputed_poc = INT_MIN; h->outputed_poc = INT_MIN;
...@@ -1387,7 +1390,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i ...@@ -1387,7 +1390,7 @@ static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple, i
for(i=16; i<16+8; i++){ for(i=16; i<16+8; i++){
if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){
uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i]; 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);
} }
} }
} }
...@@ -2185,7 +2188,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ ...@@ -2185,7 +2188,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
h->last_qscale_diff = 0; h->last_qscale_diff = 0;
tmp = h->pps.init_qp + get_se_golomb(&s->gb); 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); av_log(s->avctx, AV_LOG_ERROR, "QP %u out of range\n", tmp);
return -1; return -1;
} }
......
...@@ -108,6 +108,7 @@ ...@@ -108,6 +108,7 @@
*/ */
#define DELAYED_PIC_REF 4 #define DELAYED_PIC_REF 4
#define QP_MAX_NUM (51 + 2*6) // The maximum supported qp
/* NAL unit types */ /* NAL unit types */
enum { enum {
...@@ -354,8 +355,8 @@ typedef struct H264Context{ ...@@ -354,8 +355,8 @@ typedef struct H264Context{
*/ */
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? 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 dequant4_buffer[6][QP_MAX_NUM+1][16]; //FIXME should these be moved down?
uint32_t dequant8_buffer[2][52][64]; uint32_t dequant8_buffer[2][QP_MAX_NUM+1][64];
uint32_t (*dequant4_coeff[6])[16]; uint32_t (*dequant4_coeff[6])[16];
uint32_t (*dequant8_coeff[2])[64]; uint32_t (*dequant8_coeff[2])[64];
...@@ -601,7 +602,7 @@ typedef struct H264Context{ ...@@ -601,7 +602,7 @@ typedef struct H264Context{
}H264Context; }H264Context;
extern const uint8_t ff_h264_chroma_qp[52]; extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
/** /**
* Decode SEI * Decode SEI
......
...@@ -689,13 +689,14 @@ void ff_h264_init_cabac_states(H264Context *h) { ...@@ -689,13 +689,14 @@ void ff_h264_init_cabac_states(H264Context *h) {
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
int i; int i;
const int8_t (*tab)[2]; 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 == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I; if( h->slice_type_nos == AV_PICTURE_TYPE_I ) tab = cabac_context_init_I;
else tab = cabac_context_init_PB[h->cabac_init_idc]; else tab = cabac_context_init_PB[h->cabac_init_idc];
/* calculate pre-state */ /* calculate pre-state */
for( i= 0; i < 460; i++ ) { 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; pre^= pre>>31;
if(pre > 124) if(pre > 124)
...@@ -1631,11 +1632,12 @@ decode_intra_mb: ...@@ -1631,11 +1632,12 @@ decode_intra_mb:
if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){ if(get_cabac_noinline( &h->cabac, &h->cabac_state[60 + (h->last_qscale_diff != 0)])){
int val = 1; int val = 1;
int ctx= 2; 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] ) ) { while( get_cabac_noinline( &h->cabac, &h->cabac_state[60 + ctx] ) ) {
ctx= 3; ctx= 3;
val++; 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); 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; return -1;
} }
...@@ -1647,9 +1649,9 @@ decode_intra_mb: ...@@ -1647,9 +1649,9 @@ decode_intra_mb:
val= -((val + 1)>>1); val= -((val + 1)>>1);
h->last_qscale_diff = val; h->last_qscale_diff = val;
s->qscale += val; s->qscale += val;
if(((unsigned)s->qscale) > 51){ if(((unsigned)s->qscale) > max_qp){
if(s->qscale<0) s->qscale+= 52; if(s->qscale<0) s->qscale+= max_qp+1;
else s->qscale-= 52; else s->qscale-= max_qp+1;
} }
h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale); h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);
h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale); h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);
......
...@@ -922,6 +922,7 @@ decode_intra_mb: ...@@ -922,6 +922,7 @@ decode_intra_mb:
int dquant; int dquant;
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;
const uint8_t *scan, *scan8x8; const uint8_t *scan, *scan8x8;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
if(IS_INTERLACED(mb_type)){ if(IS_INTERLACED(mb_type)){
scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0; scan8x8= s->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
...@@ -935,10 +936,10 @@ decode_intra_mb: ...@@ -935,10 +936,10 @@ decode_intra_mb:
s->qscale += dquant; s->qscale += dquant;
if(((unsigned)s->qscale) > 51){ if(((unsigned)s->qscale) > max_qp){
if(s->qscale<0) s->qscale+= 52; if(s->qscale<0) s->qscale+= max_qp+1;
else s->qscale-= 52; else s->qscale-= max_qp+1;
if(((unsigned)s->qscale) > 51){ 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); 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; return -1;
} }
......
...@@ -57,11 +57,32 @@ static const AVRational pixel_aspect[17]={ ...@@ -57,11 +57,32 @@ static const AVRational pixel_aspect[17]={
{2, 1}, {2, 1},
}; };
const uint8_t ff_h264_chroma_qp[52]={ #define QP(qP,depth) ( (qP)+6*((depth)-8) )
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, #define CHROMA_QP_TABLE_END(d) \
28,29,29,30,31,32,32,33,34,34,35,35,36,36,37,37, QP(0,d), QP(1,d), QP(2,d), QP(3,d), QP(4,d), QP(5,d),\
37,38,38,38,39,39,39,39 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_NUM+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]={ static const uint8_t default_scaling4[2][16]={
...@@ -419,17 +440,19 @@ fail: ...@@ -419,17 +440,19 @@ fail:
} }
static void 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; int i;
for(i = 0; i < 52; i++) const int max_qp = 51 + 6*(depth-8);
pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[av_clip(i + index, 0, 51)]; 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){ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
unsigned int pps_id= get_ue_golomb(&s->gb); unsigned int pps_id= get_ue_golomb(&s->gb);
PPS *pps; PPS *pps;
const int qp_bd_offset = 6*(h->sps.bit_depth_luma-8);
if(pps_id >= MAX_PPS_COUNT) { if(pps_id >= MAX_PPS_COUNT) {
av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); 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){ ...@@ -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_pred= get_bits1(&s->gb);
pps->weighted_bipred_idc= get_bits(&s->gb, 2); pps->weighted_bipred_idc= get_bits(&s->gb, 2);
pps->init_qp= 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; pps->init_qs= get_se_golomb(&s->gb) + 26 + qp_bd_offset;
pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb); pps->chroma_qp_index_offset[0]= get_se_golomb(&s->gb);
pps->deblocking_filter_parameters_present= get_bits1(&s->gb); pps->deblocking_filter_parameters_present= get_bits1(&s->gb);
pps->constrained_intra_pred= 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){ ...@@ -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]; 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, 0, pps->chroma_qp_index_offset[0], h->sps.bit_depth_luma);
build_qp_table(pps, 1, pps->chroma_qp_index_offset[1]); 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]) if(pps->chroma_qp_index_offset[0] != pps->chroma_qp_index_offset[1])
pps->chroma_qp_diff= 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