summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Scheel <julian@jusst.de>2010-06-13 12:09:22 +0200
committerJulian Scheel <julian@jusst.de>2010-06-13 12:09:22 +0200
commite62d3d8299c6eaed3b8cc9dc0ed223753495e6ef (patch)
tree50bcf319b4974fcf92d4e97bc08f477d4e744ad3
parent977a841299e853db68fda0386b4c4aeebd52a376 (diff)
downloadxine-lib-e62d3d8299c6eaed3b8cc9dc0ed223753495e6ef.tar.gz
xine-lib-e62d3d8299c6eaed3b8cc9dc0ed223753495e6ef.tar.bz2
limit dpb size
- never exceed hard limit of 16 frames in dpb - use max_dec_frame_buffering parameter when set
-rw-r--r--src/video_dec/libvdpau/dpb.c28
-rw-r--r--src/video_dec/libvdpau/dpb.h41
-rw-r--r--src/video_dec/libvdpau/vdpau_h264.c11
3 files changed, 64 insertions, 16 deletions
diff --git a/src/video_dec/libvdpau/dpb.c b/src/video_dec/libvdpau/dpb.c
index 1a506fef0..e4be817b0 100644
--- a/src/video_dec/libvdpau/dpb.c
+++ b/src/video_dec/libvdpau/dpb.c
@@ -174,11 +174,29 @@ struct dpb* create_dpb()
dpb->output_list = xine_list_new();
dpb->reference_list = xine_list_new();
- dpb->output_list_size = MAX_REORDER_COUNT;
+ dpb->max_reorder_frames = MAX_DPB_COUNT;
+ dpb->max_dpb_frames = MAX_DPB_COUNT;
return dpb;
}
+int dpb_total_frames(struct dpb *dpb)
+{
+ int num_frames = xine_list_size(dpb->output_list);
+
+ xine_list_iterator_t ite = xine_list_front(dpb->reference_list);
+ while(ite) {
+ struct decoded_picture *pic = xine_list_get_value(dpb->reference_list, ite);
+ if (xine_list_find(dpb->output_list, pic) == NULL) {
+ num_frames++;
+ }
+
+ ite = xine_list_next(dpb->reference_list, ite);
+ }
+
+ return num_frames;
+}
+
void release_dpb(struct dpb *dpb)
{
if(!dpb)
@@ -197,7 +215,9 @@ struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb, int do_flush)
struct decoded_picture *pic = NULL;;
struct decoded_picture *outpic = NULL;
- if(!do_flush && xine_list_size(dpb->output_list) < dpb->output_list_size) {
+ if(!do_flush &&
+ xine_list_size(dpb->output_list) < dpb->max_reorder_frames &&
+ dpb_total_frames(dpb) < dpb->max_dpb_frames) {
return NULL;
}
@@ -494,7 +514,9 @@ int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_r
}
}
- printf("DPB list sizes: Output: %2d, Reference: %2d\n", xine_list_size(dpb->output_list), xine_list_size(dpb->reference_list));
+ printf("DPB list sizes: Total: %2d, Output: %2d, Reference: %2d\n",
+ dpb_total_frames(dpb), xine_list_size(dpb->output_list),
+ xine_list_size(dpb->reference_list));
return 0;
}
diff --git a/src/video_dec/libvdpau/dpb.h b/src/video_dec/libvdpau/dpb.h
index 472a3e649..e8635ff75 100644
--- a/src/video_dec/libvdpau/dpb.h
+++ b/src/video_dec/libvdpau/dpb.h
@@ -23,7 +23,7 @@
#ifndef DPB_H_
#define DPB_H_
-#define MAX_REORDER_COUNT 16
+#define MAX_DPB_COUNT 16
#include "nal.h"
#include "cpb.h"
@@ -32,6 +32,12 @@
#define USED_FOR_REF (top_is_reference || bottom_is_reference)
+/**
+ * ----------------------------------------------------------------------------
+ * decoded picture
+ * ----------------------------------------------------------------------------
+ */
+
struct decoded_picture {
vo_frame_t *img; /* this is the image we block, to make sure
* the surface is not double-used */
@@ -51,25 +57,40 @@ struct decoded_picture {
uint32_t lock_counter;
};
+struct decoded_picture* init_decoded_picture(struct coded_picture *cpic,
+ vo_frame_t *img);
+void release_decoded_picture(struct decoded_picture *pic);
+void lock_decoded_picture(struct decoded_picture *pic);
+void decoded_pic_check_reference(struct decoded_picture *pic);
+void decoded_pic_add_field(struct decoded_picture *pic,
+ struct coded_picture *cpic);
+
+
+/**
+ * ----------------------------------------------------------------------------
+ * dpb code starting here
+ * ----------------------------------------------------------------------------
+ */
+
/* Decoded Picture Buffer */
struct dpb {
xine_list_t *reference_list;
xine_list_t *output_list;
- int output_list_size;
+ int max_reorder_frames;
+ int max_dpb_frames;
};
struct dpb* create_dpb();
void release_dpb(struct dpb *dpb);
-struct decoded_picture* init_decoded_picture(struct coded_picture *cpic,
- vo_frame_t *img);
-void release_decoded_picture(struct decoded_picture *pic);
-void lock_decoded_picture(struct decoded_picture *pic);
-void decoded_pic_check_reference(struct decoded_picture *pic);
-void decoded_pic_add_field(struct decoded_picture *pic,
- struct coded_picture *cpic);
-
+/**
+ * calculates the total number of frames in the dpb
+ * when frames are used for reference and are not drawn
+ * yet the result would be less then reference_list-size+
+ * output_list-size
+ */
+int dpb_total_frames(struct dpb *dpb);
struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb, int do_flush);
diff --git a/src/video_dec/libvdpau/vdpau_h264.c b/src/video_dec/libvdpau/vdpau_h264.c
index 1bfe5bcc6..aec79886e 100644
--- a/src/video_dec/libvdpau/vdpau_h264.c
+++ b/src/video_dec/libvdpau/vdpau_h264.c
@@ -629,7 +629,7 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v
/* draw the next frame in display order */
if (draw_frame) {
- if ((decoded_pic = dpb_get_next_out_picture(this->nal_parser->dpb, 0)) != NULL) {
+ while ((decoded_pic = dpb_get_next_out_picture(this->nal_parser->dpb, 0)) != NULL) {
decoded_pic->img->top_field_first = dp_top_field_first(decoded_pic);
decoded_pic->img->draw(decoded_pic->img, this->stream);
dpb_unmark_picture_delayed(this->nal_parser->dpb, decoded_pic);
@@ -724,10 +724,15 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen,
this->completed_pic->sps_nal != NULL &&
this->completed_pic->sps_nal->sps.vui_parameters_present_flag &&
this->completed_pic->sps_nal->sps.vui_parameters.bitstream_restriction_flag) {
- this->nal_parser->dpb->output_list_size =
+
+ this->nal_parser->dpb->max_reorder_frames =
this->completed_pic->sps_nal->sps.vui_parameters.num_reorder_frames + 1;
+ this->nal_parser->dpb->max_dpb_frames = this->completed_pic->sps_nal->sps.vui_parameters.max_dec_frame_buffering;
+
xprintf(this->xine, XINE_VERBOSITY_DEBUG,
- "Reorder count: %d\n", this->nal_parser->dpb->output_list_size);
+ "max reorder count: %d, max dpb count\n",
+ this->nal_parser->dpb->max_reorder_frames,
+ this->nal_parser->dpb->max_dpb_frames);
}
if(this->decoder != VDP_INVALID_HANDLE &&