[MPlayer-dev-eng] Precised/exact/to the frame seeking (-ss) in mencoder
Sam Wong
sam at hellosam.net
Wed Apr 11 11:21:55 CEST 2007
On 4/11/07, Attila Kinali <attila at kinali.ch> wrote:
>
> On Tue, 10 Apr 2007 21:41:28 +0200
> Attila Kinali <attila at kinali.ch> wrote:
>
> > On Wed, 11 Apr 2007 03:38:18 +0800
> > Sam Wong <sam at hellosam.net> wrote:
> >
> > > Does that look good?
> >
> > No, asking the exact same question you asked already
> > on -users will not give you any substantialy different
> > answer on -dev-eng.
>
> Please disregard this mail... i was a little bit too fast. ^^;
>
> Attila Kinali
I just hope people won't stop reply because they miss your 2nd message...
I think people are all interested in real contribution, so attached is a
simple patch (against rev 22965) to the mencoder.c that implements the
idea...and surprisingly it works! =)
I didn't have test it throughly yet though, so far I have no problem with
it. and I hope someone could add some comment.
Appreciated if someone could really take a look at this, as I was just
copy-and-pasting the code around, I am expecting minor mistake like
off-by-1-frame error.
Sam
-------------- next part --------------
Index: mencoder.c
===================================================================
--- mencoder.c (revision 22965)
+++ mencoder.c (working copy)
@@ -1708,6 +1708,10 @@
static int edl_seek(edl_record_ptr next_edl_record, demuxer_t* demuxer, demux_stream_t *d_audio, muxer_stream_t* mux_a, s_frame_data * frame_data, int framecopy) {
sh_video_t * sh_video = demuxer->video ? demuxer->video->sh : NULL;
+ float target = next_edl_record->stop_sec - 30;
+ float up_b = next_edl_record->stop_sec;
+ float low_b = 0;
+ if (target < 0) target = up_b;
if (!sh_video) return 0;
if (sh_video->pts >= next_edl_record->stop_sec) return 1; // nothing to do...
@@ -1718,14 +1722,37 @@
//if (vo_vobsub) vobsub_seek(vo_vobsub,sh_video->pts);
resync_video_stream(sh_video);
//if(vo_spudec) spudec_reset(vo_spudec);
- if (audio_delay != 0.0) fixdelay(demuxer->video, d_audio, mux_a, frame_data, framecopy);
+ if (d_audio && audio_delay != 0.0) fixdelay(demuxer->video, d_audio, mux_a, frame_data, framecopy);
return 1;
}
// non-seekable stream.
return 0;
}
+ while (demux_seek(demuxer, target - sh_video->pts, audio_delay, 0)) {
+ frame_data->in_size = video_read_frame(sh_video, &frame_data->frame_time, &frame_data->start, force_fps);
+ if (frame_data->in_size < 0) return 2; // EOF
+
+ // Do bisection
+ mp_msg(MSGT_MENCODER, MSGL_INFO, "hr-edl: bisection seeking: %f > _%f_ < %f, got %f\n",
+ low_b, target, up_b, sh_video->pts);
+ if (sh_video->pts > next_edl_record->stop_sec) { up_b = target; }
+ else if (sh_video->pts < next_edl_record->stop_sec) { low_b = target; }
+
+ if (up_b - low_b < 2.5) break; // Small enough range to do slowseek
+ target = (up_b + low_b) / 2;
+
+ if (frame_data->in_size < 0) return 2;
+ }
+ mp_msg(MSGT_MENCODER, MSGL_INFO,
+ "hr-edl: seeking to the previous seekable point at %f, now slowseek to %f\n",
+ low_b, next_edl_record->stop_sec);
+ frame_data->already_read = 0;
+ demux_seek(demuxer, low_b - sh_video->pts, audio_delay, 0);
+ sh_video->pts = demuxer->video->pts;
+ resync_video_stream(sh_video);
+ if (d_audio && audio_delay != 0.0) fixdelay(demuxer->video, d_audio, mux_a, frame_data, framecopy);
+
// slow seek, read every frame.
-
return slowseek(next_edl_record->stop_sec, demuxer->video, d_audio, mux_a, frame_data, framecopy, 1);
}
More information about the MPlayer-dev-eng
mailing list