[MPlayer-dev-eng] [PATCH] ve_lavc delayed frames

Loren Merritt lorenm at u.washington.edu
Tue Nov 23 18:20:13 CET 2004


On Mon, 8 Nov 2004, Ivan Kalvachev wrote:
> On Wed, 28 Jul 2004 13:31:50 +0200 Michael Niedermayer wrote:
>
>> see output_example.c in ffmpeg cvs, but u are right pict_type may work too,
>> its just not exactly supposed to be used for this, it could be uninitalzed or
>> coded_frame could be NULL, as no frame has been written yet theres no
>> gurantee that coded_frame contains meaningfull values ...
>
> Whatever pict_type or out_size is better, this should be fixed.
> Az I have commited support for flushing frames at the end of encoding
> (required for xvid4), so ve_lavc could be fixed in the right way.
>
> Loren I have strange feeling that you are mplayer developer, so you can do it...

OK, velavc_flush_b.patch suppresses empty frames (using out_size) and 
flushes delayed frames.
lavc_flush_b.patch makes it not crash on the 2nd pass. (repost from 
ffmpeg-devel).

This works for me, but could probably use more testing.

--Loren Merritt
-------------- next part --------------
Index: libmpcodecs/ve_lavc.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ve_lavc.c,v
retrieving revision 1.104
diff -u -r1.104 ve_lavc.c
--- libmpcodecs/ve_lavc.c	18 Oct 2004 12:26:45 -0000	1.104
+++ libmpcodecs/ve_lavc.c	22 Nov 2004 02:34:54 -0000
@@ -738,11 +738,6 @@
     return 1;
 }
 
-static int control(struct vf_instance_s* vf, int request, void* data){
-
-    return CONTROL_UNKNOWN;
-}
-
 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
     switch(fmt){
     case IMGFMT_YV12:
@@ -780,34 +775,16 @@
     return -10.0*log(d)/log(10);
 }
 
-static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
+static int encode_frame(struct vf_instance_s* vf, AVFrame *pic){
     const char pict_type_char[5]= {'?', 'I', 'P', 'B', 'S'};
     int out_size;
-    AVFrame *pic= vf->priv->pic;
-
-    pic->data[0]=mpi->planes[0];
-    pic->data[1]=mpi->planes[1];
-    pic->data[2]=mpi->planes[2];
-    pic->linesize[0]=mpi->stride[0];
-    pic->linesize[1]=mpi->stride[1];
-    pic->linesize[2]=mpi->stride[2];
-
-#if LIBAVCODEC_BUILD >= 4697
-    if(lavc_param_interlaced_dct){
-        if((mpi->fields & MP_IMGFIELD_ORDERED) && (mpi->fields & MP_IMGFIELD_INTERLACED))
-            pic->top_field_first= !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
-        else 
-            pic->top_field_first= 1;
-    
-        if(lavc_param_top!=-1)
-            pic->top_field_first= lavc_param_top;
-    }
-#endif
 
 	out_size = avcodec_encode_video(lavc_venc_context, mux_v->buffer, mux_v->buffer_size,
 	    pic);
 
-           
+    if(out_size == 0)
+        return 0;
+
     muxer_write_chunk(mux_v,out_size,lavc_venc_context->coded_frame->key_frame?0x10:0);
         
 #if LIBAVCODEC_BUILD >= 4643
@@ -835,7 +812,7 @@
                 perror("fopen");
                 lavc_param_psnr=0; // disable block
                 mp_msg(MSGT_MENCODER,MSGL_ERR,"Can't open %s for writing. Check its permissions.\n",filename);
-                return 0; 
+                return -1;
                 /*exit(1);*/
             }
         }
@@ -870,7 +847,55 @@
     /* store stats if there are any */
     if(lavc_venc_context->stats_out && stats_file) 
         fprintf(stats_file, "%s", lavc_venc_context->stats_out);
-    return 1;
+
+    return out_size;
+}
+
+static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
+    AVFrame *pic= vf->priv->pic;
+
+    pic->data[0]=mpi->planes[0];
+    pic->data[1]=mpi->planes[1];
+    pic->data[2]=mpi->planes[2];
+    pic->linesize[0]=mpi->stride[0];
+    pic->linesize[1]=mpi->stride[1];
+    pic->linesize[2]=mpi->stride[2];
+
+#if LIBAVCODEC_BUILD >= 4697
+    if(lavc_param_interlaced_dct){
+        if((mpi->fields & MP_IMGFIELD_ORDERED) && (mpi->fields & MP_IMGFIELD_INTERLACED))
+            pic->top_field_first= !!(mpi->fields & MP_IMGFIELD_TOP_FIRST);
+        else 
+            pic->top_field_first= 1;
+    
+        if(lavc_param_top!=-1)
+            pic->top_field_first= lavc_param_top;
+    }
+#endif
+
+    return (encode_frame(vf, pic) >= 0);
+}
+
+static void flush_internal_buffers(struct vf_instance_s* vf){
+    int out_size;
+
+    if(!(vf->priv->codec->capabilities & CODEC_CAP_DELAY))
+        return;
+
+    do {
+        out_size = encode_frame(vf, NULL);
+    } while(out_size > 0);
+}
+
+static int control(struct vf_instance_s* vf, int request, void* data){
+
+    switch(request){
+        case VFCTRL_FLUSH_FRAMES:
+            flush_internal_buffers(vf);
+            return CONTROL_TRUE;
+        default:
+            return CONTROL_UNKNOWN;
+    }
 }
 
 static void uninit(struct vf_instance_s* vf){
-------------- next part --------------
Index: libavcodec/mpegvideo.c
===================================================================
RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/mpegvideo.c,v
retrieving revision 1.444
diff -u -r1.444 mpegvideo.c
--- libavcodec/mpegvideo.c	12 Nov 2004 01:21:33 -0000	1.444
+++ libavcodec/mpegvideo.c	22 Nov 2004 02:31:35 -0000
@@ -2015,6 +2015,12 @@
                 for(i=0; i<s->max_b_frames+1; i++){
                     int pict_num= s->input_picture[0]->display_picture_number + i;
                     int pict_type= s->rc_context.entry[pict_num].new_pict_type;
+
+                    if(!s->input_picture[i]){
+                        if(i>0)
+                            s->rc_context.entry[pict_num-1].new_pict_type = P_TYPE;
+                        break;
+                    }
                     s->input_picture[i]->pict_type= pict_type;
                     
                     if(i + 1 >= s->rc_context.num_entries) break;


More information about the MPlayer-dev-eng mailing list