summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorJeff Downs <heydowns@borg.com>2007-10-04 06:35:46 +0000
committerAndreas Ă–man <andreas@lonelycoder.com>2007-10-04 06:35:46 +0000
commit8fd57a667b083013156135e88025bc8a37fa6d98 (patch)
tree81c37231e5ddcc4317c6e1a4257a1fdd942fce7c /libavcodec
parentbbb3edb827de21a7c91e38b4ee741f1bbd9062a6 (diff)
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 Originally committed as revision 10659 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/h264.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index fbfb6a1f90..0e26cb1457 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3093,9 +3093,22 @@ static void implicit_weight_table(H264Context *h){
}
}
-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 @@ static inline void unreference_pic(H264Context *h, Picture *pic){
break;
}
}
+ return 1;
+ }
}
/**
@@ -3115,14 +3130,14 @@ static void idr(H264Context *h){
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 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
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 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
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 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
// 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 @@ static int execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){
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");
}