#endif
}
-const uint8_t ff_rem6[52]={
+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,
};
-const uint8_t ff_div6[52]={
+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,
};
if(for_deblock){
topleft_type = 0;
topright_type = 0;
- top_type = h->slice_table[top_xy ] < 255 ? s->current_picture.mb_type[top_xy] : 0;
- left_type[0] = h->slice_table[left_xy[0] ] < 255 ? s->current_picture.mb_type[left_xy[0]] : 0;
- left_type[1] = h->slice_table[left_xy[1] ] < 255 ? s->current_picture.mb_type[left_xy[1]] : 0;
+ top_type = h->slice_table[top_xy ] < 0xFFFF ? s->current_picture.mb_type[top_xy] : 0;
+ left_type[0] = h->slice_table[left_xy[0] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[0]] : 0;
+ left_type[1] = h->slice_table[left_xy[1] ] < 0xFFFF ? s->current_picture.mb_type[left_xy[1]] : 0;
- if(FRAME_MBAFF && !IS_INTRA(mb_type)){
+ if(MB_MBAFF && !IS_INTRA(mb_type)){
int list;
- int v = *(uint16_t*)&h->non_zero_count[mb_xy][14];
- for(i=0; i<16; i++)
- h->non_zero_count_cache[scan8[i]] = (v>>i)&1;
for(list=0; list<h->list_count; list++){
+ //These values where changed for ease of performing MC, we need to change them back
+ //FIXME maybe we can make MC and loop filter use the same values or prevent
+ //the MC code from changing ref_cache and rather use a temporary array.
if(USES_LIST(mb_type,list)){
- uint32_t *src = (uint32_t*)s->current_picture.motion_val[list][h->mb2b_xy[mb_xy]];
- uint32_t *dst = (uint32_t*)h->mv_cache[list][scan8[0]];
int8_t *ref = &s->current_picture.ref_index[list][h->mb2b8_xy[mb_xy]];
- for(i=0; i<4; i++, dst+=8, src+=h->b_stride){
- dst[0] = src[0];
- dst[1] = src[1];
- dst[2] = src[2];
- dst[3] = src[3];
- }
*(uint32_t*)&h->ref_cache[list][scan8[ 0]] =
- *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = pack16to32(ref[0],ref[1])*0x0101;
+ *(uint32_t*)&h->ref_cache[list][scan8[ 2]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
ref += h->b8_stride;
*(uint32_t*)&h->ref_cache[list][scan8[ 8]] =
- *(uint32_t*)&h->ref_cache[list][scan8[10]] = pack16to32(ref[0],ref[1])*0x0101;
- }else{
- fill_rectangle(&h-> mv_cache[list][scan8[ 0]], 4, 4, 8, 0, 4);
- fill_rectangle(&h->ref_cache[list][scan8[ 0]], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1);
+ *(uint32_t*)&h->ref_cache[list][scan8[10]] = (pack16to32(ref[0],ref[1])&0x00FF00FF)*0x0101;
}
}
}
topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;
left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;
left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;
- }
if(IS_INTRA(mb_type)){
+ int type_mask= h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
h->topleft_samples_available=
h->top_samples_available=
h->left_samples_available= 0xFFFF;
h->topright_samples_available= 0xEEEA;
- if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){
+ if(!(top_type & type_mask)){
h->topleft_samples_available= 0xB3FF;
h->top_samples_available= 0x33FF;
h->topright_samples_available= 0x26EA;
}
- for(i=0; i<2; i++){
- if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){
+ if(IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[0])){
+ if(IS_INTERLACED(mb_type)){
+ if(!(left_type[0] & type_mask)){
+ h->topleft_samples_available&= 0xDFFF;
+ h->left_samples_available&= 0x5FFF;
+ }
+ if(!(left_type[1] & type_mask)){
+ h->topleft_samples_available&= 0xFF5F;
+ h->left_samples_available&= 0xFF5F;
+ }
+ }else{
+ int left_typei = h->slice_table[left_xy[0] + s->mb_stride ] == h->slice_num
+ ? s->current_picture.mb_type[left_xy[0] + s->mb_stride] : 0;
+ assert(left_xy[0] == left_xy[1]);
+ if(!((left_typei & type_mask) && (left_type[0] & type_mask))){
+ h->topleft_samples_available&= 0xDF5F;
+ h->left_samples_available&= 0x5F5F;
+ }
+ }
+ }else{
+ if(!(left_type[0] & type_mask)){
h->topleft_samples_available&= 0xDF5F;
h->left_samples_available&= 0x5F5F;
}
}
- if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred))
+ if(!(topleft_type & type_mask))
h->topleft_samples_available&= 0x7FFF;
- if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred))
+ if(!(topright_type & type_mask))
h->topright_samples_available&= 0xFBFF;
if(IS_INTRA4x4(mb_type)){
h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];
}else{
int pred;
- if(!top_type || (IS_INTER(top_type) && h->pps.constrained_intra_pred))
+ if(!(top_type & type_mask))
pred= -1;
else{
pred= 2;
h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];
}else{
int pred;
- if(!left_type[i] || (IS_INTER(left_type[i]) && h->pps.constrained_intra_pred))
+ if(!(left_type[i] & type_mask))
pred= -1;
else{
pred= 2;
}
}
}
+ }
/*
}
}
- if((for_deblock || (IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred)) && !FRAME_MBAFF)
+ if(for_deblock || ((IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred) && !FRAME_MBAFF))
continue;
if(USES_LIST(topleft_type, list)){
}
}
- if(!(h->left_samples_available&0x8000)){
+ if((h->left_samples_available&0x8888)!=0x8888){
+ static const int mask[4]={0x8000,0x2000,0x80,0x20};
for(i=0; i<4; i++){
+ if(!(h->left_samples_available&mask[i])){
int status= left[ h->intra4x4_pred_mode_cache[scan8[0] + 8*i] ];
if(status<0){
av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra4x4 mode %d at %d %d\n", status, s->mb_x, s->mb_y);
} else if(status){
h->intra4x4_pred_mode_cache[scan8[0] + 8*i]= status;
}
+ }
}
}
}
}
- if(!(h->left_samples_available&0x8000)){
+ if((h->left_samples_available&0x8080) != 0x8080){
mode= left[ mode ];
+ if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred
+ mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8);
+ }
if(mode<0){
av_log(h->s.avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", s->mb_x, s->mb_y);
return -1;
h->non_zero_count[mb_xy][12]=h->non_zero_count_cache[1+8*5];
h->non_zero_count[mb_xy][11]=h->non_zero_count_cache[2+8*5];
h->non_zero_count[mb_xy][10]=h->non_zero_count_cache[2+8*4];
-
- if(FRAME_MBAFF){
- // store all luma nnzs, for deblocking
- int v = 0, i;
- for(i=0; i<16; i++)
- v += (!!h->non_zero_count_cache[scan8[i]]) << i;
- *(uint16_t*)&h->non_zero_count[mb_xy][14] = v;
- }
}
/**
return;
}
+static int get_scale_factor(H264Context * const h, int poc, int poc1, int i){
+ int poc0 = h->ref_list[0][i].poc;
+ int td = av_clip(poc1 - poc0, -128, 127);
+ if(td == 0 || h->ref_list[0][i].long_ref){
+ return 256;
+ }else{
+ int tb = av_clip(poc - poc0, -128, 127);
+ int tx = (16384 + (FFABS(td) >> 1)) / td;
+ return av_clip((tb*tx + 32) >> 6, -1024, 1023);
+ }
+}
+
static inline void direct_dist_scale_factor(H264Context * const h){
MpegEncContext * const s = &h->s;
const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure == PICT_BOTTOM_FIELD ];
const int poc1 = h->ref_list[1][0].poc;
- int i;
+ int i, field;
+ for(field=0; field<2; field++){
+ const int poc = h->s.current_picture_ptr->field_poc[field];
+ const int poc1 = h->ref_list[1][0].field_poc[field];
+ for(i=0; i < 2*h->ref_count[0]; i++)
+ h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, poc, poc1, i+16);
+ }
+
for(i=0; i<h->ref_count[0]; i++){
- int poc0 = h->ref_list[0][i].poc;
- int td = av_clip(poc1 - poc0, -128, 127);
- if(td == 0 || h->ref_list[0][i].long_ref){
- h->dist_scale_factor[i] = 256;
- }else{
- int tb = av_clip(poc - poc0, -128, 127);
- int tx = (16384 + (FFABS(td) >> 1)) / td;
- h->dist_scale_factor[i] = av_clip((tb*tx + 32) >> 6, -1024, 1023);
- }
+ h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
}
- if(FRAME_MBAFF){
- for(i=0; i<h->ref_count[0]; i++){
- h->dist_scale_factor_field[2*i] =
- h->dist_scale_factor_field[2*i+1] = h->dist_scale_factor[i];
+}
+
+static void fill_colmap(H264Context *h, int map[2][16+32], int list, int field, int colfield, int mbafi){
+ MpegEncContext * const s = &h->s;
+ Picture * const ref1 = &h->ref_list[1][0];
+ int j, old_ref, rfield;
+ int start= mbafi ? 16 : 0;
+ int end = mbafi ? 16+2*h->ref_count[list] : h->ref_count[list];
+ int interl= mbafi || s->picture_structure != PICT_FRAME;
+
+ /* bogus; fills in for missing frames */
+ memset(map[list], 0, sizeof(map[list]));
+
+ for(rfield=0; rfield<2; rfield++){
+ for(old_ref=0; old_ref<ref1->ref_count[colfield][list]; old_ref++){
+ int poc = ref1->ref_poc[colfield][list][old_ref];
+
+ if (!interl)
+ poc |= 3;
+ else if( interl && (poc&3) == 3) //FIXME store all MBAFF references so this isnt needed
+ poc= (poc&~3) + rfield + 1;
+
+ for(j=start; j<end; j++){
+ if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){
+ int cur_ref= mbafi ? (j-16)^field : j;
+ map[list][2*old_ref + (rfield^field) + 16] = cur_ref;
+ if(rfield == field)
+ map[list][old_ref] = cur_ref;
+ break;
+ }
+ }
}
}
}
+
static inline void direct_ref_list_init(H264Context * const h){
MpegEncContext * const s = &h->s;
Picture * const ref1 = &h->ref_list[1][0];
Picture * const cur = s->current_picture_ptr;
- int list, i, j;
- int sidx= s->picture_structure&1;
- int ref1sidx= ref1->reference&1;
+ int list, j, field;
+ int sidx= (s->picture_structure&1)^1;
+ int ref1sidx= (ref1->reference&1)^1;
+
for(list=0; list<2; list++){
cur->ref_count[sidx][list] = h->ref_count[list];
for(j=0; j<h->ref_count[list]; j++)
cur->ref_poc[sidx][list][j] = 4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3);
}
+
if(s->picture_structure == PICT_FRAME){
- memcpy(cur->ref_count[0], cur->ref_count[1], sizeof(cur->ref_count[0]));
- memcpy(cur->ref_poc [0], cur->ref_poc [1], sizeof(cur->ref_poc [0]));
+ memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
+ memcpy(cur->ref_poc [1], cur->ref_poc [0], sizeof(cur->ref_poc [0]));
}
+
+ cur->mbaff= FRAME_MBAFF;
+
if(cur->pict_type != FF_B_TYPE || h->direct_spatial_mv_pred)
return;
+
for(list=0; list<2; list++){
- for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){
- int poc = ref1->ref_poc[ref1sidx][list][i];
- if(((poc&3) == 3) != (s->picture_structure == PICT_FRAME))
- poc= (poc&~3) + s->picture_structure;
- h->map_col_to_list0[list][i] = 0; /* bogus; fills in for missing frames */
- for(j=0; j<h->ref_count[list]; j++)
- if(4*h->ref_list[list][j].frame_num + (h->ref_list[list][j].reference&3) == poc){
- h->map_col_to_list0[list][i] = j;
- break;
- }
- }
- }
- if(FRAME_MBAFF){
- for(list=0; list<2; list++){
- for(i=0; i<ref1->ref_count[ref1sidx][list]; i++){
- j = h->map_col_to_list0[list][i];
- h->map_col_to_list0_field[list][2*i] = 2*j;
- h->map_col_to_list0_field[list][2*i+1] = 2*j+1;
- }
- }
+ fill_colmap(h, h->map_col_to_list0, list, sidx, ref1sidx, 0);
+ for(field=0; field<2; field++)
+ fill_colmap(h, h->map_col_to_list0_field[field], list, field, field, 1);
}
}
#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16|MB_TYPE_INTRA4x4|MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM)
if(IS_INTERLACED(h->ref_list[1][0].mb_type[mb_xy])){ // AFL/AFR/FR/FL -> AFL/FL
- if(h->ref_list[1][0].reference == PICT_FRAME){ // AFL/AFR/FR/FL -> AFL
- if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL
- int cur_poc = s->current_picture_ptr->poc;
- int *col_poc = h->ref_list[1]->field_poc;
- int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc);
- mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride;
- b8_stride = 0;
- }
- }else if(!(s->picture_structure & h->ref_list[1][0].reference)){// FL -> FL & differ parity
+ if(!IS_INTERLACED(*mb_type)){ // AFR/FR -> AFL/FL
+ int cur_poc = s->current_picture_ptr->poc;
+ int *col_poc = h->ref_list[1]->field_poc;
+ int col_parity = FFABS(col_poc[0] - cur_poc) >= FFABS(col_poc[1] - cur_poc);
+ mb_xy= s->mb_x + ((s->mb_y&~1) + col_parity)*s->mb_stride;
+ b8_stride = 0;
+ }else if(!(s->picture_structure & h->ref_list[1][0].reference) && !h->ref_list[1][0].mbaff){// FL -> FL & differ parity
int fieldoff= 2*(h->ref_list[1][0].reference)-3;
mb_xy += s->mb_stride*fieldoff;
}
}else{ /* direct temporal mv pred */
const int *map_col_to_list0[2] = {h->map_col_to_list0[0], h->map_col_to_list0[1]};
const int *dist_scale_factor = h->dist_scale_factor;
+ int ref_offset= 0;
if(FRAME_MBAFF && IS_INTERLACED(*mb_type)){
- map_col_to_list0[0] = h->map_col_to_list0_field[0];
- map_col_to_list0[1] = h->map_col_to_list0_field[1];
- dist_scale_factor = h->dist_scale_factor_field;
+ map_col_to_list0[0] = h->map_col_to_list0_field[s->mb_y&1][0];
+ map_col_to_list0[1] = h->map_col_to_list0_field[s->mb_y&1][1];
+ dist_scale_factor =h->dist_scale_factor_field[s->mb_y&1];
}
+ if(h->ref_list[1][0].mbaff && IS_INTERLACED(mb_type_col[0]))
+ ref_offset += 16;
+
if(IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])){
/* FIXME assumes direct_8x8_inference == 1 */
int y_shift = 2*!IS_INTERLACED(*mb_type);
- int ref_shift= FRAME_MBAFF ? y_shift : 1;
for(i8=0; i8<4; i8++){
const int x8 = i8&1;
ref0 = l1ref0[x8 + y8*b8_stride];
if(ref0 >= 0)
- ref0 = map_col_to_list0[0][ref0*2>>ref_shift];
+ ref0 = map_col_to_list0[0][ref0 + ref_offset];
else{
- ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]*2>>ref_shift];
+ ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];
l1mv= l1mv1;
}
scale = dist_scale_factor[ref0];
if(IS_INTRA(mb_type_col[0])){
ref=mv0=mv1=0;
}else{
- const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0]]
- : map_col_to_list0[1][l1ref1[0]];
+ const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
+ : map_col_to_list0[1][l1ref1[0] + ref_offset];
const int scale = dist_scale_factor[ref0];
const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
int mv_l0[2];
continue;
}
- ref0 = l1ref0[x8 + y8*b8_stride];
+ ref0 = l1ref0[x8 + y8*b8_stride] + ref_offset;
if(ref0 >= 0)
ref0 = map_col_to_list0[0][ref0];
else{
- ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride]];
+ ref0 = map_col_to_list0[1][l1ref1[x8 + y8*b8_stride] + ref_offset];
l1mv= l1mv1;
}
scale = dist_scale_factor[ref0];
return h->pps.chroma_qp_table[t][qscale];
}
-//FIXME need to check that this does not overflow signed 32 bit for low qp, I am not sure, it's very close
-//FIXME check that gcc inlines this (and optimizes intra & separate_dc stuff away)
-static inline int quantize_c(DCTELEM *block, uint8_t *scantable, int qscale, int intra, int separate_dc){
- int i;
- const int * const quant_table= quant_coeff[qscale];
- const int bias= intra ? (1<<QUANT_SHIFT)/3 : (1<<QUANT_SHIFT)/6;
- const unsigned int threshold1= (1<<QUANT_SHIFT) - bias - 1;
- const unsigned int threshold2= (threshold1<<1);
- int last_non_zero;
-
- if(separate_dc){
- if(qscale<=18){
- //avoid overflows
- const int dc_bias= intra ? (1<<(QUANT_SHIFT-2))/3 : (1<<(QUANT_SHIFT-2))/6;
- const unsigned int dc_threshold1= (1<<(QUANT_SHIFT-2)) - dc_bias - 1;
- const unsigned int dc_threshold2= (dc_threshold1<<1);
-
- int level= block[0]*quant_coeff[qscale+18][0];
- if(((unsigned)(level+dc_threshold1))>dc_threshold2){
- if(level>0){
- level= (dc_bias + level)>>(QUANT_SHIFT-2);
- block[0]= level;
- }else{
- level= (dc_bias - level)>>(QUANT_SHIFT-2);
- block[0]= -level;
- }
-// last_non_zero = i;
- }else{
- block[0]=0;
- }
- }else{
- const int dc_bias= intra ? (1<<(QUANT_SHIFT+1))/3 : (1<<(QUANT_SHIFT+1))/6;
- const unsigned int dc_threshold1= (1<<(QUANT_SHIFT+1)) - dc_bias - 1;
- const unsigned int dc_threshold2= (dc_threshold1<<1);
-
- int level= block[0]*quant_table[0];
- if(((unsigned)(level+dc_threshold1))>dc_threshold2){
- if(level>0){
- level= (dc_bias + level)>>(QUANT_SHIFT+1);
- block[0]= level;
- }else{
- level= (dc_bias - level)>>(QUANT_SHIFT+1);
- block[0]= -level;
- }
-// last_non_zero = i;
- }else{
- block[0]=0;
- }
- }
- last_non_zero= 0;
- i=1;
- }else{
- last_non_zero= -1;
- i=0;
- }
-
- for(; i<16; i++){
- const int j= scantable[i];
- int level= block[j]*quant_table[j];
-
-// if( bias+level >= (1<<(QMAT_SHIFT - 3))
-// || bias-level >= (1<<(QMAT_SHIFT - 3))){
- if(((unsigned)(level+threshold1))>threshold2){
- if(level>0){
- level= (bias + level)>>QUANT_SHIFT;
- block[j]= level;
- }else{
- level= (bias - level)>>QUANT_SHIFT;
- block[j]= -level;
- }
- last_non_zero = i;
- }else{
- block[j]=0;
- }
- }
-
- return last_non_zero;
-}
-
static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, int chroma_height, int delta, int list,
uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
int src_x_offset, int src_y_offset,
* the packed static coeff_token_vlc table sizes
* were initialized correctly.
*/
- assert(offset == sizeof(coeff_token_vlc_tables)/(sizeof(VLC_TYPE)*2));
+ assert(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
for(i=0; i<3; i++){
chroma_dc_total_zeros_vlc[i].table = chroma_dc_total_zeros_vlc_tables[i];
av_freep(&h->mb2b_xy);
av_freep(&h->mb2b8_xy);
- for(i = 0; i < MAX_SPS_COUNT; i++)
- av_freep(h->sps_buffers + i);
-
- for(i = 0; i < MAX_PPS_COUNT; i++)
- av_freep(h->pps_buffers + i);
-
for(i = 0; i < h->s.avctx->thread_count; i++) {
hx = h->thread_context[i];
if(!hx) continue;
}
for(q=0; q<52; q++){
- int shift = ff_div6[q];
- int idx = ff_rem6[q];
+ int shift = div6[q];
+ int idx = rem6[q];
for(x=0; x<64; x++)
h->dequant8_coeff[i][q][transpose ? (x>>3)|((x&7)<<3) : x] =
((uint32_t)dequant8_coeff_init[idx][ dequant8_coeff_init_scan[((x>>1)&12) | (x&3)] ] *
continue;
for(q=0; q<52; q++){
- int shift = ff_div6[q] + 2;
- int idx = ff_rem6[q];
+ int shift = div6[q] + 2;
+ int idx = rem6[q];
for(x=0; x<16; x++)
h->dequant4_coeff[i][q][transpose ? (x>>2)|((x<<2)&0xF) : x] =
((uint32_t)dequant4_coeff_init[idx][(x&1) + ((x>>2)&1)] *
CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t))
CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t))
- CHECKED_ALLOCZ(h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(uint8_t))
+ CHECKED_ALLOCZ(h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base))
CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t))
CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t))
CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t));
CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t));
- memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(uint8_t));
+ memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base));
h->slice_table= h->slice_table_base + s->mb_stride*2 + 1;
CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint32_t));
h->thread_context[0] = h;
h->outputed_poc = INT_MIN;
+ h->prev_poc_msb= 1<<16;
return 0;
}
/* some macroblocks will be accessed before they're available */
if(FRAME_MBAFF || s->avctx->thread_count > 1)
- memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(uint8_t));
+ memset(h->slice_table, -1, (s->mb_height*s->mb_stride-1) * sizeof(*h->slice_table));
// s->decode= (s->flags&CODEC_FLAG_PSNR) || !s->encoding || s->current_picture.reference /*|| h->contains_intra*/ || 1;
static inline void backup_mb_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int simple){
MpegEncContext * const s = &h->s;
int i;
+ int step = 1;
+ int offset = 1;
+ int uvoffset= 1;
+ int top_idx = 1;
+ int skiplast= 0;
src_y -= linesize;
src_cb -= uvlinesize;
src_cr -= uvlinesize;
+ if(!simple && FRAME_MBAFF){
+ if(s->mb_y&1){
+ offset = MB_MBAFF ? 1 : 17;
+ uvoffset= MB_MBAFF ? 1 : 9;
+ if(!MB_MBAFF){
+ *(uint64_t*)(h->top_borders[0][s->mb_x]+ 0)= *(uint64_t*)(src_y + 15*linesize);
+ *(uint64_t*)(h->top_borders[0][s->mb_x]+ 8)= *(uint64_t*)(src_y +8+15*linesize);
+ if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+7*uvlinesize);
+ *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+7*uvlinesize);
+ }
+ }
+ }else{
+ if(!MB_MBAFF){
+ h->left_border[0]= h->top_borders[0][s->mb_x][15];
+ if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
+ h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7 ];
+ h->left_border[34+18]= h->top_borders[0][s->mb_x][16+8+7];
+ }
+ skiplast= 1;
+ }
+ offset =
+ uvoffset=
+ top_idx = MB_MBAFF ? 0 : 1;
+ }
+ step= MB_MBAFF ? 2 : 1;
+ }
+
// There are two lines saved, the line above the the top macroblock of a pair,
// and the line above the bottom macroblock
- h->left_border[0]= h->top_borders[0][s->mb_x][15];
- for(i=1; i<17; i++){
- h->left_border[i]= src_y[15+i* linesize];
+ h->left_border[offset]= h->top_borders[top_idx][s->mb_x][15];
+ for(i=1; i<17 - skiplast; i++){
+ h->left_border[offset+i*step]= src_y[15+i* linesize];
}
- *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize);
+ *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0)= *(uint64_t*)(src_y + 16*linesize);
+ *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8)= *(uint64_t*)(src_y +8+16*linesize);
if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- h->left_border[17 ]= h->top_borders[0][s->mb_x][16+7];
- h->left_border[17+9]= h->top_borders[0][s->mb_x][24+7];
- for(i=1; i<9; i++){
- h->left_border[i+17 ]= src_cb[7+i*uvlinesize];
- h->left_border[i+17+9]= src_cr[7+i*uvlinesize];
+ h->left_border[uvoffset+34 ]= h->top_borders[top_idx][s->mb_x][16+7];
+ h->left_border[uvoffset+34+18]= h->top_borders[top_idx][s->mb_x][24+7];
+ for(i=1; i<9 - skiplast; i++){
+ h->left_border[uvoffset+34 +i*step]= src_cb[7+i*uvlinesize];
+ h->left_border[uvoffset+34+18+i*step]= src_cr[7+i*uvlinesize];
}
- *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+8*uvlinesize);
+ *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16)= *(uint64_t*)(src_cb+8*uvlinesize);
+ *(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24)= *(uint64_t*)(src_cr+8*uvlinesize);
}
}
int deblock_left;
int deblock_top;
int mb_xy;
+ int step = 1;
+ int offset = 1;
+ int uvoffset= 1;
+ int top_idx = 1;
+
+ if(!simple && FRAME_MBAFF){
+ if(s->mb_y&1){
+ offset = MB_MBAFF ? 1 : 17;
+ uvoffset= MB_MBAFF ? 1 : 9;
+ }else{
+ offset =
+ uvoffset=
+ top_idx = MB_MBAFF ? 0 : 1;
+ }
+ step= MB_MBAFF ? 2 : 1;
+ }
if(h->deblocking_filter == 2) {
mb_xy = h->mb_xy;
deblock_top = h->slice_table[mb_xy] == h->slice_table[h->top_mb_xy];
} else {
deblock_left = (s->mb_x > 0);
- deblock_top = (s->mb_y > 0);
+ deblock_top = (s->mb_y > !!MB_FIELD);
}
src_y -= linesize + 1;
b= t;
if(deblock_left){
- for(i = !deblock_top; i<17; i++){
- XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg);
+ for(i = !deblock_top; i<16; i++){
+ XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, xchg);
}
+ XCHG(h->left_border[offset+i*step], src_y [i* linesize], temp8, 1);
}
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);
+ XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+0), *(uint64_t*)(src_y +1), temp64, xchg);
+ XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+8), *(uint64_t*)(src_y +9), temp64, 1);
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);
+ XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x+1]), *(uint64_t*)(src_y +17), temp64, 1);
}
}
if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
if(deblock_left){
- for(i = !deblock_top; i<9; i++){
- XCHG(h->left_border[i+17 ], src_cb[i*uvlinesize], temp8, xchg);
- XCHG(h->left_border[i+17+9], src_cr[i*uvlinesize], temp8, xchg);
- }
- }
- if(deblock_top){
- XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1);
- XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1);
- }
- }
-}
-
-static inline void backup_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize){
- MpegEncContext * const s = &h->s;
- int i;
-
- src_y -= 2 * linesize;
- src_cb -= 2 * uvlinesize;
- src_cr -= 2 * uvlinesize;
-
- // There are two lines saved, the line above the the top macroblock of a pair,
- // and the line above the bottom macroblock
- h->left_border[0]= h->top_borders[0][s->mb_x][15];
- h->left_border[1]= h->top_borders[1][s->mb_x][15];
- for(i=2; i<34; i++){
- h->left_border[i]= src_y[15+i* linesize];
- }
-
- *(uint64_t*)(h->top_borders[0][s->mb_x]+0)= *(uint64_t*)(src_y + 32*linesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+8)= *(uint64_t*)(src_y +8+32*linesize);
- *(uint64_t*)(h->top_borders[1][s->mb_x]+0)= *(uint64_t*)(src_y + 33*linesize);
- *(uint64_t*)(h->top_borders[1][s->mb_x]+8)= *(uint64_t*)(src_y +8+33*linesize);
-
- if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- h->left_border[34 ]= h->top_borders[0][s->mb_x][16+7];
- h->left_border[34+ 1]= h->top_borders[1][s->mb_x][16+7];
- h->left_border[34+18 ]= h->top_borders[0][s->mb_x][24+7];
- h->left_border[34+18+1]= h->top_borders[1][s->mb_x][24+7];
- for(i=2; i<18; i++){
- h->left_border[i+34 ]= src_cb[7+i*uvlinesize];
- h->left_border[i+34+18]= src_cr[7+i*uvlinesize];
- }
- *(uint64_t*)(h->top_borders[0][s->mb_x]+16)= *(uint64_t*)(src_cb+16*uvlinesize);
- *(uint64_t*)(h->top_borders[0][s->mb_x]+24)= *(uint64_t*)(src_cr+16*uvlinesize);
- *(uint64_t*)(h->top_borders[1][s->mb_x]+16)= *(uint64_t*)(src_cb+17*uvlinesize);
- *(uint64_t*)(h->top_borders[1][s->mb_x]+24)= *(uint64_t*)(src_cr+17*uvlinesize);
- }
-}
-
-static inline void xchg_pair_border(H264Context *h, uint8_t *src_y, uint8_t *src_cb, uint8_t *src_cr, int linesize, int uvlinesize, int xchg){
- MpegEncContext * const s = &h->s;
- int temp8, i;
- uint64_t temp64;
- int deblock_left = (s->mb_x > 0);
- int deblock_top = (s->mb_y > 1);
-
- tprintf(s->avctx, "xchg_pair_border: src_y:%p src_cb:%p src_cr:%p ls:%d uvls:%d\n", src_y, src_cb, src_cr, linesize, uvlinesize);
-
- src_y -= 2 * linesize + 1;
- src_cb -= 2 * uvlinesize + 1;
- src_cr -= 2 * uvlinesize + 1;
-
-#define XCHG(a,b,t,xchg)\
-t= a;\
-if(xchg)\
- a= b;\
-b= t;
-
- if(deblock_left){
- for(i = (!deblock_top)<<1; i<34; i++){
- XCHG(h->left_border[i ], src_y [i* linesize], temp8, xchg);
- }
- }
-
- 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);
- XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+0), *(uint64_t*)(src_y +1 +linesize), temp64, xchg);
- XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+8), *(uint64_t*)(src_y +9 +linesize), temp64, 1);
- 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);
- XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x+1]), *(uint64_t*)(src_y +17 +linesize), temp64, 1);
- }
- }
-
- if(!ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
- if(deblock_left){
- for(i = (!deblock_top) << 1; i<18; i++){
- XCHG(h->left_border[i+34 ], src_cb[i*uvlinesize], temp8, xchg);
- XCHG(h->left_border[i+34+18], src_cr[i*uvlinesize], temp8, xchg);
+ for(i = !deblock_top; i<8; i++){
+ XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, xchg);
+ XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, xchg);
}
+ XCHG(h->left_border[uvoffset+34 +i*step], src_cb[i*uvlinesize], temp8, 1);
+ XCHG(h->left_border[uvoffset+34+18+i*step], src_cr[i*uvlinesize], temp8, 1);
}
if(deblock_top){
- XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1);
- XCHG(*(uint64_t*)(h->top_borders[0][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1);
- XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+16), *(uint64_t*)(src_cb+1 +uvlinesize), temp64, 1);
- XCHG(*(uint64_t*)(h->top_borders[1][s->mb_x]+24), *(uint64_t*)(src_cr+1 +uvlinesize), temp64, 1);
+ XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+16), *(uint64_t*)(src_cb+1), temp64, 1);
+ XCHG(*(uint64_t*)(h->top_borders[top_idx][s->mb_x]+24), *(uint64_t*)(src_cr+1), temp64, 1);
}
}
}
int linesize, uvlinesize /*dct_offset*/;
int i;
int *block_offset = &h->block_offset[0];
- const unsigned int bottom = mb_y & 1;
const int transform_bypass = (s->qscale == 0 && h->sps.transform_bypass), is_h264 = (simple || s->codec_id == CODEC_ID_H264);
void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);
void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);
fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1);
}else{
for(i=0; i<16; i+=4){
- //FIXME can refs be smaller than 8x8 when !direct_8x8_inference ?
int ref = h->ref_cache[list][scan8[i]];
if(ref >= 0)
fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1);
idct_add = s->dsp.h264_idct_add;
}
- if(!simple && FRAME_MBAFF && h->deblocking_filter && IS_INTRA(mb_type)
- && (!bottom || !IS_INTRA(s->current_picture.mb_type[mb_xy-s->mb_stride]))){
- int mbt_y = mb_y&~1;
- uint8_t *top_y = s->current_picture.data[0] + (mbt_y * 16* s->linesize ) + mb_x * 16;
- uint8_t *top_cb = s->current_picture.data[1] + (mbt_y * 8 * s->uvlinesize) + mb_x * 8;
- uint8_t *top_cr = s->current_picture.data[2] + (mbt_y * 8 * s->uvlinesize) + mb_x * 8;
- xchg_pair_border(h, top_y, top_cb, top_cr, s->linesize, s->uvlinesize, 1);
- }
-
if (!simple && IS_INTRA_PCM(mb_type)) {
for (i=0; i<16; i++) {
memcpy(dest_y + i* linesize, h->mb + i*8, 16);
}
} else {
if(IS_INTRA(mb_type)){
- if(h->deblocking_filter && (simple || !FRAME_MBAFF))
+ if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple);
if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
}else
svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);
}
- if(h->deblocking_filter && (simple || !FRAME_MBAFF))
+ if(h->deblocking_filter)
xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple);
}else if(is_h264){
hl_motion(h, dest_y, dest_cb, dest_cr,
}
}
if(h->deblocking_filter) {
+ backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple);
+ fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb
+ h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
+ h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
if (!simple && FRAME_MBAFF) {
- //FIXME try deblocking one mb at a time?
- // the reduction in load/storing mvs and such might outweigh the extra backup/xchg_border
- const int mb_y = s->mb_y - 1;
- uint8_t *pair_dest_y, *pair_dest_cb, *pair_dest_cr;
- const int mb_xy= mb_x + mb_y*s->mb_stride;
- const int mb_type_top = s->current_picture.mb_type[mb_xy];
- const int mb_type_bottom= s->current_picture.mb_type[mb_xy+s->mb_stride];
- if (!bottom) return;
- pair_dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16;
- pair_dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
- pair_dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8;
-
- if(IS_INTRA(mb_type_top | mb_type_bottom))
- xchg_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize, 0);
-
- backup_pair_border(h, pair_dest_y, pair_dest_cb, pair_dest_cr, s->linesize, s->uvlinesize);
- // deblock a pair
- // top
- s->mb_y--; h->mb_xy -= s->mb_stride;
- tprintf(h->s.avctx, "call mbaff filter_mb mb_x:%d mb_y:%d pair_dest_y = %p, dest_y = %p\n", mb_x, mb_y, pair_dest_y, dest_y);
- fill_caches(h, mb_type_top, 1); //FIXME don't fill stuff which isn't used by filter_mb
- h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
- h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
- filter_mb(h, mb_x, mb_y, pair_dest_y, pair_dest_cb, pair_dest_cr, linesize, uvlinesize);
- // bottom
- s->mb_y++; h->mb_xy += s->mb_stride;
- tprintf(h->s.avctx, "call mbaff filter_mb\n");
- fill_caches(h, mb_type_bottom, 1); //FIXME don't fill stuff which isn't used by filter_mb
- h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy+s->mb_stride]);
- h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy+s->mb_stride]);
- filter_mb(h, mb_x, mb_y+1, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
+ filter_mb (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
} else {
- tprintf(h->s.avctx, "call filter_mb\n");
- backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple);
- fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb
- h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);
- h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);
filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);
}
}
}
}
- if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
- direct_dist_scale_factor(h);
- direct_ref_list_init(h);
return 0;
}
for(j=0; j<3; j++)
field[0].linesize[j] <<= 1;
field[0].reference = PICT_TOP_FIELD;
+ field[0].poc= field[0].field_poc[0];
field[1] = field[0];
for(j=0; j<3; j++)
field[1].data[j] += frame->linesize[j];
field[1].reference = PICT_BOTTOM_FIELD;
+ field[1].poc= field[1].field_poc[1];
h->luma_weight[list][16+2*i] = h->luma_weight[list][16+2*i+1] = h->luma_weight[list][i];
h->luma_offset[list][16+2*i] = h->luma_offset[list][16+2*i+1] = h->luma_offset[list][i];
unsigned int first_mb_in_slice;
unsigned int pps_id;
int num_ref_idx_active_override_flag;
- static const uint8_t slice_type_map[5]= {FF_P_TYPE, FF_B_TYPE, FF_I_TYPE, FF_SP_TYPE, FF_SI_TYPE};
unsigned int slice_type, tmp, i, j;
int default_ref_list_done = 0;
int last_pic_structure;
}else
h->slice_type_fixed=0;
- slice_type= slice_type_map[ slice_type ];
+ slice_type= golomb_to_pict_type[ slice_type ];
if (slice_type == FF_I_TYPE
|| (h0->current_slice != 0 && slice_type == h0->last_slice_type) ) {
default_ref_list_done = 1;
if(h != h0)
return -1; // width / height changed during parallelized decoding
free_tables(h);
+ flush_dpb(s->avctx);
MPV_common_end(s);
}
if (!s->context_initialized) {
if(h->slice_type_nos!=FF_I_TYPE && decode_ref_pic_list_reordering(h) < 0)
return -1;
+ if(h->slice_type_nos!=FF_I_TYPE){
+ s->last_picture_ptr= &h->ref_list[0][0];
+ ff_copy_picture(&s->last_picture, s->last_picture_ptr);
+ }
+ if(h->slice_type_nos==FF_B_TYPE){
+ s->next_picture_ptr= &h->ref_list[1][0];
+ ff_copy_picture(&s->next_picture, s->next_picture_ptr);
+ }
+
if( (h->pps.weighted_pred && h->slice_type_nos == FF_P_TYPE )
|| (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) )
pred_weight_table(h);
if(FRAME_MBAFF)
fill_mbaff_ref_list(h);
+ if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)
+ direct_dist_scale_factor(h);
+ direct_ref_list_init(h);
+
if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){
tmp = get_ue_golomb(&s->gb);
if(tmp > 2){
h0->last_slice_type = slice_type;
h->slice_num = ++h0->current_slice;
+ if(h->slice_num >= MAX_SLICES){
+ av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n");
+ }
for(j=0; j<2; j++){
- int *ref2frm= h->ref2frm[h->slice_num&15][j];
+ int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j];
ref2frm[0]=
ref2frm[1]= -1;
- for(i=0; i<48; i++)
+ for(i=0; i<16; i++)
ref2frm[i+2]= 4*h->ref_list[j][i].frame_num
+(h->ref_list[j][i].reference&3);
+ ref2frm[18+0]=
+ ref2frm[18+1]= -1;
+ for(i=16; i<48; i++)
+ ref2frm[i+4]= 4*h->ref_list[j][i].frame_num
+ +(h->ref_list[j][i].reference&3);
}
h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;
h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
+ av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",
h->slice_num,
(s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"),
first_mb_in_slice,
- av_get_pict_type_char(h->slice_type),
+ av_get_pict_type_char(h->slice_type), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",
pps_id, h->frame_num,
s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],
h->ref_count[0], h->ref_count[1],
if (FRAME_MBAFF
// left mb is in picture
- && h->slice_table[mb_xy-1] != 255
+ && h->slice_table[mb_xy-1] != 0xFFFF
// and current and left pair do not have the same interlaced type
&& (IS_INTERLACED(mb_type) != IS_INTERLACED(s->current_picture.mb_type[mb_xy-1]))
// and left mb is in the same slice if deblocking_filter == 2
if( IS_INTRA( s->current_picture.mb_type[mbn_xy] ) )
bS[i] = 4;
else if( h->non_zero_count_cache[12+8*(i>>1)] != 0 ||
- /* FIXME: with 8x8dct + cavlc, should check cbp instead of nnz */
- h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2] )
+ ((!h->pps.cabac && IS_8x8DCT(s->current_picture.mb_type[mbn_xy])) ?
+ (h->cbp_table[mbn_xy] & ((MB_FIELD ? (i&2) : (mb_y&1)) ? 8 : 2))
+ :
+ h->non_zero_count[mbn_xy][MB_FIELD ? i&3 : (i>>2)+(mb_y&1)*2]))
bS[i] = 2;
else
bS[i] = 1;
int edge;
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
const int mbm_type = s->current_picture.mb_type[mbm_xy];
- int (*ref2frm) [48+2] = h->ref2frm[ h->slice_num &15 ];
- int (*ref2frmm)[48+2] = h->ref2frm[ h->slice_table[mbm_xy]&15 ];
- int start = h->slice_table[mbm_xy] == 255 ? 1 : 0;
+ int (*ref2frm) [64] = h->ref2frm[ h->slice_num &(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
+ int (*ref2frmm)[64] = h->ref2frm[ h->slice_table[mbm_xy]&(MAX_SLICES-1) ][0] + (MB_MBAFF ? 20 : 2);
+ int start = h->slice_table[mbm_xy] == 0xFFFF ? 1 : 0;
const int edges = (mb_type & (MB_TYPE_16x16|MB_TYPE_SKIP))
== (MB_TYPE_16x16|MB_TYPE_SKIP) ? 1 : 4;
/* mbn_xy: neighbor macroblock */
const int mbn_xy = edge > 0 ? mb_xy : mbm_xy;
const int mbn_type = s->current_picture.mb_type[mbn_xy];
- int (*ref2frmn)[48+2] = edge > 0 ? ref2frm : ref2frmm;
+ int (*ref2frmn)[64] = edge > 0 ? ref2frm : ref2frmm;
int16_t bS[4];
int qp;
int v = 0;
for( l = 0; !v && l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
- v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] ||
+ v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit;
}
v=0;
for( l = 0; !v && l < 2; l++ ) {
int ln= 1-l;
- v |= ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] ||
+ v |= ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit;
}
{
bS[i] = 0;
for( l = 0; l < 1 + (h->slice_type_nos == FF_B_TYPE); l++ ) {
- if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[l][h->ref_cache[l][bn_idx]+2] ||
+ if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[l][h->ref_cache[l][bn_idx]] ||
FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[l][bn_idx][0] ) >= 4 ||
FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[l][bn_idx][1] ) >= mvy_limit ) {
bS[i] = 1;
bS[i] = 0;
for( l = 0; l < 2; l++ ) {
int ln= 1-l;
- if( ref2frm[l][h->ref_cache[l][b_idx]+2] != ref2frmn[ln][h->ref_cache[ln][bn_idx]+2] ||
+ if( ref2frm[l][h->ref_cache[l][b_idx]] != ref2frmn[ln][h->ref_cache[ln][bn_idx]] ||
FFABS( h->mv_cache[l][b_idx][0] - h->mv_cache[ln][bn_idx][0] ) >= 4 ||
FFABS( h->mv_cache[l][b_idx][1] - h->mv_cache[ln][bn_idx][1] ) >= mvy_limit ) {
bS[i] = 1;
}
}
-static int decode_slice(struct AVCodecContext *avctx, H264Context *h){
+static int decode_slice(struct AVCodecContext *avctx, void *arg){
+ H264Context *h = *(void**)arg;
MpegEncContext * const s = &h->s;
const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
return -1; //not reached
}
+static int decode_picture_timing(H264Context *h){
+ MpegEncContext * const s = &h->s;
+ if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){
+ skip_bits(&s->gb, h->sps.cpb_removal_delay_length); /* cpb_removal_delay */
+ skip_bits(&s->gb, h->sps.dpb_output_delay_length); /* dpb_output_delay */
+ }
+ if(h->sps.pic_struct_present_flag){
+ unsigned int i, num_clock_ts;
+ h->sei_pic_struct = get_bits(&s->gb, 4);
+
+ if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING)
+ return -1;
+
+ num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct];
+
+ for (i = 0 ; i < num_clock_ts ; i++){
+ if(get_bits(&s->gb, 1)){ /* clock_timestamp_flag */
+ unsigned int full_timestamp_flag;
+ skip_bits(&s->gb, 2); /* ct_type */
+ skip_bits(&s->gb, 1); /* nuit_field_based_flag */
+ skip_bits(&s->gb, 5); /* counting_type */
+ full_timestamp_flag = get_bits(&s->gb, 1);
+ skip_bits(&s->gb, 1); /* discontinuity_flag */
+ skip_bits(&s->gb, 1); /* cnt_dropped_flag */
+ skip_bits(&s->gb, 8); /* n_frames */
+ if(full_timestamp_flag){
+ skip_bits(&s->gb, 6); /* seconds_value 0..59 */
+ skip_bits(&s->gb, 6); /* minutes_value 0..59 */
+ skip_bits(&s->gb, 5); /* hours_value 0..23 */
+ }else{
+ if(get_bits(&s->gb, 1)){ /* seconds_flag */
+ skip_bits(&s->gb, 6); /* seconds_value range 0..59 */
+ if(get_bits(&s->gb, 1)){ /* minutes_flag */
+ skip_bits(&s->gb, 6); /* minutes_value 0..59 */
+ if(get_bits(&s->gb, 1)) /* hours_flag */
+ skip_bits(&s->gb, 5); /* hours_value 0..23 */
+ }
+ }
+ }
+ if(h->sps.time_offset_length > 0)
+ skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */
+ }
+ }
+ }
+ return 0;
+}
+
static int decode_unregistered_user_data(H264Context *h, int size){
MpegEncContext * const s = &h->s;
uint8_t user_data[16+256];
}while(get_bits(&s->gb, 8) == 255);
switch(type){
+ case 1: // Picture timing SEI
+ if(decode_picture_timing(h) < 0)
+ return -1;
+ break;
case 5:
if(decode_unregistered_user_data(h, size) < 0)
return -1;
get_bits1(&s->gb); /* cbr_flag */
}
get_bits(&s->gb, 5); /* initial_cpb_removal_delay_length_minus1 */
- get_bits(&s->gb, 5); /* cpb_removal_delay_length_minus1 */
- get_bits(&s->gb, 5); /* dpb_output_delay_length_minus1 */
- get_bits(&s->gb, 5); /* time_offset_length */
+ sps->cpb_removal_delay_length = get_bits(&s->gb, 5) + 1;
+ sps->dpb_output_delay_length = get_bits(&s->gb, 5) + 1;
+ sps->time_offset_length = get_bits(&s->gb, 5);
}
static inline int decode_vui_parameters(H264Context *h, SPS *sps){
MpegEncContext * const s = &h->s;
int aspect_ratio_info_present_flag;
unsigned int aspect_ratio_idc;
- int nal_hrd_parameters_present_flag, vcl_hrd_parameters_present_flag;
aspect_ratio_info_present_flag= get_bits1(&s->gb);
if( aspect_ratio_idc == EXTENDED_SAR ) {
sps->sar.num= get_bits(&s->gb, 16);
sps->sar.den= get_bits(&s->gb, 16);
- }else if(aspect_ratio_idc < sizeof(pixel_aspect)/sizeof(*pixel_aspect)){
+ }else if(aspect_ratio_idc < FF_ARRAY_ELEMS(pixel_aspect)){
sps->sar= pixel_aspect[aspect_ratio_idc];
}else{
av_log(h->s.avctx, AV_LOG_ERROR, "illegal aspect ratio\n");
sps->fixed_frame_rate_flag = get_bits1(&s->gb);
}
- nal_hrd_parameters_present_flag = get_bits1(&s->gb);
- if(nal_hrd_parameters_present_flag)
+ sps->nal_hrd_parameters_present_flag = get_bits1(&s->gb);
+ if(sps->nal_hrd_parameters_present_flag)
decode_hrd_parameters(h, sps);
- vcl_hrd_parameters_present_flag = get_bits1(&s->gb);
- if(vcl_hrd_parameters_present_flag)
+ sps->vcl_hrd_parameters_present_flag = get_bits1(&s->gb);
+ if(sps->vcl_hrd_parameters_present_flag)
decode_hrd_parameters(h, sps);
- if(nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag)
+ if(sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag)
get_bits1(&s->gb); /* low_delay_hrd_flag */
- get_bits1(&s->gb); /* pic_struct_present_flag */
+ sps->pic_struct_present_flag = get_bits1(&s->gb);
sps->bitstream_restriction_flag = get_bits1(&s->gb);
if(sps->bitstream_restriction_flag){
- unsigned int num_reorder_frames;
get_bits1(&s->gb); /* motion_vectors_over_pic_boundaries_flag */
get_ue_golomb(&s->gb); /* max_bytes_per_pic_denom */
get_ue_golomb(&s->gb); /* max_bits_per_mb_denom */
get_ue_golomb(&s->gb); /* log2_max_mv_length_horizontal */
get_ue_golomb(&s->gb); /* log2_max_mv_length_vertical */
- num_reorder_frames= get_ue_golomb(&s->gb);
+ sps->num_reorder_frames= get_ue_golomb(&s->gb);
get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
- if(num_reorder_frames > 16 /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
- av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", num_reorder_frames);
+ if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
+ av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames);
return -1;
}
-
- sps->num_reorder_frames= num_reorder_frames;
}
return 0;
decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y
decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y
}
- } else if(fallback_sps) {
- memcpy(scaling_matrix4, sps->scaling_matrix4, 6*16*sizeof(uint8_t));
- memcpy(scaling_matrix8, sps->scaling_matrix8, 2*64*sizeof(uint8_t));
- }
-}
-
-/**
- * Returns and optionally allocates SPS / PPS structures in the supplied array 'vec'
- */
-static void *
-alloc_parameter_set(H264Context *h, void **vec, const unsigned int id, const unsigned int max,
- const size_t size, const char *name)
-{
- if(id>=max) {
- av_log(h->s.avctx, AV_LOG_ERROR, "%s_id (%d) out of range\n", name, id);
- return NULL;
}
-
- if(!vec[id]) {
- vec[id] = av_mallocz(size);
- if(vec[id] == NULL)
- av_log(h->s.avctx, AV_LOG_ERROR, "cannot allocate memory for %s\n", name);
- }
- return vec[id];
}
static inline int decode_seq_parameter_set(H264Context *h){
MpegEncContext * const s = &h->s;
int profile_idc, level_idc;
- unsigned int sps_id, tmp, mb_width, mb_height;
+ unsigned int sps_id;
int i;
SPS *sps;
level_idc= get_bits(&s->gb, 8);
sps_id= get_ue_golomb(&s->gb);
- sps = alloc_parameter_set(h, (void **)h->sps_buffers, sps_id, MAX_SPS_COUNT, sizeof(SPS), "sps");
+ if(sps_id >= MAX_SPS_COUNT) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "sps_id (%d) out of range\n", sps_id);
+ return -1;
+ }
+ sps= av_mallocz(sizeof(SPS));
if(sps == NULL)
return -1;
sps->profile_idc= profile_idc;
sps->level_idc= level_idc;
+ memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
+ memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
+ sps->scaling_matrix_present = 0;
+
if(sps->profile_idc >= 100){ //high profile
sps->chroma_format_idc= get_ue_golomb(&s->gb);
if(sps->chroma_format_idc == 3)
sps->transform_bypass = get_bits1(&s->gb);
decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
}else{
- sps->scaling_matrix_present = 0;
sps->chroma_format_idc= 1;
}
sps->delta_pic_order_always_zero_flag= get_bits1(&s->gb);
sps->offset_for_non_ref_pic= get_se_golomb(&s->gb);
sps->offset_for_top_to_bottom_field= get_se_golomb(&s->gb);
- tmp= get_ue_golomb(&s->gb);
+ sps->poc_cycle_length = get_ue_golomb(&s->gb);
- if(tmp >= sizeof(sps->offset_for_ref_frame) / sizeof(sps->offset_for_ref_frame[0])){
- av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", tmp);
- return -1;
+ if((unsigned)sps->poc_cycle_length >= FF_ARRAY_ELEMS(sps->offset_for_ref_frame)){
+ av_log(h->s.avctx, AV_LOG_ERROR, "poc_cycle_length overflow %u\n", sps->poc_cycle_length);
+ goto fail;
}
- sps->poc_cycle_length= tmp;
for(i=0; i<sps->poc_cycle_length; i++)
sps->offset_for_ref_frame[i]= get_se_golomb(&s->gb);
}else if(sps->poc_type != 2){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal POC type %d\n", sps->poc_type);
- return -1;
+ goto fail;
}
- tmp= get_ue_golomb(&s->gb);
- if(tmp > MAX_PICTURE_COUNT-2 || tmp >= 32){
+ sps->ref_frame_count= get_ue_golomb(&s->gb);
+ if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){
av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n");
- return -1;
+ goto fail;
}
- sps->ref_frame_count= tmp;
sps->gaps_in_frame_num_allowed_flag= get_bits1(&s->gb);
- mb_width= get_ue_golomb(&s->gb) + 1;
- mb_height= get_ue_golomb(&s->gb) + 1;
- if(mb_width >= INT_MAX/16 || mb_height >= INT_MAX/16 ||
- avcodec_check_dimensions(NULL, 16*mb_width, 16*mb_height)){
+ sps->mb_width = get_ue_golomb(&s->gb) + 1;
+ sps->mb_height= get_ue_golomb(&s->gb) + 1;
+ if((unsigned)sps->mb_width >= INT_MAX/16 || (unsigned)sps->mb_height >= INT_MAX/16 ||
+ avcodec_check_dimensions(NULL, 16*sps->mb_width, 16*sps->mb_height)){
av_log(h->s.avctx, AV_LOG_ERROR, "mb_width/height overflow\n");
- return -1;
+ goto fail;
}
- sps->mb_width = mb_width;
- sps->mb_height= mb_height;
sps->frame_mbs_only_flag= get_bits1(&s->gb);
if(!sps->frame_mbs_only_flag)
if(sps->mb_aff)
av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF support not included; enable it at compile-time.\n");
#endif
- if(!sps->direct_8x8_inference_flag && sps->mb_aff)
- av_log(h->s.avctx, AV_LOG_ERROR, "MBAFF + !direct_8x8_inference is not implemented\n");
-
sps->crop= get_bits1(&s->gb);
if(sps->crop){
sps->crop_left = get_ue_golomb(&s->gb);
if(sps->crop_left || sps->crop_top){
av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
}
- if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !h->sps.frame_mbs_only_flag)){
+ if(sps->crop_right >= 8 || sps->crop_bottom >= (8>> !sps->frame_mbs_only_flag)){
av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
}
}else{
((const char*[]){"Gray","420","422","444"})[sps->chroma_format_idc]
);
}
+ av_free(h->sps_buffers[sps_id]);
+ h->sps_buffers[sps_id]= sps;
return 0;
+fail:
+ av_free(sps);
+ return -1;
}
static void
static inline int decode_picture_parameter_set(H264Context *h, int bit_length){
MpegEncContext * const s = &h->s;
- unsigned int tmp, pps_id= get_ue_golomb(&s->gb);
+ unsigned int pps_id= get_ue_golomb(&s->gb);
PPS *pps;
- pps = alloc_parameter_set(h, (void **)h->pps_buffers, pps_id, MAX_PPS_COUNT, sizeof(PPS), "pps");
- if(pps == NULL)
+ if(pps_id >= MAX_PPS_COUNT) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
return -1;
+ }
- tmp= get_ue_golomb(&s->gb);
- if(tmp>=MAX_SPS_COUNT || h->sps_buffers[tmp] == NULL){
- av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n");
+ pps= av_mallocz(sizeof(PPS));
+ if(pps == NULL)
return -1;
+ pps->sps_id= get_ue_golomb(&s->gb);
+ if((unsigned)pps->sps_id>=MAX_SPS_COUNT || h->sps_buffers[pps->sps_id] == NULL){
+ av_log(h->s.avctx, AV_LOG_ERROR, "sps_id out of range\n");
+ goto fail;
}
- pps->sps_id= tmp;
pps->cabac= get_bits1(&s->gb);
pps->pic_order_present= get_bits1(&s->gb);
pps->ref_count[1]= get_ue_golomb(&s->gb) + 1;
if(pps->ref_count[0]-1 > 32-1 || pps->ref_count[1]-1 > 32-1){
av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow (pps)\n");
- pps->ref_count[0]= pps->ref_count[1]= 1;
- return -1;
+ goto fail;
}
pps->weighted_pred= get_bits1(&s->gb);
pps->transform_8x8_mode= 0;
h->dequant_coeff_pps= -1; //contents of sps/pps can change even if id doesn't, so reinit
- memset(pps->scaling_matrix4, 16, 6*16*sizeof(uint8_t));
- memset(pps->scaling_matrix8, 16, 2*64*sizeof(uint8_t));
+ memcpy(pps->scaling_matrix4, h->sps_buffers[pps->sps_id]->scaling_matrix4, sizeof(pps->scaling_matrix4));
+ memcpy(pps->scaling_matrix8, h->sps_buffers[pps->sps_id]->scaling_matrix8, sizeof(pps->scaling_matrix8));
if(get_bits_count(&s->gb) < bit_length){
pps->transform_8x8_mode= get_bits1(&s->gb);
);
}
+ av_free(h->pps_buffers[pps_id]);
+ h->pps_buffers[pps_id]= pps;
return 0;
+fail:
+ av_free(pps);
+ return -1;
}
/**
int i;
if(context_count == 1) {
- decode_slice(avctx, h);
+ decode_slice(avctx, &h);
} else {
for(i = 1; i < context_count; i++) {
hx = h->thread_context[i];
- hx->s.error_resilience = avctx->error_resilience;
+ hx->s.error_recognition = avctx->error_recognition;
hx->s.error_count = 0;
}
avctx->execute(avctx, (void *)decode_slice,
- (void **)h->thread_context, NULL, context_count);
+ (void **)h->thread_context, NULL, context_count, sizeof(void*));
/* pull back stuff from slices to master context */
hx = h->thread_context[context_count - 1];
//FIXME factorize this with the output code below
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++)
+ for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
h->got_avcC = 1;
}
- if(avctx->frame_number==0 && !h->is_avc && s->avctx->extradata_size){
+ if(!h->got_avcC && !h->is_avc && s->avctx->extradata_size){
if(decode_nal_units(h, s->avctx->extradata, s->avctx->extradata_size) < 0)
return -1;
+ h->got_avcC = 1;
}
buf_index=decode_nal_units(h, buf, buf_size);
*data_size = 0;
} else {
- cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
- /* Derive top_field_first from field pocs. */
- cur->top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ cur->repeat_pict = 0;
+
+ /* Signal interlacing information externally. */
+ /* Prioritize picture timing SEI information over used decoding process if it exists. */
+ if(h->sps.pic_struct_present_flag){
+ switch (h->sei_pic_struct)
+ {
+ case SEI_PIC_STRUCT_FRAME:
+ cur->interlaced_frame = 0;
+ break;
+ case SEI_PIC_STRUCT_TOP_FIELD:
+ case SEI_PIC_STRUCT_BOTTOM_FIELD:
+ case SEI_PIC_STRUCT_TOP_BOTTOM:
+ case SEI_PIC_STRUCT_BOTTOM_TOP:
+ cur->interlaced_frame = 1;
+ break;
+ case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
+ case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
+ // Signal the possibility of telecined film externally (pic_struct 5,6)
+ // From these hints, let the applications decide if they apply deinterlacing.
+ cur->repeat_pict = 1;
+ cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
+ break;
+ case SEI_PIC_STRUCT_FRAME_DOUBLING:
+ // Force progressive here, as doubling interlaced frame is a bad idea.
+ cur->interlaced_frame = 0;
+ cur->repeat_pict = 2;
+ break;
+ case SEI_PIC_STRUCT_FRAME_TRIPLING:
+ cur->interlaced_frame = 0;
+ cur->repeat_pict = 4;
+ break;
+ }
+ }else{
+ /* Derive interlacing flag from used decoding process. */
+ cur->interlaced_frame = FIELD_OR_MBAFF_PICTURE;
+ }
+
+ if (cur->field_poc[0] != cur->field_poc[1]){
+ /* Derive top_field_first from field pocs. */
+ cur->top_field_first = cur->field_poc[0] < cur->field_poc[1];
+ }else{
+ if(cur->interlaced_frame || h->sps.pic_struct_present_flag){
+ /* Use picture timing SEI information. Even if it is a information of a past frame, better than nothing. */
+ if(h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM
+ || h->sei_pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)
+ cur->top_field_first = 1;
+ else
+ cur->top_field_first = 0;
+ }else{
+ /* Most likely progressive */
+ cur->top_field_first = 0;
+ }
+ }
//FIXME do something with unavailable reference frames
out = h->delayed_pic[0];
out_idx = 0;
- for(i=1; h->delayed_pic[i] && h->delayed_pic[i]->poc; i++)
+ for(i=1; h->delayed_pic[i] && (h->delayed_pic[i]->poc && !h->delayed_pic[i]->key_frame); i++)
if(h->delayed_pic[i]->poc < out->poc){
out = h->delayed_pic[i];
out_idx = i;
}
- cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i];
+ cross_idr = !h->delayed_pic[0]->poc || !!h->delayed_pic[i] || h->delayed_pic[0]->key_frame;
out_of_order = !cross_idr && out->poc < h->outputed_poc;
{
H264Context *h = avctx->priv_data;
MpegEncContext *s = &h->s;
+ int i;
av_freep(&h->rbsp_buffer[0]);
av_freep(&h->rbsp_buffer[1]);
free_tables(h); //FIXME cleanup init stuff perhaps
+
+ for(i = 0; i < MAX_SPS_COUNT; i++)
+ av_freep(h->sps_buffers + i);
+
+ for(i = 0; i < MAX_PPS_COUNT; i++)
+ av_freep(h->pps_buffers + i);
+
MPV_common_end(s);
// memset(h, 0, sizeof(H264Context));