Mercurial > libavcodec.hg
changeset 5768:09b557fcfafb libavcodec
Modify unreference_pic implementation with PAFF in mind.
patch by Jeff Downs, heydowns a borg d com
original thread:
Subject: [FFmpeg-devel] [PATCH] Implement PAFF in H.264
Date: 18/09/07 20:30
author | andoma |
---|---|
date | Thu, 04 Oct 2007 06:35:46 +0000 |
parents | 32b404ec4c19 |
children | 59049863494c |
files | h264.c |
diffstat | 1 files changed, 27 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/h264.c Thu Oct 04 06:33:26 2007 +0000 +++ b/h264.c Thu Oct 04 06:35:46 2007 +0000 @@ -3093,9 +3093,22 @@ } } -static inline void unreference_pic(H264Context *h, Picture *pic){ +/** + * Mark a picture as no longer needed for reference. The refmask + * argument allows unreferencing of individual fields or the whole frame. + * If the picture becomes entirely unreferenced, but is being held for + * display purposes, it is marked as such. + * @param refmask mask of fields to unreference; the mask is bitwise + * anded with the reference marking of pic + * @return non-zero if pic becomes entirely unreferenced (except possibly + * for display purposes) zero if one of the fields remains in + * reference + */ +static inline int unreference_pic(H264Context *h, Picture *pic, int refmask){ int i; - pic->reference=0; + if (pic->reference &= refmask) { + return 0; + } else { if(pic == h->delayed_output_pic) pic->reference=DELAYED_PIC_REF; else{ @@ -3105,6 +3118,8 @@ break; } } + return 1; + } } /** @@ -3115,14 +3130,14 @@ for(i=0; i<16; i++){ if (h->long_ref[i] != NULL) { - unreference_pic(h, h->long_ref[i]); + unreference_pic(h, h->long_ref[i], 0); h->long_ref[i]= NULL; } } h->long_ref_count=0; for(i=0; i<h->short_ref_count; i++){ - unreference_pic(h, h->short_ref[i]); + unreference_pic(h, h->short_ref[i], 0); h->short_ref[i]= NULL; } h->short_ref_count=0; @@ -3234,13 +3249,13 @@ case MMCO_SHORT2UNUSED: pic= remove_short(h, mmco[i].short_pic_num); if(pic) - unreference_pic(h, pic); + unreference_pic(h, pic, 0); else if(s->avctx->debug&FF_DEBUG_MMCO) av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_short() failure\n"); break; case MMCO_SHORT2LONG: pic= remove_long(h, mmco[i].long_arg); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); h->long_ref[ mmco[i].long_arg ]= remove_short(h, mmco[i].short_pic_num); if (h->long_ref[ mmco[i].long_arg ]){ @@ -3251,13 +3266,13 @@ case MMCO_LONG2UNUSED: pic= remove_long(h, mmco[i].long_arg); if(pic) - unreference_pic(h, pic); + unreference_pic(h, pic, 0); else if(s->avctx->debug&FF_DEBUG_MMCO) av_log(h->s.avctx, AV_LOG_DEBUG, "mmco: remove_long() failure\n"); break; case MMCO_LONG: pic= remove_long(h, mmco[i].long_arg); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); h->long_ref[ mmco[i].long_arg ]= s->current_picture_ptr; h->long_ref[ mmco[i].long_arg ]->long_ref=1; @@ -3270,17 +3285,17 @@ // just remove the long term which index is greater than new max for(j = mmco[i].long_arg; j<16; j++){ pic = remove_long(h, j); - if (pic) unreference_pic(h, pic); + if (pic) unreference_pic(h, pic, 0); } break; case MMCO_RESET: while(h->short_ref_count){ pic= remove_short(h, h->short_ref[0]->frame_num); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); } for(j = 0; j < 16; j++) { pic= remove_long(h, j); - if(pic) unreference_pic(h, pic); + if(pic) unreference_pic(h, pic, 0); } break; default: assert(0); @@ -3290,7 +3305,7 @@ if(!current_is_long){ pic= remove_short(h, s->current_picture_ptr->frame_num); if(pic){ - unreference_pic(h, pic); + unreference_pic(h, pic, 0); av_log(h->s.avctx, AV_LOG_ERROR, "illegal short term buffer state detected\n"); }