[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