Browse Source

h264: propagate error return values for AV_LOG_ERROR-triggering events

Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
tags/n0.9
Dustin Brody Ronald S. Bultje 14 years ago
parent
commit
12fe759423
2 changed files with 25 additions and 15 deletions
  1. +19
    -13
      libavcodec/h264.c
  2. +6
    -2
      libavcodec/h264_refs.c

+ 19
- 13
libavcodec/h264.c View File

@@ -1194,7 +1194,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
if(!s->current_picture_ptr) return 0; if(!s->current_picture_ptr) return 0;


if(!s->dropable) { if(!s->dropable) {
ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb = h->poc_msb; h->prev_poc_msb = h->poc_msb;
h->prev_poc_lsb = h->poc_lsb; h->prev_poc_lsb = h->poc_lsb;
} }
@@ -1202,7 +1202,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
h->prev_frame_num = h->frame_num; h->prev_frame_num = h->frame_num;
h->outputed_poc = h->next_outputed_poc; h->outputed_poc = h->next_outputed_poc;


return 0;
return err;
} }


int ff_h264_frame_start(H264Context *h){ int ff_h264_frame_start(H264Context *h){
@@ -2318,9 +2318,10 @@ static void init_scan_tables(H264Context *h){
} }
} }


static void field_end(H264Context *h, int in_setup){
static int field_end(H264Context *h, int in_setup){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx; AVCodecContext * const avctx= s->avctx;
int err = 0;
s->mb_y= 0; s->mb_y= 0;


if (!in_setup && !s->dropable) if (!in_setup && !s->dropable)
@@ -2332,7 +2333,7 @@ static void field_end(H264Context *h, int in_setup){


if(in_setup || !(avctx->active_thread_type&FF_THREAD_FRAME)){ if(in_setup || !(avctx->active_thread_type&FF_THREAD_FRAME)){
if(!s->dropable) { if(!s->dropable) {
ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
h->prev_poc_msb= h->poc_msb; h->prev_poc_msb= h->poc_msb;
h->prev_poc_lsb= h->poc_lsb; h->prev_poc_lsb= h->poc_lsb;
} }
@@ -2367,6 +2368,8 @@ static void field_end(H264Context *h, int in_setup){
MPV_frame_end(s); MPV_frame_end(s);


h->current_slice=0; h->current_slice=0;

return err;
} }


/** /**
@@ -2668,7 +2671,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0); ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0);
ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1); ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1);
ff_generate_sliding_window_mmcos(h); ff_generate_sliding_window_mmcos(h);
ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);
if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 &&
s->avctx->error_recognition >= FF_ER_EXPLODE)
return AVERROR_INVALIDDATA;
/* Error concealment: if a ref is missing, copy the previous ref in its place. /* Error concealment: if a ref is missing, copy the previous ref in its place.
* FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions * FIXME: avoiding a memcpy would be nice, but ref handling makes many assumptions
* about there being no actual duplicates. * about there being no actual duplicates.
@@ -2842,8 +2847,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
} }
} }


if(h->nal_ref_idc)
ff_h264_decode_ref_pic_marking(h0, &s->gb);
if(h->nal_ref_idc && ff_h264_decode_ref_pic_marking(h0, &s->gb) < 0 &&
s->avctx->error_recognition >= FF_ER_EXPLODE)
return AVERROR_INVALIDDATA;


if(FRAME_MBAFF){ if(FRAME_MBAFF){
ff_h264_fill_mbaff_ref_list(h); ff_h264_fill_mbaff_ref_list(h);
@@ -3467,18 +3473,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){
* @param h h264 master context * @param h h264 master context
* @param context_count number of contexts to execute * @param context_count number of contexts to execute
*/ */
static void execute_decode_slices(H264Context *h, int context_count){
static int execute_decode_slices(H264Context *h, int context_count){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx; AVCodecContext * const avctx= s->avctx;
H264Context *hx; H264Context *hx;
int i; int i;


if (s->avctx->hwaccel)
return;
if(s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
return;
if (s->avctx->hwaccel || s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)
return 0;
if(context_count == 1) { if(context_count == 1) {
decode_slice(avctx, &h);
return decode_slice(avctx, &h);
} else { } else {
for(i = 1; i < context_count; i++) { for(i = 1; i < context_count; i++) {
hx = h->thread_context[i]; hx = h->thread_context[i];
@@ -3498,6 +3502,8 @@ static void execute_decode_slices(H264Context *h, int context_count){
for(i = 1; i < context_count; i++) for(i = 1; i < context_count; i++)
h->s.error_count += h->thread_context[i]->s.error_count; h->s.error_count += h->thread_context[i]->s.error_count;
} }

return 0;
} }






+ 6
- 2
libavcodec/h264_refs.c View File

@@ -498,7 +498,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h) {
int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
int i, av_uninit(j); int i, av_uninit(j);
int current_ref_assigned=0;
int current_ref_assigned=0, err=0;
Picture *av_uninit(pic); Picture *av_uninit(pic);


if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0) if((s->avctx->debug&FF_DEBUG_MMCO) && mmco_count==0)
@@ -517,6 +517,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg]
|| h->long_ref[mmco[i].long_arg]->frame_num != frame_num) || h->long_ref[mmco[i].long_arg]->frame_num != frame_num)
av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n");
err = AVERROR_INVALIDDATA;
continue; continue;
} }
} }
@@ -608,10 +609,12 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
"assignment for second field " "assignment for second field "
"in complementary field pair " "in complementary field pair "
"(first field is long term)\n"); "(first field is long term)\n");
err = AVERROR_INVALIDDATA;
} else { } else {
pic= remove_short(h, s->current_picture_ptr->frame_num, 0); pic= remove_short(h, s->current_picture_ptr->frame_num, 0);
if(pic){ if(pic){
av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n");
err = AVERROR_INVALIDDATA;
} }


if(h->short_ref_count) if(h->short_ref_count)
@@ -634,6 +637,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
"number of reference frames (%d+%d) exceeds max (%d; probably " "number of reference frames (%d+%d) exceeds max (%d; probably "
"corrupt input), discarding one\n", "corrupt input), discarding one\n",
h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count); h->long_ref_count, h->short_ref_count, h->sps.ref_frame_count);
err = AVERROR_INVALIDDATA;


if (h->long_ref_count && !h->short_ref_count) { if (h->long_ref_count && !h->short_ref_count) {
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
@@ -650,7 +654,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){


print_short_term(h); print_short_term(h);
print_long_term(h); print_long_term(h);
return 0;
return err;
} }


int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb){


Loading…
Cancel
Save