diff options
author | Julian Scheel <julian@jusst.de> | 2010-06-13 12:09:22 +0200 |
---|---|---|
committer | Julian Scheel <julian@jusst.de> | 2010-06-13 12:09:22 +0200 |
commit | e62d3d8299c6eaed3b8cc9dc0ed223753495e6ef (patch) | |
tree | 50bcf319b4974fcf92d4e97bc08f477d4e744ad3 | |
parent | 977a841299e853db68fda0386b4c4aeebd52a376 (diff) | |
download | xine-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.c | 28 | ||||
-rw-r--r-- | src/video_dec/libvdpau/dpb.h | 41 | ||||
-rw-r--r-- | src/video_dec/libvdpau/vdpau_h264.c | 11 |
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 && |