Mercurial > mplayer.hg
changeset 34772:d32f75f79517
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.
author | reimar |
---|---|
date | Sun, 15 Apr 2012 15:01:09 +0000 |
parents | 83febd56b681 |
children | 37af463fd7fc |
files | libmpcodecs/vd_ffmpeg.c libmpcodecs/vd_mpegpes.c libmpcodecs/vd_zrmjpeg.c mencoder.c mplayer.c |
diffstat | 5 files changed, 33 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpcodecs/vd_ffmpeg.c Sun Apr 15 13:12:56 2012 +0000 +++ b/libmpcodecs/vd_ffmpeg.c Sun Apr 15 15:01:09 2012 +0000 @@ -731,7 +731,7 @@ 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 @@ 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);
--- a/libmpcodecs/vd_mpegpes.c Sun Apr 15 13:12:56 2012 +0000 +++ b/libmpcodecs/vd_mpegpes.c Sun Apr 15 15:01:09 2012 +0000 @@ -61,6 +61,8 @@ 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;
--- a/libmpcodecs/vd_zrmjpeg.c Sun Apr 15 13:12:56 2012 +0000 +++ b/libmpcodecs/vd_zrmjpeg.c Sun Apr 15 15:01:09 2012 +0000 @@ -232,6 +232,8 @@ 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;
--- a/mencoder.c Sun Apr 15 13:12:56 2012 +0000 +++ b/mencoder.c Sun Apr 15 15:01:09 2012 +0000 @@ -232,6 +232,7 @@ 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 @@ 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 @@ 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 (!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 @@ ((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;
--- a/mplayer.c Sun Apr 15 13:12:56 2012 +0000 +++ b/mplayer.c Sun Apr 15 15:01:09 2012 +0000 @@ -1798,6 +1798,7 @@ 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 @@ 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 @@ 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 @@ #ifdef CONFIG_DVDNAV full_frame = 1; decoded_frame = mp_dvdnav_restore_smpi(&in_size, &start, decoded_frame); +#endif // still frame has been reached, no need to decode - if (in_size > 0 && !decoded_frame) -#endif + 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)