summaryrefslogtreecommitdiff
path: root/src/video_dec/libvdpau/dpb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_dec/libvdpau/dpb.c')
-rw-r--r--src/video_dec/libvdpau/dpb.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/src/video_dec/libvdpau/dpb.c b/src/video_dec/libvdpau/dpb.c
index 819f1f9a2..509075134 100644
--- a/src/video_dec/libvdpau/dpb.c
+++ b/src/video_dec/libvdpau/dpb.c
@@ -30,6 +30,8 @@
#include <xine/video_out.h>
+void free_decoded_picture(struct decoded_picture *pic);
+
struct decoded_picture* init_decoded_picture(struct coded_picture *cpic,
VdpVideoSurface surface, vo_frame_t *img)
{
@@ -43,6 +45,7 @@ struct decoded_picture* init_decoded_picture(struct coded_picture *cpic,
pic->surface = surface;
pic->img = img;
pic->delayed_output = 1;
+ pic->lock_counter = 1;
return pic;
}
@@ -64,12 +67,32 @@ void dpb_add_coded_picture(struct decoded_picture *pic,
}
}
+void release_decoded_picture(struct decoded_picture *pic)
+{
+ if(!pic)
+ return;
+
+ pic->lock_counter--;
+
+ if(pic->lock_counter <= 0) {
+ free_decoded_picture(pic);
+ }
+}
+
+void lock_decoded_picture(struct decoded_picture *pic)
+{
+ if(!pic)
+ return;
+
+ pic->lock_counter++;
+}
+
void free_decoded_picture(struct decoded_picture *pic)
{
pic->img->free(pic->img);
+ free_coded_picture(pic->coded_pic[1]);
free_coded_picture(pic->coded_pic[0]);
pic->coded_pic[0] = NULL;
- free_coded_picture(pic->coded_pic[1]);
pic->coded_pic[1] = NULL;
free(pic);
}
@@ -127,13 +150,6 @@ struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb, int do_flush)
} while ((pic = pic->next) != NULL);
}
- int32_t out_top_field_order_cnt = outpic != NULL ?
- outpic->coded_pic[0]->top_field_order_cnt : 0;
- int32_t out_bottom_field_order_cnt = outpic != NULL ?
- (outpic->coded_pic[1] != NULL ?
- outpic->coded_pic[1]->bottom_field_order_cnt :
- outpic->coded_pic[0]->top_field_order_cnt) : 0;
-
return outpic;
}
@@ -327,7 +343,7 @@ int dpb_set_unused_ref_picture_lidx_gt(struct dpb *dpb, int32_t longterm_idx)
int dpb_set_output_picture(struct dpb *dpb, struct decoded_picture *outpic)
{
- struct decoded_picture *pic = dpb->pictures;
+ /*struct decoded_picture *pic = dpb->pictures;
if (pic != NULL)
do {
if (pic == outpic) {
@@ -336,9 +352,15 @@ int dpb_set_output_picture(struct dpb *dpb, struct decoded_picture *outpic)
dpb_remove_picture(dpb, pic);
return 0;
}
- } while ((pic = pic->next) != NULL);
+ } while ((pic = pic->next) != NULL);*/
+ if(!outpic)
+ return -1;
- return -1;
+ outpic->delayed_output = 0;
+ if(!outpic->used_for_reference)
+ dpb_remove_picture(dpb, outpic);
+
+ return 0;
}
int dpb_remove_picture(struct dpb *dpb, struct decoded_picture *rempic)
@@ -353,7 +375,7 @@ int dpb_remove_picture(struct dpb *dpb, struct decoded_picture *rempic)
last_pic->next = pic->next;
else
dpb->pictures = pic->next;
- free_decoded_picture(pic);
+ release_decoded_picture(pic);
dpb->used--;
return 0;
}
@@ -376,7 +398,7 @@ static int dpb_remove_picture_by_img(struct dpb *dpb, vo_frame_t *remimg)
last_pic->next = pic->next;
else
dpb->pictures = pic->next;
- free_decoded_picture(pic);
+ release_decoded_picture(pic);
dpb->used--;
return 0;
}
@@ -460,7 +482,7 @@ void dpb_free_all( struct dpb *dpb )
if (pic != NULL)
do {
struct decoded_picture *next_pic = pic->next;
- free_decoded_picture(pic);
+ release_decoded_picture(pic);
--dpb->used;
pic = next_pic;
} while (pic != NULL);
@@ -493,7 +515,9 @@ int fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist)
reflist[i].is_long_term = pic->coded_pic[0]->used_for_long_term_ref ||
(pic->coded_pic[1] != NULL && pic->coded_pic[1]->used_for_long_term_ref);
- reflist[i].frame_idx = pic->coded_pic[0]->slc_nal->slc.frame_num;
+ reflist[i].frame_idx = pic->coded_pic[0]->used_for_long_term_ref ?
+ pic->coded_pic[0]->long_term_pic_num :
+ pic->coded_pic[0]->slc_nal->slc.frame_num;
reflist[i].top_is_reference = pic->top_is_reference;
reflist[i].bottom_is_reference = pic->bottom_is_reference;
reflist[i].field_order_cnt[0] = pic->coded_pic[0]->top_field_order_cnt;