|
|
|
@@ -3339,6 +3339,7 @@ static void flush_dpb(AVCodecContext *avctx){ |
|
|
|
idr(h); |
|
|
|
if(h->s.current_picture_ptr) |
|
|
|
h->s.current_picture_ptr->reference= 0; |
|
|
|
h->s.first_field= 0; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@@ -3830,6 +3831,7 @@ static void clone_slice(H264Context *dst, H264Context *src) |
|
|
|
dst->s.current_picture = src->s.current_picture; |
|
|
|
dst->s.linesize = src->s.linesize; |
|
|
|
dst->s.uvlinesize = src->s.uvlinesize; |
|
|
|
dst->s.first_field = src->s.first_field; |
|
|
|
|
|
|
|
dst->prev_poc_msb = src->prev_poc_msb; |
|
|
|
dst->prev_poc_lsb = src->prev_poc_lsb; |
|
|
|
@@ -3857,12 +3859,14 @@ static void clone_slice(H264Context *dst, H264Context *src) |
|
|
|
*/ |
|
|
|
static int decode_slice_header(H264Context *h, H264Context *h0){ |
|
|
|
MpegEncContext * const s = &h->s; |
|
|
|
MpegEncContext * const s0 = &h0->s; |
|
|
|
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]= {P_TYPE, B_TYPE, I_TYPE, SP_TYPE, SI_TYPE}; |
|
|
|
unsigned int slice_type, tmp, i; |
|
|
|
int default_ref_list_done = 0; |
|
|
|
int last_pic_structure; |
|
|
|
|
|
|
|
s->dropable= h->nal_ref_idc == 0; |
|
|
|
|
|
|
|
@@ -3870,6 +3874,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ |
|
|
|
|
|
|
|
if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){ |
|
|
|
h0->current_slice = 0; |
|
|
|
if (!s0->first_field) |
|
|
|
s->current_picture_ptr= NULL; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -3939,6 +3944,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ |
|
|
|
return -1; // we cant (re-)initialize context during parallel decoding |
|
|
|
if (MPV_common_init(s) < 0) |
|
|
|
return -1; |
|
|
|
s->first_field = 0; |
|
|
|
|
|
|
|
init_scan_tables(h); |
|
|
|
alloc_tables(h); |
|
|
|
@@ -3977,6 +3983,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ |
|
|
|
|
|
|
|
h->mb_mbaff = 0; |
|
|
|
h->mb_aff_frame = 0; |
|
|
|
last_pic_structure = s0->picture_structure; |
|
|
|
if(h->sps.frame_mbs_only_flag){ |
|
|
|
s->picture_structure= PICT_FRAME; |
|
|
|
}else{ |
|
|
|
@@ -3990,8 +3997,50 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ |
|
|
|
} |
|
|
|
|
|
|
|
if(h0->current_slice == 0){ |
|
|
|
if(frame_start(h) < 0) |
|
|
|
/* See if we have a decoded first field looking for a pair... */ |
|
|
|
if (s0->first_field) { |
|
|
|
assert(s0->current_picture_ptr); |
|
|
|
assert(s0->current_picture_ptr->data[0]); |
|
|
|
assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF); |
|
|
|
|
|
|
|
/* figure out if we have a complementary field pair */ |
|
|
|
if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) { |
|
|
|
/* |
|
|
|
* Previous field is unmatched. Don't display it, but let it |
|
|
|
* remain for reference if marked as such. |
|
|
|
*/ |
|
|
|
s0->current_picture_ptr = NULL; |
|
|
|
s0->first_field = FIELD_PICTURE; |
|
|
|
|
|
|
|
} else { |
|
|
|
if (h->nal_ref_idc && |
|
|
|
s0->current_picture_ptr->reference && |
|
|
|
s0->current_picture_ptr->frame_num != h->frame_num) { |
|
|
|
/* |
|
|
|
* This and previous field were reference, but had |
|
|
|
* different frame_nums. Consider this field first in |
|
|
|
* pair. Throw away previous field except for reference |
|
|
|
* purposes. |
|
|
|
*/ |
|
|
|
s0->first_field = 1; |
|
|
|
s0->current_picture_ptr = NULL; |
|
|
|
|
|
|
|
} else { |
|
|
|
/* Second field in complementary pair */ |
|
|
|
s0->first_field = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
/* Frame or first field in a potentially complementary pair */ |
|
|
|
assert(!s0->current_picture_ptr); |
|
|
|
s0->first_field = FIELD_PICTURE; |
|
|
|
} |
|
|
|
|
|
|
|
if((!FIELD_PICTURE || s0->first_field) && frame_start(h) < 0) { |
|
|
|
s0->first_field = 0; |
|
|
|
return -1; |
|
|
|
} |
|
|
|
} |
|
|
|
if(h != h0) |
|
|
|
clone_slice(h, h0); |
|
|
|
@@ -7363,6 +7412,8 @@ static void execute_decode_slices(H264Context *h, int context_count){ |
|
|
|
hx = h->thread_context[context_count - 1]; |
|
|
|
s->mb_x = hx->s.mb_x; |
|
|
|
s->mb_y = hx->s.mb_y; |
|
|
|
s->dropable = hx->s.dropable; |
|
|
|
s->picture_structure = hx->s.picture_structure; |
|
|
|
for(i = 1; i < context_count; i++) |
|
|
|
h->s.error_count += h->thread_context[i]->s.error_count; |
|
|
|
} |
|
|
|
@@ -7385,6 +7436,7 @@ static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){ |
|
|
|
#endif |
|
|
|
if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){ |
|
|
|
h->current_slice = 0; |
|
|
|
if (!s->first_field) |
|
|
|
s->current_picture_ptr= NULL; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -7682,16 +7734,34 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
|
|
|
|
h->prev_frame_num_offset= h->frame_num_offset; |
|
|
|
h->prev_frame_num= h->frame_num; |
|
|
|
if(s->current_picture_ptr->reference & s->picture_structure){ |
|
|
|
if(!s->dropable) { |
|
|
|
h->prev_poc_msb= h->poc_msb; |
|
|
|
h->prev_poc_lsb= h->poc_lsb; |
|
|
|
execute_ref_pic_marking(h, h->mmco, h->mmco_index); |
|
|
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
* FIXME: Error handling code does not seem to support interlaced |
|
|
|
* when slices span multiple rows |
|
|
|
* The ff_er_add_slice calls don't work right for bottom |
|
|
|
* fields; they cause massive erroneous error concealing |
|
|
|
* Error marking covers both fields (top and bottom). |
|
|
|
* This causes a mismatched s->error_count |
|
|
|
* and a bad error table. Further, the error count goes to |
|
|
|
* INT_MAX when called for bottom field, because mb_y is |
|
|
|
* past end by one (callers fault) and resync_mb_y != 0 |
|
|
|
* causes problems for the first MB line, too. |
|
|
|
*/ |
|
|
|
if (!FIELD_PICTURE) |
|
|
|
ff_er_frame_end(s); |
|
|
|
|
|
|
|
MPV_frame_end(s); |
|
|
|
|
|
|
|
if (s->first_field) { |
|
|
|
/* Wait for second field. */ |
|
|
|
*data_size = 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
//FIXME do something with unavailable reference frames |
|
|
|
|
|
|
|
#if 0 //decode order |
|
|
|
@@ -7762,6 +7832,7 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
*pict= *(AVFrame*)out; |
|
|
|
else |
|
|
|
av_log(avctx, AV_LOG_DEBUG, "no picture\n"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
assert(pict->data[0] || !*data_size); |
|
|
|
|