diff options
Diffstat (limited to 'src/libvdpau')
-rw-r--r-- | src/libvdpau/dpb.c | 31 | ||||
-rw-r--r-- | src/libvdpau/vdpau_h264.c | 22 |
2 files changed, 46 insertions, 7 deletions
diff --git a/src/libvdpau/dpb.c b/src/libvdpau/dpb.c index 9aa2f4298..01f147639 100644 --- a/src/libvdpau/dpb.c +++ b/src/libvdpau/dpb.c @@ -240,6 +240,31 @@ int dpb_remove_picture(struct dpb *dpb, struct decoded_picture *rempic) return -1; } +static int dpb_remove_picture_by_img(struct dpb *dpb, vo_frame_t *remimg) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + if (pic->img == remimg) { + // FIXME: free the picture.... + + if (last_pic != NULL) + last_pic->next = pic->next; + else + dpb->pictures = pic->next; + free_decoded_picture(pic); + dpb->used--; + return 0; + } + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + return -1; +} + int dpb_remove_picture_by_picnum(struct dpb *dpb, uint32_t picnum) { struct decoded_picture *pic = dpb->pictures; @@ -259,6 +284,12 @@ int dpb_remove_picture_by_picnum(struct dpb *dpb, uint32_t picnum) int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_ref_frames) { + pic->img->lock(pic->img); + if (0 == dpb_remove_picture_by_img(dpb, pic->img)) + fprintf(stderr, "broken stream: current img was already in dpb -- freed it\n"); + else + pic->img->free(pic->img); + int i = 0; struct decoded_picture *last_pic = dpb->pictures; diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c index a8d4093d9..90dc15d67 100644 --- a/src/libvdpau/vdpau_h264.c +++ b/src/libvdpau/vdpau_h264.c @@ -353,6 +353,13 @@ static int vdpau_decoder_init(video_decoder_t *this_gen) img->duration = this->video_step; img->pts = this->curr_pts; + if (this->dangling_img) { + fprintf(stderr, "broken stream: current img wasn't processed -- freeing it\n!"); + this->dangling_img->free(this->dangling_img); + } + this->dangling_img = img; + this->last_img = img; + this->vdpau_accel = (vdpau_accel_t*)img->accel_data; /*VdpBool is_supported; @@ -370,9 +377,6 @@ static int vdpau_decoder_init(video_decoder_t *this_gen) return 0; } } - this->last_img = img; - this->dangling_img = img; - return 1; } @@ -438,6 +442,10 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v img->duration = this->video_step; img->pts = this->curr_pts; + if (this->dangling_img) { + fprintf(stderr, "broken stream: current img wasn't processed -- freeing it\n!"); + this->dangling_img->free(this->dangling_img); + } this->dangling_img = img; } @@ -446,8 +454,6 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v this->decoder = VDP_INVALID_HANDLE; vdpau_h264_reset(this_gen); this->vdp_runtime_nr = this->vdpau_accel->vdp_runtime_nr; - img->free(img); - img = this->last_img = NULL; return 0; } @@ -471,7 +477,8 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v if(status != VDP_STATUS_OK) { xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Decoder failure: %s\n", this->vdpau_accel->vdp_get_error_string(status)); - img->free(img); + if (this->dangling_img) + this->dangling_img->free(this->dangling_img); img = this->last_img = this->dangling_img = NULL; } else { @@ -700,6 +707,8 @@ static void vdpau_h264_reset (video_decoder_t *this_gen) { this->dangling_img->free(this->dangling_img); this->dangling_img = NULL; } + + this->last_img = NULL; } /* @@ -725,7 +734,6 @@ static void vdpau_h264_dispose (video_decoder_t *this_gen) { this->dangling_img = NULL; } - dpb_free_all( &(this->nal_parser->dpb) ); if (this->decoder != VDP_INVALID_HANDLE) { |