Skip to content

Commit

Permalink
Decode last frames for codecs with delay.
Browse files Browse the repository at this point in the history
Previously they would get lost, which would be particularly
extreme when decoding with frame multithreading and lots of threads.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@34860 b3059339-0415-0410-9bf9-f77b7e298cf2
  • Loading branch information
reimar committed Apr 15, 2012
1 parent 0f2c774 commit 79a730e
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 3 deletions.
3 changes: 2 additions & 1 deletion libmpcodecs/vd_ffmpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
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)
Expand All @@ -755,6 +755,7 @@ static mp_image_t *decode(sh_video_t *sh, void *data, int len, int flags){
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);
Expand Down
2 changes: 2 additions & 0 deletions libmpcodecs/vd_mpegpes.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
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;
Expand Down
2 changes: 2 additions & 0 deletions libmpcodecs/vd_zrmjpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ static mp_image_t* decode(sh_video_t *sh, void* data, int len, int flags) {
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;
Expand Down
15 changes: 15 additions & 0 deletions mencoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -433,6 +434,11 @@ static int slowseek(float end_pts, demux_stream_t *d_video,

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;
}
Expand All @@ -454,6 +460,8 @@ static int slowseek(float end_pts, demux_stream_t *d_video,
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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1469,6 +1482,8 @@ case VCODEC_FRAMENO:
((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;
Expand Down
14 changes: 12 additions & 2 deletions mplayer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,7 @@ static int generate_video_frame(sh_video_t *sh_video, demux_stream_t *d_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;
}
Expand Down Expand Up @@ -2425,6 +2426,7 @@ static double update_video(int *blit_frame)
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,
Expand All @@ -2441,6 +2443,11 @@ static double update_video(int *blit_frame)
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)
Expand All @@ -2450,12 +2457,15 @@ static double update_video(int *blit_frame)
#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)
Expand Down

0 comments on commit 79a730e

Please sign in to comment.