diff options
author | Julian Scheel <julian@jusst.de> | 2010-01-30 12:45:49 +0100 |
---|---|---|
committer | Julian Scheel <julian@jusst.de> | 2010-01-30 12:45:49 +0100 |
commit | 474815e24bf5ed57813bab2c970bce13ad822e3c (patch) | |
tree | 97e1e0e12fe9a6d5e49683d5b4fd16006e13ee87 | |
parent | aba6adc0529ceed3406faabdc682efab035ef5ca (diff) | |
download | xine-lib-474815e24bf5ed57813bab2c970bce13ad822e3c.tar.gz xine-lib-474815e24bf5ed57813bab2c970bce13ad822e3c.tar.bz2 |
fix a memleak with interlaced content
some minor cleanups
-rw-r--r-- | src/video_dec/libvdpau/dpb.c | 54 | ||||
-rw-r--r-- | src/video_dec/libvdpau/dpb.h | 5 | ||||
-rw-r--r-- | src/video_dec/libvdpau/h264_parser.c | 9 | ||||
-rw-r--r-- | src/video_dec/libvdpau/vdpau_h264.c | 29 |
4 files changed, 65 insertions, 32 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; diff --git a/src/video_dec/libvdpau/dpb.h b/src/video_dec/libvdpau/dpb.h index 9a667b79f..9881ebccb 100644 --- a/src/video_dec/libvdpau/dpb.h +++ b/src/video_dec/libvdpau/dpb.h @@ -50,6 +50,8 @@ struct decoded_picture { uint8_t delayed_output; struct decoded_picture *next; + + uint32_t lock_counter; }; /* Decoded Picture Buffer */ @@ -62,7 +64,8 @@ struct dpb { struct decoded_picture* init_decoded_picture(struct coded_picture *cpic, VdpVideoSurface surface, vo_frame_t *img); -void free_decoded_picture(struct decoded_picture *pic); +void release_decoded_picture(struct decoded_picture *pic); +void lock_decoded_picture(struct decoded_picture *pic); void dpb_add_coded_picture(struct decoded_picture *pic, struct coded_picture *cpic); diff --git a/src/video_dec/libvdpau/h264_parser.c b/src/video_dec/libvdpau/h264_parser.c index 505891caf..d26d53f0c 100644 --- a/src/video_dec/libvdpau/h264_parser.c +++ b/src/video_dec/libvdpau/h264_parser.c @@ -1541,11 +1541,6 @@ struct h264_parser* init_parser(xine_t *xine) parser->xine = xine; memset(&parser->dpb, 0x00, sizeof(struct dpb)); - /* no idea why we do that. inspired by libavcodec, - * as we couldn't figure in the specs.... - */ - parser->prev_pic_order_cnt_msb = 1 << 16; - return parser; } @@ -1561,7 +1556,7 @@ void reset_parser(struct h264_parser *parser) } parser->last_vcl_nal = NULL; - parser->prev_pic_order_cnt_msb = 1 << 16; + parser->prev_pic_order_cnt_msb = 0; parser->prev_pic_order_cnt_lsb = 0; parser->frame_num_offset = 0; parser->prev_top_field_order_cnt = 0; @@ -1898,7 +1893,7 @@ int parse_nal(uint8_t *buf, int buf_len, struct h264_parser *parser, } /* increase the slice_cnt until a new frame is detected */ - if (ret) { + if (ret && *completed_picture == NULL) { *completed_picture = parser->pic; parser->pic = create_coded_picture(); } diff --git a/src/video_dec/libvdpau/vdpau_h264.c b/src/video_dec/libvdpau/vdpau_h264.c index 6341a1b9a..e20ac2ac9 100644 --- a/src/video_dec/libvdpau/vdpau_h264.c +++ b/src/video_dec/libvdpau/vdpau_h264.c @@ -396,7 +396,10 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v // picture? - should we keep the first field in dpb? if(this->completed_pic->flag_mask & IDR_PIC) { dpb_flush(&(this->nal_parser->dpb)); - this->last_ref_pic = NULL; + if(this->last_ref_pic) { + release_decoded_picture(this->last_ref_pic); + this->last_ref_pic = NULL; + } } VdpPictureInfoH264 pic; @@ -471,8 +474,8 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v VdpVideoSurface surface = this->vdpau_accel->surface; - //xprintf(this->xine, XINE_VERBOSITY_DEBUG, - // "Decode: NUM: %d, REF: %d, BYTES: %d, PTS: %lld\n", pic.frame_num, pic.is_reference, vdp_buffer->bitstream_bytes, this->completed_pic->pts); + /*xprintf(this->xine, XINE_VERBOSITY_DEBUG, + "Decode: NUM: %d, REF: %d, BYTES: %d, PTS: %lld\n", pic.frame_num, pic.is_reference, vdp_buffer->bitstream_bytes, this->completed_pic->pts);*/ VdpStatus status = this->vdpau_accel->vdp_decoder_render(this->decoder, surface, (VdpPictureInfo*)&pic, 1, vdp_buffer); @@ -529,16 +532,19 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v if(!slc->field_pic_flag || !this->wait_for_bottom_field) { decoded_pic = init_decoded_picture(this->completed_pic, surface, img); this->completed_pic = NULL; + if(this->last_ref_pic) { + release_decoded_picture(this->last_ref_pic); + this->last_ref_pic = NULL; + } this->last_ref_pic = decoded_pic; + lock_decoded_picture(this->last_ref_pic); decoded_pic->used_for_reference = 1; dpb_add_picture(&(this->nal_parser->dpb), decoded_pic, sps->num_ref_frames); this->dangling_img = NULL; } else if(slc->field_pic_flag && this->wait_for_bottom_field) { if(this->last_ref_pic) { decoded_pic = this->last_ref_pic; - //copy_nal_unit(decoded_pic->nal, this->nal_parser->current_nal); - - dpb_add_coded_picture(this->last_ref_pic, this->completed_pic); + dpb_add_coded_picture(decoded_pic, this->completed_pic); this->completed_pic = NULL; } } @@ -550,7 +556,7 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v if(!decoded_pic) { decoded_pic = init_decoded_picture(this->completed_pic, surface, img); this->completed_pic = NULL; - //decoded_pic->nal->top_field_order_cnt = this->last_top_field_order_cnt; + dpb_add_picture(&(this->nal_parser->dpb), decoded_pic, sps->num_ref_frames); this->dangling_img = NULL; } @@ -570,10 +576,13 @@ static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *v this->wait_for_bottom_field = 0; } else if(slc->field_pic_flag && !slc->bottom_field_flag) { - // don't draw yet, second field is missing. - //this->last_top_field_order_cnt = this->nal_parser->completed_pic->top_field_order_cnt; + /* don't draw yet, second field is missing. */ this->wait_for_bottom_field = 1; this->last_img = img; + if(this->completed_pic) { + free_coded_picture(this->completed_pic); + } + this->completed_pic = NULL; } } @@ -664,6 +673,8 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, this->completed_pic->slc_nal != NULL && this->completed_pic->pps_nal != NULL) { vdpau_decoder_render(this_gen, &vdp_buffer, this->completed_pic->slice_cnt); + } else if (this->completed_pic != NULL) { + free_coded_picture(this->completed_pic); } /* in case the last nal was detected as END_OF_SEQUENCE |