|
|
|
@@ -3465,42 +3465,80 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "no mmco here\n"); |
|
|
|
|
|
|
|
for(i=0; i<mmco_count; i++){ |
|
|
|
int structure, frame_num, unref_pic; |
|
|
|
if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco:%d %d %d\n", h->mmco[i].opcode, h->mmco[i].short_pic_num, h->mmco[i].long_arg); |
|
|
|
|
|
|
|
switch(mmco[i].opcode){ |
|
|
|
case MMCO_SHORT2UNUSED: |
|
|
|
pic= remove_short(h, mmco[i].short_pic_num); |
|
|
|
if(pic) |
|
|
|
unreference_pic(h, pic, 0); |
|
|
|
else if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_short() failure\n"); |
|
|
|
if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short %d count %d\n", h->mmco[i].short_pic_num, h->short_ref_count); |
|
|
|
frame_num = pic_num_extract(h, mmco[i].short_pic_num, &structure); |
|
|
|
pic = find_short(h, frame_num, &j); |
|
|
|
if (pic) { |
|
|
|
if (unreference_pic(h, pic, structure ^ PICT_FRAME)) |
|
|
|
remove_short_at_index(h, j); |
|
|
|
} else if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref short failure\n"); |
|
|
|
break; |
|
|
|
case MMCO_SHORT2LONG: |
|
|
|
pic= remove_long(h, mmco[i].long_arg); |
|
|
|
if(pic) unreference_pic(h, pic, 0); |
|
|
|
if (FIELD_PICTURE && mmco[i].long_arg < h->long_ref_count && |
|
|
|
h->long_ref[mmco[i].long_arg]->frame_num == |
|
|
|
mmco[i].short_pic_num / 2) { |
|
|
|
/* do nothing, we've already moved this field pair. */ |
|
|
|
} else { |
|
|
|
int frame_num = mmco[i].short_pic_num >> FIELD_PICTURE; |
|
|
|
|
|
|
|
pic= remove_long(h, mmco[i].long_arg); |
|
|
|
if(pic) unreference_pic(h, pic, 0); |
|
|
|
|
|
|
|
h->long_ref[ mmco[i].long_arg ]= remove_short(h, mmco[i].short_pic_num); |
|
|
|
h->long_ref[ mmco[i].long_arg ]= remove_short(h, frame_num); |
|
|
|
if (h->long_ref[ mmco[i].long_arg ]){ |
|
|
|
h->long_ref[ mmco[i].long_arg ]->long_ref=1; |
|
|
|
h->long_ref_count++; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
case MMCO_LONG2UNUSED: |
|
|
|
pic= remove_long(h, mmco[i].long_arg); |
|
|
|
if(pic) |
|
|
|
unreference_pic(h, pic, 0); |
|
|
|
else if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_long() failure\n"); |
|
|
|
j = pic_num_extract(h, mmco[i].long_arg, &structure); |
|
|
|
pic = h->long_ref[j]; |
|
|
|
if (pic) { |
|
|
|
if (unreference_pic(h, pic, structure ^ PICT_FRAME)) |
|
|
|
remove_long_at_index(h, j); |
|
|
|
} else if(s->avctx->debug&FF_DEBUG_MMCO) |
|
|
|
av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: unref long failure\n"); |
|
|
|
break; |
|
|
|
case MMCO_LONG: |
|
|
|
unref_pic = 1; |
|
|
|
if (FIELD_PICTURE && !s->first_field) { |
|
|
|
if (h->long_ref[mmco[i].long_arg] == s->current_picture_ptr) { |
|
|
|
/* Just mark second field as referenced */ |
|
|
|
unref_pic = 0; |
|
|
|
} else if (s->current_picture_ptr->reference) { |
|
|
|
/* First field in pair is in short term list or |
|
|
|
* at a different long term index. |
|
|
|
* This is not allowed; see 7.4.3, notes 2 and 3. |
|
|
|
* Report the problem and keep the pair where it is, |
|
|
|
* and mark this field valid. |
|
|
|
*/ |
|
|
|
av_log(h->s.avctx, AV_LOG_ERROR, |
|
|
|
"illegal long term reference assignment for second " |
|
|
|
"field in complementary field pair (first field is " |
|
|
|
"short term or has non-matching long index)\n"); |
|
|
|
unref_pic = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (unref_pic) { |
|
|
|
pic= remove_long(h, mmco[i].long_arg); |
|
|
|
if(pic) unreference_pic(h, pic, 0); |
|
|
|
|
|
|
|
h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; |
|
|
|
h->long_ref[ mmco[i].long_arg ]->long_ref=1; |
|
|
|
h->long_ref_count++; |
|
|
|
} |
|
|
|
|
|
|
|
s->current_picture_ptr->reference |= s->picture_structure; |
|
|
|
current_ref_assigned=1; |
|
|
|
break; |
|
|
|
case MMCO_SET_MAX_LONG: |
|
|
|
@@ -3525,6 +3563,34 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!current_ref_assigned && FIELD_PICTURE && |
|
|
|
!s->first_field && s->current_picture_ptr->reference) { |
|
|
|
|
|
|
|
/* Second field of complementary field pair; the first field of |
|
|
|
* which is already referenced. If short referenced, it |
|
|
|
* should be first entry in short_ref. If not, it must exist |
|
|
|
* in long_ref; trying to put it on the short list here is an |
|
|
|
* error in the encoded bit stream (ref: 7.4.3, NOTE 2 and 3). |
|
|
|
*/ |
|
|
|
if (h->short_ref_count && h->short_ref[0] == s->current_picture_ptr) { |
|
|
|
/* Just mark the second field valid */ |
|
|
|
s->current_picture_ptr->reference = PICT_FRAME; |
|
|
|
} else if (s->current_picture_ptr->long_ref) { |
|
|
|
av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term reference " |
|
|
|
"assignment for second field " |
|
|
|
"in complementary field pair " |
|
|
|
"(first field is long term)\n"); |
|
|
|
} else { |
|
|
|
/* |
|
|
|
* First field in reference, but not in any sensible place on our |
|
|
|
* reference lists. This shouldn't happen unless reference |
|
|
|
* handling somewhere else is wrong. |
|
|
|
*/ |
|
|
|
assert(0); |
|
|
|
} |
|
|
|
current_ref_assigned = 1; |
|
|
|
} |
|
|
|
|
|
|
|
if(!current_ref_assigned){ |
|
|
|
pic= remove_short(h, s->current_picture_ptr->frame_num); |
|
|
|
if(pic){ |
|
|
|
@@ -3538,6 +3604,7 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ |
|
|
|
h->short_ref[0]= s->current_picture_ptr; |
|
|
|
h->short_ref[0]->long_ref=0; |
|
|
|
h->short_ref_count++; |
|
|
|
s->current_picture_ptr->reference |= s->picture_structure; |
|
|
|
} |
|
|
|
|
|
|
|
print_short_term(h); |
|
|
|
|