diff options
-rw-r--r-- | src/video_dec/libvdpau/dpb.c | 13 | ||||
-rw-r--r-- | src/video_dec/libvdpau/vdpau_h264.c | 38 |
2 files changed, 32 insertions, 19 deletions
diff --git a/src/video_dec/libvdpau/dpb.c b/src/video_dec/libvdpau/dpb.c index d37603ba5..bffc582ac 100644 --- a/src/video_dec/libvdpau/dpb.c +++ b/src/video_dec/libvdpau/dpb.c @@ -40,7 +40,7 @@ int dp_top_field_first(struct decoded_picture *decoded_pic) { - int top_field_first = 0; + int top_field_first = 1; if (decoded_pic->coded_pic[1] != NULL) { @@ -51,9 +51,9 @@ int dp_top_field_first(struct decoded_picture *decoded_pic) top_field_first = decoded_pic->coded_pic[0]->top_field_order_cnt < decoded_pic->coded_pic[1]->bottom_field_order_cnt; } else if (decoded_pic->coded_pic[0]->slc_nal->slc.bottom_field_flag && !decoded_pic->coded_pic[1]->slc_nal->slc.bottom_field_flag && - decoded_pic->coded_pic[0]->top_field_order_cnt != - decoded_pic->coded_pic[1]->bottom_field_order_cnt) { - top_field_first = decoded_pic->coded_pic[0]->top_field_order_cnt > decoded_pic->coded_pic[1]->bottom_field_order_cnt; + decoded_pic->coded_pic[0]->bottom_field_order_cnt != + decoded_pic->coded_pic[1]->top_field_order_cnt) { + top_field_first = decoded_pic->coded_pic[0]->bottom_field_order_cnt > decoded_pic->coded_pic[1]->top_field_order_cnt; } } @@ -62,8 +62,11 @@ int dp_top_field_first(struct decoded_picture *decoded_pic) if(pic_struct == DISP_TOP_BOTTOM || pic_struct == DISP_TOP_BOTTOM_TOP) { top_field_first = 1; - } else if (pic_struct == DISP_FRAME) { + } else if (pic_struct == DISP_BOTTOM_TOP || + pic_struct == DISP_BOTTOM_TOP_BOTTOM) { top_field_first = 0; + } else if (pic_struct == DISP_FRAME) { + top_field_first = 1; } } diff --git a/src/video_dec/libvdpau/vdpau_h264.c b/src/video_dec/libvdpau/vdpau_h264.c index 8f3e956d9..144f02a6d 100644 --- a/src/video_dec/libvdpau/vdpau_h264.c +++ b/src/video_dec/libvdpau/vdpau_h264.c @@ -411,15 +411,6 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v } } - VdpPictureInfoH264 pic; - - fill_vdpau_pictureinfo_h264(this_gen, slice_count, &pic); - - if(!this->decoder_started && !pic.is_reference) - return 0; - - this->decoder_started = 1; - struct seq_parameter_set_rbsp *sps = &this->completed_pic->sps_nal->sps; struct slice_header *slc = &this->completed_pic->slc_nal->slc; @@ -451,13 +442,32 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v #endif /* check if we expect a second field, but got a frame */ - if (this->incomplete_pic && img && !slc->field_pic_flag) { - xprintf(this->xine, XINE_VERBOSITY_DEBUG, "H264 warning: Expected a second field, but got a frame\n"); - release_decoded_picture(this->incomplete_pic); - this->incomplete_pic = NULL; - img = NULL; + if (this->incomplete_pic && img) { + if ((this->completed_pic->slc_nal->slc.frame_num != + this->incomplete_pic->coded_pic[0]->slc_nal->slc.frame_num) || + !slc->field_pic_flag) { + xprintf(this->xine, XINE_VERBOSITY_DEBUG, "H264 warning: Expected a second field, stream might be broken\n"); + + /* remove this pic from dpb, as it is not complete */ + dpb_unmark_picture_delayed(this->nal_parser->dpb, this->incomplete_pic); + dpb_unmark_reference_picture(this->nal_parser->dpb, this->incomplete_pic); + + release_decoded_picture(this->incomplete_pic); + this->incomplete_pic = NULL; + img = NULL; + } } + + VdpPictureInfoH264 pic; + + fill_vdpau_pictureinfo_h264(this_gen, slice_count, &pic); + + if(!this->decoder_started && !pic.is_reference) + return 0; + + this->decoder_started = 1; + if(img == NULL) { img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, |