[MPlayer-cvslog] r34860 - in trunk: libmpcodecs/vd_ffmpeg.c libmpcodecs/vd_mpegpes.c libmpcodecs/vd_zrmjpeg.c mencoder.c mplayer.c

reimar subversion at mplayerhq.hu
Sun Apr 15 17:01:09 CEST 2012


Author: reimar
Date: Sun Apr 15 17:01:09 2012
New Revision: 34860

Log:
Decode last frames for codecs with delay.

Previously they would get lost, which would be particularly
extreme when decoding with frame multithreading and lots of threads.

Modified:
   trunk/libmpcodecs/vd_ffmpeg.c
   trunk/libmpcodecs/vd_mpegpes.c
   trunk/libmpcodecs/vd_zrmjpeg.c
   trunk/mencoder.c
   trunk/mplayer.c

Modified: trunk/libmpcodecs/vd_ffmpeg.c
==============================================================================
--- trunk/libmpcodecs/vd_ffmpeg.c	Sun Apr 15 15:12:56 2012	(r34859)
+++ trunk/libmpcodecs/vd_ffmpeg.c	Sun Apr 15 17:01:09 2012	(r34860)
@@ -731,7 +731,7 @@ static mp_image_t *decode(sh_video_t *sh
     int dr1= ctx->do_dr1;
     AVPacket pkt;
 
-    if(len<=0) return NULL; // skipped frame
+    if(data && len<=0) return NULL; // skipped frame
 
 //ffmpeg interlace (mpeg2) bug have been fixed. no need of -noslices
     if (!dr1)
@@ -755,6 +755,7 @@ static mp_image_t *decode(sh_video_t *sh
             avctx->skip_idct = AVDISCARD_ALL;
     }
 
+    if (data)
     mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "vd_ffmpeg data: %04x, %04x, %04x, %04x\n",
            ((int *)data)[0], ((int *)data)[1], ((int *)data)[2], ((int *)data)[3]);
     av_init_packet(&pkt);

