summaryrefslogtreecommitdiff
path: root/src/libffmpeg/libavcodec/h264.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libffmpeg/libavcodec/h264.c')
-rw-r--r--src/libffmpeg/libavcodec/h264.c311
1 files changed, 203 insertions, 108 deletions
diff --git a/src/libffmpeg/libavcodec/h264.c b/src/libffmpeg/libavcodec/h264.c
index 10baf2709..5897738ac 100644
--- a/src/libffmpeg/libavcodec/h264.c
+++ b/src/libffmpeg/libavcodec/h264.c
@@ -348,6 +348,8 @@ typedef struct H264Context{
uint8_t field_scan[16];
const uint8_t *zigzag_scan_q0;
const uint8_t *field_scan_q0;
+
+ int x264_build;
}H264Context;
static VLC coeff_token_vlc[4];
@@ -1205,6 +1207,7 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
const int b4_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride;
const int mb_type_col = h->ref_list[1][0].mb_type[mb_xy];
const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[0][b4_xy];
+ const int16_t (*l1mv1)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[1][b4_xy];
const int8_t *l1ref0 = &h->ref_list[1][0].ref_index[0][b8_xy];
const int8_t *l1ref1 = &h->ref_list[1][0].ref_index[1][b8_xy];
const int is_b8x8 = IS_8X8(*mb_type);
@@ -1273,8 +1276,10 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
if(IS_16X16(*mb_type)){
fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref[0], 1);
fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, ref[1], 1);
- if(!IS_INTRA(mb_type_col) && l1ref0[0] == 0 &&
- ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1){
+ if(!IS_INTRA(mb_type_col)
+ && ( (l1ref0[0] == 0 && ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1)
+ || (l1ref0[0] < 0 && l1ref1[0] == 0 && ABS(l1mv1[0][0]) <= 1 && ABS(l1mv1[0][1]) <= 1
+ && (h->x264_build>33 || !h->x264_build)))){
if(ref[0] > 0)
fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4);
else
@@ -1302,9 +1307,12 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, ref[1], 1);
/* col_zero_flag */
- if(!IS_INTRA(mb_type_col) && l1ref0[x8 + y8*h->b8_stride] == 0){
+ if(!IS_INTRA(mb_type_col) && ( l1ref0[x8 + y8*h->b8_stride] == 0
+ || (l1ref0[x8 + y8*h->b8_stride] < 0 && l1ref1[x8 + y8*h->b8_stride] == 0
+ && (h->x264_build>33 || !h->x264_build)))){
+ const int16_t (*l1mv)[2]= l1ref0[x8 + y8*h->b8_stride] == 0 ? l1mv0 : l1mv1;
for(i4=0; i4<4; i4++){
- const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];
+ const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];
if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){
if(ref[0] == 0)
*(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0;
@@ -1326,7 +1334,7 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
const int ref0 = l1ref0[0] >= 0 ? h->map_col_to_list0[0][l1ref0[0]]
: h->map_col_to_list0[1][l1ref1[0]];
const int dist_scale_factor = h->dist_scale_factor[ref0];
- const int16_t *mv_col = l1mv0[0];
+ const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
int mv_l0[2];
mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8;
mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8;
@@ -1339,7 +1347,8 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
const int x8 = i8&1;
const int y8 = i8>>1;
int ref0, dist_scale_factor;
-
+ const int16_t (*l1mv)[2]= l1mv0;
+
if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8]))
continue;
h->sub_mb_type[i8] = sub_mb_type;
@@ -1354,14 +1363,16 @@ static inline void pred_direct_motion(H264Context * const h, int *mb_type){
ref0 = l1ref0[x8 + y8*h->b8_stride];
if(ref0 >= 0)
ref0 = h->map_col_to_list0[0][ref0];
- else
+ else{
ref0 = h->map_col_to_list0[1][l1ref1[x8 + y8*h->b8_stride]];
+ l1mv= l1mv1;
+ }
dist_scale_factor = h->dist_scale_factor[ref0];
fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1);
fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1);
for(i4=0; i4<4; i4++){
- const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];
+ const int16_t *mv_col = l1mv[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride];
int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]];
mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8;
mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8;
@@ -2316,7 +2327,7 @@ static void pred8x8_plane_c(uint8_t *src, int stride){
const int l0 = ((has_topleft ? SRC(-1,-1) : SRC(-1,0)) \
+ 2*SRC(-1,0) + SRC(-1,1) + 2) >> 2; \
PL(1) PL(2) PL(3) PL(4) PL(5) PL(6) \
- const int l7 = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2
+ const int l7 attribute_unused = (SRC(-1,6) + 3*SRC(-1,7) + 2) >> 2
#define PT(x) \
const int t##x = (SRC(x-1,-1) + 2*SRC(x,-1) + SRC(x+1,-1) + 2) >> 2;
@@ -2324,7 +2335,7 @@ static void pred8x8_plane_c(uint8_t *src, int stride){
const int t0 = ((has_topleft ? SRC(-1,-1) : SRC(0,-1)) \
+ 2*SRC(0,-1) + SRC(1,-1) + 2) >> 2; \
PT(1) PT(2) PT(3) PT(4) PT(5) PT(6) \
- const int t7 = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \
+ const int t7 attribute_unused = ((has_topright ? SRC(8,-1) : SRC(7,-1)) \
+ 2*SRC(7,-1) + SRC(6,-1) + 2) >> 2
#define PTR(x) \
@@ -2567,6 +2578,8 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
int emu=0;
const int full_mx= mx>>2;
const int full_my= my>>2;
+ const int pic_width = 16*s->mb_width;
+ const int pic_height = 16*s->mb_height;
assert(pic->data[0]);
@@ -2575,9 +2588,9 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
if( full_mx < 0-extra_width
|| full_my < 0-extra_height
- || full_mx + 16/*FIXME*/ > s->width + extra_width
- || full_my + 16/*FIXME*/ > s->height + extra_height){
- ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, s->width, s->height);
+ || full_mx + 16/*FIXME*/ > pic_width + extra_width
+ || full_my + 16/*FIXME*/ > pic_height + extra_height){
+ ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);
src_y= s->edge_emu_buffer + 2 + 2*s->linesize;
emu=1;
}
@@ -2590,13 +2603,13 @@ static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square,
if(s->flags&CODEC_FLAG_GRAY) return;
if(emu){
- ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
+ ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
src_cb= s->edge_emu_buffer;
}
chroma_op(dest_cb, src_cb, s->uvlinesize, chroma_height, mx&7, my&7);
if(emu){
- ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), s->width>>1, s->height>>1);
+ ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);
src_cr= s->edge_emu_buffer;
}
chroma_op(dest_cr, src_cr, s->uvlinesize, chroma_height, mx&7, my&7);
@@ -3108,7 +3121,7 @@ b= t;
if(deblock_top){
XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg);
XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1);
- if(s->mb_x < s->mb_width){
+ if(s->mb_x+1 < s->mb_width){
XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1);
}
}
@@ -3988,7 +4001,7 @@ static int decode_ref_pic_marking(H264Context *h){
if(opcode==MMCO_SHORT2UNUSED || opcode==MMCO_SHORT2LONG){
h->mmco[i].short_frame_num= (h->frame_num - get_ue_golomb(&s->gb) - 1) & ((1<<h->sps.log2_max_frame_num)-1); //FIXME fields
/* if(h->mmco[i].short_frame_num >= h->short_ref_count || h->short_ref[ h->mmco[i].short_frame_num ] == NULL){
- fprintf(stderr, "illegal short ref in memory management control operation %d\n", mmco);
+ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control operation %d\n", mmco);
return -1;
}*/
}
@@ -4424,8 +4437,8 @@ static inline int get_dct8x8_allowed(H264Context *h){
static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, int n, const uint8_t *scantable, const uint16_t *qmul, int max_coeff){
MpegEncContext * const s = &h->s;
static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
- int level[16], run[16];
- int suffix_length, zeros_left, coeff_num, coeff_token, total_coeff, i, trailing_ones;
+ int level[16];
+ int zeros_left, coeff_num, coeff_token, total_coeff, i, j, trailing_ones, run_before;
//FIXME put trailing_onex into the context
@@ -4458,12 +4471,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
level[i]= 1 - 2*get_bits1(gb);
}
- suffix_length= total_coeff > 10 && trailing_ones < 3;
-
- for(; i<total_coeff; i++){
- const int prefix= get_level_prefix(gb);
+ if(i<total_coeff) {
int level_code, mask;
+ int suffix_length = total_coeff > 10 && trailing_ones < 3;
+ int prefix= get_level_prefix(gb);
+ //first coefficient has suffix_length equal to 0 or 1
if(prefix<14){ //FIXME try to build a large unified VLC table for all this
if(suffix_length)
level_code= (prefix<<suffix_length) + get_bits(gb, suffix_length); //part
@@ -4482,20 +4495,32 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
return -1;
}
- if(i==trailing_ones && i<3) level_code+= 2; //FIXME split first iteration
+ if(trailing_ones < 3) level_code += 2;
+ suffix_length = 1;
+ if(level_code > 5)
+ suffix_length++;
mask= -(level_code&1);
level[i]= (((2+level_code)>>1) ^ mask) - mask;
-
- if(suffix_length==0) suffix_length=1; //FIXME split first iteration
-
-#if 1
- if(ABS(level[i]) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++;
-#else
- if((2+level_code)>>1) > (3<<(suffix_length-1)) && suffix_length<6) suffix_length++;
- /* ? == prefix > 2 or sth */
-#endif
- tprintf("level: %d suffix_length:%d\n", level[i], suffix_length);
+ i++;
+
+ //remaining coefficients have suffix_length > 0
+ for(;i<total_coeff;i++) {
+ static const int suffix_limit[7] = {0,5,11,23,47,95,INT_MAX };
+ prefix = get_level_prefix(gb);
+ if(prefix<15){
+ level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length);
+ }else if(prefix==15){
+ level_code = (prefix<<suffix_length) + get_bits(gb, 12);
+ }else{
+ av_log(h->s.avctx, AV_LOG_ERROR, "prefix too large at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ mask= -(level_code&1);
+ level[i]= (((2+level_code)>>1) ^ mask) - mask;
+ if(level_code > suffix_limit[suffix_length])
+ suffix_length++;
+ }
}
if(total_coeff == max_coeff)
@@ -4506,50 +4531,49 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
else
zeros_left= get_vlc2(gb, total_zeros_vlc[ total_coeff-1 ].table, TOTAL_ZEROS_VLC_BITS, 1);
}
-
- for(i=0; i<total_coeff-1; i++){
- if(zeros_left <=0)
- break;
- else if(zeros_left < 7){
- run[i]= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1);
- }else{
- run[i]= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
- }
- zeros_left -= run[i];
- }
- if(zeros_left<0){
- av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- for(; i<total_coeff-1; i++){
- run[i]= 0;
- }
-
- run[i]= zeros_left;
-
- coeff_num=-1;
+ coeff_num = zeros_left + total_coeff - 1;
+ j = scantable[coeff_num];
if(n > 24){
- for(i=total_coeff-1; i>=0; i--){ //FIXME merge into rundecode?
- int j;
-
- coeff_num += run[i] + 1; //FIXME add 1 earlier ?
+ block[j] = level[0];
+ for(i=1;i<total_coeff;i++) {
+ if(zeros_left <= 0)
+ run_before = 0;
+ else if(zeros_left < 7){
+ run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1);
+ }else{
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
+ }
+ zeros_left -= run_before;
+ coeff_num -= 1 + run_before;
j= scantable[ coeff_num ];
block[j]= level[i];
}
}else{
- for(i=total_coeff-1; i>=0; i--){ //FIXME merge into rundecode?
- int j;
-
- coeff_num += run[i] + 1; //FIXME add 1 earlier ?
+ block[j] = level[0] * qmul[j];
+ for(i=1;i<total_coeff;i++) {
+ if(zeros_left <= 0)
+ run_before = 0;
+ else if(zeros_left < 7){
+ run_before= get_vlc2(gb, run_vlc[zeros_left-1].table, RUN_VLC_BITS, 1);
+ }else{
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2);
+ }
+ zeros_left -= run_before;
+ coeff_num -= 1 + run_before;
j= scantable[ coeff_num ];
block[j]= level[i] * qmul[j];
// printf("%d %d ", block[j], qmul[j]);
}
}
+
+ if(zeros_left<0){
+ av_log(h->s.avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
return 0;
}
@@ -5352,6 +5376,8 @@ static int decode_cabac_mb_dqp( H264Context *h) {
else
ctx = 3;
val++;
+ if(val > 52) //prevent infinite loop
+ return INT_MIN;
}
if( val&0x01 )
@@ -5491,9 +5517,6 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
static const int significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 297 };
static const int last_significant_coeff_flag_offset[6] = { 0, 15, 29, 44, 47, 251 };
static const int coeff_abs_level_m1_offset[6] = { 227+0, 227+10, 227+20, 227+30, 227+39, 426 };
- static const int identity[15] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
- };
static const int significant_coeff_flag_offset_8x8[63] = {
0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
@@ -5515,12 +5538,9 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
int abslevel1 = 1;
int abslevelgt1 = 0;
- const int* significant_coeff_ctx_offset;
- const int* last_coeff_ctx_offset;
- const int significant_coeff_ctx_base = significant_coeff_flag_offset[cat]
- + significant_coeff_flag_field_offset[h->mb_field_decoding_flag];
- const int last_coeff_ctx_base = last_significant_coeff_flag_offset[cat]
- + last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag];
+ uint8_t *significant_coeff_ctx_base;
+ uint8_t *last_coeff_ctx_base;
+ uint8_t *abs_level_m1_ctx_base;
/* cat: 0-> DC 16x16 n = 0
* 1-> AC 16x16 n = luma4x4idx
@@ -5531,10 +5551,7 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
*/
/* read coded block flag */
- if( cat == 5 ) {
- significant_coeff_ctx_offset = significant_coeff_flag_offset_8x8;
- last_coeff_ctx_offset = last_coeff_flag_offset_8x8;
- } else {
+ if( cat != 5 ) {
if( get_cabac( &h->cabac, &h->cabac_state[85 + get_cabac_cbf_ctx( h, cat, n ) ] ) == 0 ) {
if( cat == 1 || cat == 2 )
h->non_zero_count_cache[scan8[n]] = 0;
@@ -5543,21 +5560,34 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
return 0;
}
-
- significant_coeff_ctx_offset =
- last_coeff_ctx_offset = identity;
}
- for(last= 0; last < max_coeff - 1; last++) {
- int sig_ctx = significant_coeff_ctx_base + significant_coeff_ctx_offset[last];
- if( get_cabac( &h->cabac, &h->cabac_state[sig_ctx] )) {
- int last_ctx = last_coeff_ctx_base + last_coeff_ctx_offset[last];
- index[coeff_count++] = last;
- if( get_cabac( &h->cabac, &h->cabac_state[last_ctx] ) ) {
- last= max_coeff;
- break;
- }
- }
+ significant_coeff_ctx_base = h->cabac_state
+ + significant_coeff_flag_offset[cat]
+ + significant_coeff_flag_field_offset[h->mb_field_decoding_flag];
+ last_coeff_ctx_base = h->cabac_state
+ + last_significant_coeff_flag_offset[cat]
+ + last_significant_coeff_flag_field_offset[h->mb_field_decoding_flag];
+ abs_level_m1_ctx_base = h->cabac_state
+ + coeff_abs_level_m1_offset[cat];
+
+ if( cat == 5 ) {
+#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \
+ for(last= 0; last < coefs; last++) { \
+ uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \
+ if( get_cabac( &h->cabac, sig_ctx )) { \
+ uint8_t *last_ctx = last_coeff_ctx_base + last_off; \
+ index[coeff_count++] = last; \
+ if( get_cabac( &h->cabac, last_ctx ) ) { \
+ last= max_coeff; \
+ break; \
+ } \
+ } \
+ }
+ DECODE_SIGNIFICANCE( 63, significant_coeff_flag_offset_8x8[last],
+ last_coeff_flag_offset_8x8[last] );
+ } else {
+ DECODE_SIGNIFICANCE( max_coeff - 1, last, last );
}
if( last == max_coeff -1 ) {
index[coeff_count++] = last;
@@ -5578,11 +5608,11 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
}
for( i = coeff_count - 1; i >= 0; i-- ) {
- int ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + coeff_abs_level_m1_offset[cat];
+ uint8_t *ctx = (abslevelgt1 != 0 ? 0 : FFMIN( 4, abslevel1 )) + abs_level_m1_ctx_base;
int j= scantable[index[i]];
- if( get_cabac( &h->cabac, &h->cabac_state[ctx] ) == 0 ) {
- if( cat == 0 || cat == 3 ) {
+ if( get_cabac( &h->cabac, ctx ) == 0 ) {
+ if( !qmul ) {
if( get_cabac_bypass( &h->cabac ) ) block[j] = -1;
else block[j] = 1;
}else{
@@ -5593,8 +5623,8 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
abslevel1++;
} else {
int coeff_abs = 2;
- ctx = 5 + FFMIN( 4, abslevelgt1 ) + coeff_abs_level_m1_offset[cat];
- while( coeff_abs < 15 && get_cabac( &h->cabac, &h->cabac_state[ctx] ) ) {
+ ctx = 5 + FFMIN( 4, abslevelgt1 ) + abs_level_m1_ctx_base;
+ while( coeff_abs < 15 && get_cabac( &h->cabac, ctx ) ) {
coeff_abs++;
}
@@ -5611,7 +5641,7 @@ static int inline decode_cabac_residual( H264Context *h, DCTELEM *block, int cat
}
}
- if( cat == 0 || cat == 3 ) {
+ if( !qmul ) {
if( get_cabac_bypass( &h->cabac ) ) block[j] = -coeff_abs;
else block[j] = coeff_abs;
}else{
@@ -6029,6 +6059,10 @@ decode_intra_mb:
}
h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h );
+ if( dqp == INT_MIN ){
+ 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;
+ }
s->qscale += dqp;
if(((unsigned)s->qscale) > 51){
if(s->qscale<0) s->qscale+= 52;
@@ -6039,7 +6073,7 @@ decode_intra_mb:
if( IS_INTRA16x16( mb_type ) ) {
int i;
//av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" );
- if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, h->dequant4_coeff[s->qscale], 16) < 0)
+ if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0)
return -1;
if( cbp&15 ) {
for( i = 0; i < 16; i++ ) {
@@ -6081,7 +6115,7 @@ decode_intra_mb:
int c;
for( c = 0; c < 2; c++ ) {
//av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );
- if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, h->dequant4_coeff[h->chroma_qp], 4) < 0)
+ if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0)
return -1;
}
}
@@ -6177,7 +6211,7 @@ static void filter_mb_edgev( H264Context *h, uint8_t *pix, int stride, int bS[4]
}
}
static void filter_mb_edgecv( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
- int i, d;
+ int i;
const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
const int alpha = alpha_table[index_a];
const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
@@ -6407,7 +6441,7 @@ static void filter_mb_edgeh( H264Context *h, uint8_t *pix, int stride, int bS[4]
}
static void filter_mb_edgech( H264Context *h, uint8_t *pix, int stride, int bS[4], int qp ) {
- int i, d;
+ int i;
const int index_a = clip( qp + h->slice_alpha_c0_offset, 0, 51 );
const int alpha = alpha_table[index_a];
const int beta = beta_table[clip( qp + h->slice_beta_offset, 0, 51 )];
@@ -6537,7 +6571,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
bS[0] = bS[1] = bS[2] = bS[3] = 3;
} else {
// TODO
- assert(0);
+ av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n");
}
/* Filter edge */
// Do not use s->qscale as luma quantizer because it has not the same
@@ -6558,7 +6592,7 @@ static void filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8
bS[0] = bS[1] = bS[2] = bS[3] = 3;
} else {
// TODO
- assert(0);
+ av_log(h->s.avctx, AV_LOG_ERROR, "both non intra (TODO)\n");
}
/* Filter edge */
// Do not use s->qscale as luma quantizer because it has not the same
@@ -6690,7 +6724,7 @@ static int decode_slice(H264Context *h){
if(ret>=0) ret = decode_mb_cabac(h);
- hl_decode_mb(h);
+ if(ret>=0) hl_decode_mb(h);
s->mb_y--;
}
eos = get_cabac_terminate( &h->cabac );
@@ -6823,6 +6857,64 @@ static int decode_slice(H264Context *h){
return -1; //not reached
}
+static int decode_unregistered_user_data(H264Context *h, int size){
+ MpegEncContext * const s = &h->s;
+ uint8_t user_data[16+256];
+ int e, build, i;
+
+ if(size<16)
+ return -1;
+
+ for(i=0; i<sizeof(user_data)-1 && i<size; i++){
+ user_data[i]= get_bits(&s->gb, 8);
+ }
+
+ user_data[i]= 0;
+ e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
+ if(e==1 && build>=0)
+ h->x264_build= build;
+
+ if(s->avctx->debug & FF_DEBUG_BUGS)
+ av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16);
+
+ for(; i<size; i++)
+ skip_bits(&s->gb, 8);
+
+ return 0;
+}
+
+static int decode_sei(H264Context *h){
+ MpegEncContext * const s = &h->s;
+
+ while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){
+ int size, type;
+
+ type=0;
+ do{
+ type+= show_bits(&s->gb, 8);
+ }while(get_bits(&s->gb, 8) == 255);
+
+ size=0;
+ do{
+ size+= show_bits(&s->gb, 8);
+ }while(get_bits(&s->gb, 8) == 255);
+
+ switch(type){
+ case 5:
+ if(decode_unregistered_user_data(h, size) < 0);
+ return -1;
+ break;
+ default:
+ skip_bits(&s->gb, 8*size);
+ }
+
+ //FIXME check bits here
+ align_get_bits(&s->gb);
+ }
+
+ return 0;
+}
+
static inline void decode_hrd_parameters(H264Context *h, SPS *sps){
MpegEncContext * const s = &h->s;
int cpb_count, i;
@@ -7206,8 +7298,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
int buf_index=0;
#if 0
int i;
- for(i=0; i<32; i++){
- printf("%X ", buf[i]);
+ for(i=0; i<50; i++){
+ av_log(NULL, AV_LOG_ERROR,"%02X ", buf[i]);
}
#endif
h->slice_num = 0;
@@ -7250,7 +7342,7 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
buf_index += consumed;
- if( (s->hurry_up == 1 && h->nal_ref_idc == 0)
+ if( (s->hurry_up == 1 && h->nal_ref_idc == 0) //FIXME dont discard SEI id
||(avctx->skip_frame >= AVDISCARD_NONREF && h->nal_ref_idc == 0))
continue;
@@ -7301,6 +7393,8 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
decode_slice(h);
break;
case NAL_SEI:
+ init_get_bits(&s->gb, ptr, bit_length);
+ decode_sei(h);
break;
case NAL_SPS:
init_get_bits(&s->gb, ptr, bit_length);
@@ -7409,7 +7503,7 @@ static int decode_frame(AVCodecContext *avctx,
p += 6;
for (i = 0; i < cnt; i++) {
nalsize = BE_16(p) + 2;
- if(decode_nal_units(h, p, nalsize) != nalsize) {
+ if(decode_nal_units(h, p, nalsize) < 0) {
av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i);
return -1;
}
@@ -7728,6 +7822,7 @@ static int decode_end(AVCodecContext *avctx)
H264Context *h = avctx->priv_data;
MpegEncContext *s = &h->s;
+ av_freep(&h->rbsp_buffer);
free_tables(h); //FIXME cleanup init stuff perhaps
MPV_common_end(s);