Modified: trunk/libmpcodecs/vd_mpegpes.c
==============================================================================
--- trunk/libmpcodecs/vd_mpegpes.c	Sun Apr 15 15:12:56 2012	(r34859)
+++ trunk/libmpcodecs/vd_mpegpes.c	Sun Apr 15 17:01:09 2012	(r34860)
@@ -61,6 +61,8 @@ static mp_image_t* decode(sh_video_t *sh
     mp_mpeg_header_t picture;
     const unsigned char *d = data;
 
+    if (len <= 0 && !data) return NULL; // delay flush
+
     if(len>10 && !d[0] && !d[1] && d[2]==1 && d[3]==0xB3) {
         float old_aspect = sh->aspect;
         int oldw = sh->disp_w, oldh = sh->disp_h;

Modified: trunk/libmpcodecs/vd_zrmjpeg.c
==============================================================================
--- trunk/libmpcodecs/vd_zrmjpeg.c	Sun Apr 15 15:12:56 2012	(r34859)
+++ trunk/libmpcodecs/vd_zrmjpeg.c	Sun Apr 15 17:01:09 2012	(r34860)
@@ -232,6 +232,8 @@ static mp_image_t* decode(sh_video_t *sh
 	mp_image_t* mpi;
 	vd_zrmjpeg_ctx_t *ctx = sh->context;
 
+	if (len <= 0 && !data) return NULL; // delay flush
+
 	if (!ctx->vo_initialized) {
 		ctx->preferred_csp = guess_mjpeg_type(data, len, sh->disp_h);
 		if (ctx->preferred_csp == 0) return NULL;

Modified: trunk/mencoder.c
==============================================================================
--- trunk/mencoder.c	Sun Apr 15 15:12:56 2012	(r34859)
+++ trunk/mencoder.c	Sun Apr 15 17:01:09 2012	(r34860)
@@ -232,6 +232,7 @@ typedef struct {
     int in_size;
     float frame_time;
     int already_read;
+    int flush;
 } s_frame_data;
 
 static edl_record_ptr edl_records = NULL; ///< EDL entries memory area
@@ -433,6 +434,11 @@ static int slowseek(float end_pts, demux
 
         if (!frame_data->already_read) { // when called after fixdelay, a frame is already read
             frame_data->in_size = video_read_frame(sh_video, &frame_data->frame_time, &frame_data->start, force_fps);
+            frame_data->flush = frame_data->in_size < 0 && d_video->eof;
+            if (frame_data->flush) {
+                frame_data->in_size = 0;
+                frame_data->start = NULL;
+            }
             if(frame_data->in_size<0) return 2;
             sh_video->timer += frame_data->frame_time;
         }
@@ -454,6 +460,8 @@ static int slowseek(float end_pts, demux
             void *decoded_frame = decode_video(sh_video, frame_data->start, frame_data->in_size, !softskip, MP_NOPTS_VALUE, NULL);
 	    if (decoded_frame)
 		filter_video(sh_video, decoded_frame, MP_NOPTS_VALUE);
+	    else if (frame_data->flush)
+		return 2;
         }
 
         if (print_info) mp_msg(MSGT_MENCODER, MSGL_STATUS,
@@ -1392,6 +1400,11 @@ if(sh_audio){
 
     if (!frame_data.already_read) {
         frame_data.in_size=video_read_frame(sh_video,&frame_data.frame_time,&frame_data.start,force_fps);
+        frame_data.flush = frame_data.in_size < 0 && d_video->eof;
+        if (frame_data.flush) {
+            frame_data.in_size = 0;
+            frame_data.start = NULL;
+        }
         sh_video->timer+=frame_data.frame_time;
     }
     frame_data.frame_time /= playback_speed;
@@ -1469,6 +1482,8 @@ default:
                       ((vf_instance_t *)sh_video->vfilter)->control(sh_video->vfilter, VFCTRL_SKIP_NEXT_FRAME, 0) != CONTROL_TRUE);
     void *decoded_frame = decode_video(sh_video,frame_data.start,frame_data.in_size,
                                        drop_frame, MP_NOPTS_VALUE, NULL);
+    if (frame_data.flush && !decoded_frame)
+        at_eof = 1;
     if (did_seek && sh_video->pts != MP_NOPTS_VALUE) {
         did_seek = 0;
         sub_offset = sh_video->pts;

Modified: trunk/mplayer.c
==============================================================================
--- trunk/mplayer.c	Sun Apr 15 15:12:56 2012	(r34859)
+++ trunk/mplayer.c	Sun Apr 15 17:01:09 2012	(r34860)
@@ -1798,6 +1798,7 @@ static int generate_video_frame(sh_video
         if (in_size < 0) {
             // try to extract last frames in case of decoder lag
             in_size = 0;
+            start   = NULL;
             pts     = MP_NOPTS_VALUE;
             hit_eof = 1;
         }
@@ -2425,6 +2426,7 @@ static double update_video(int *blit_fra
         int full_frame;
 
         do {
+            int flush;
             current_module = "video_read_frame";
             frame_time     = sh_video->next_frame_time;
             in_size = video_read_frame(sh_video, &sh_video->next_frame_time,
@@ -2441,6 +2443,11 @@ static double update_video(int *blit_fra
                 mpctx->stream->eof = 0;
             } else
 #endif
+            flush = in_size < 0 && mpctx->d_video->eof;
+            if (flush) {
+                start = NULL;
+                in_size = 0;
+            }
             if (in_size < 0)
                 return -1;
             if (in_size > max_framesize)
@@ -2450,12 +2457,15 @@ static double update_video(int *blit_fra
 #ifdef CONFIG_DVDNAV
             full_frame    = 1;
             decoded_frame = mp_dvdnav_restore_smpi(&in_size, &start, decoded_frame);
-            // still frame has been reached, no need to decode
-            if (in_size > 0 && !decoded_frame)
 #endif
+            // still frame has been reached, no need to decode
+            if ((in_size > 0 || flush) && !decoded_frame)
             decoded_frame = decode_video(sh_video, start, in_size, drop_frame,
                                          sh_video->pts, &full_frame);
 
+            if (flush && !decoded_frame)
+                return -1;
+
             if (full_frame) {
                 sh_video->timer += frame_time;
                 if (mpctx->sh_audio)


More information about the MPlayer-cvslog mailing list