[gegl/video-rejuvenation: 39/60] ff-load: implement video-frame only seeking
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/video-rejuvenation: 39/60] ff-load: implement video-frame only seeking
- Date: Mon, 16 Nov 2015 22:16:45 +0000 (UTC)
commit a4ed23d0bedfedc524f909382c2518989b1e5b04
Author: Øyvind Kolås <pippin gimp org>
Date: Tue Nov 3 02:27:20 2015 +0100
ff-load: implement video-frame only seeking
bin/mrg-ui.c | 45 ++++++++++++++++---------
operations/external/ff-load.c | 74 ++++++++++++++++-------------------------
2 files changed, 58 insertions(+), 61 deletions(-)
---
diff --git a/bin/mrg-ui.c b/bin/mrg-ui.c
index 9081287..9300829 100644
--- a/bin/mrg-ui.c
+++ b/bin/mrg-ui.c
@@ -139,6 +139,8 @@ struct _State {
int is_video;
int frame_no;
+
+ int prev_frame_played;
};
@@ -1006,6 +1008,9 @@ static void gegl_ui (Mrg *mrg, void *data)
if (o->is_video)
{
o->frame_no++;
+ if ((o->frame_no / 50) % 2 == 1)
+ o->frame_no+=250;
+ fprintf (stderr, "\r%i", o->frame_no);
gegl_node_set (o->load, "frame", o->frame_no, NULL);
mrg_queue_draw (o->mrg, NULL);
}
@@ -1027,22 +1032,29 @@ static void gegl_ui (Mrg *mrg, void *data)
{
if (audio->samples > 0)
{
- int i;
- if (!audio_started)
- {
- open_audio (audio->samplerate);
- SDL_PauseAudio(0);
- audio_started = 1;
- }
- for (i = 0; i < audio->samples; i++)
- {
- sdl_add_audio_sample (0, audio->left[i], audio->right[i]);
- }
-
- while ( (audio_post / 4.0) / audio->samplerate < (o->frame_no / fps) - 0.05 )
- {
- g_usleep (100); /* sync audio */
- }
+ int i;
+ if (!audio_started)
+ {
+ open_audio (audio->samplerate);
+ SDL_PauseAudio(0);
+ audio_started = 1;
+ }
+ for (i = 0; i < audio->samples; i++)
+ {
+ sdl_add_audio_sample (0, audio->left[i], audio->right[i]);
+ }
+
+ /* XXX: needs adjustment with seeking enabled
+ */
+#if 0
+ while ( (audio_post / 4.0) / audio->samplerate <
+ (o->frame_no / fps) - 1.0 &&
+ (o->frame_no - o->prev_frame_played) < 2)
+ {
+ g_usleep (100); /* sync audio */
+ }
+#endif
+ o->prev_frame_played = o->frame_no;
}
g_object_unref (audio);
}
@@ -1284,6 +1296,7 @@ static void load_path (State *o)
o->v = 0;
o->is_video = 0;
o->frame_no = 0;
+ o->prev_frame_played = 0;
if (str_has_video_suffix (path))
{
diff --git a/operations/external/ff-load.c b/operations/external/ff-load.c
index 07785fe..fd6d0bb 100644
--- a/operations/external/ff-load.c
+++ b/operations/external/ff-load.c
@@ -185,15 +185,6 @@ init (GeglProperties *o)
ff_cleanup (o);
}
-static glong
-prev_keyframe (Priv *priv, glong frame)
-{
- /* no way to detect previous keyframe at the moment for ffmpeg,
- so we'll just return 0, the first, and a forced reload happens
- */
- return 0;
-}
-
/* maintain list of audio samples */
static int
decode_audio (GeglOperation *operation,
@@ -305,44 +296,30 @@ decode_frame (GeglOperation *operation,
GeglProperties *o = GEGL_PROPERTIES (operation);
Priv *p = (Priv*)o->user_data;
glong prevframe = p->prevframe;
- glong decodeframe; /*< frame to be requested decoded */
+ glong decodeframe = prevframe;
- if (frame >= o->frames)
- {
- frame = o->frames - 1;
- }
if (frame < 0)
{
frame = 0;
}
- if (frame == prevframe)
+ else if (frame >= o->frames)
{
- /* we've already got the right frame ready for delivery */
- return 0;
- }
-
- /* figure out which frame we should start decoding at */
-
- if (frame == prevframe + 1)
- {
- decodeframe = prevframe + 1;
+ frame = o->frames - 1;
}
- else
+ if (frame == prevframe)
{
- decodeframe = prev_keyframe (p, frame);
- if (prevframe > decodeframe && prevframe < frame)
- decodeframe = prevframe + 1;
+ return 0;
}
- if (decodeframe < prevframe + 0.0) // XXX: shuts up gcc
- {
- /* seeking backwards, since it ffmpeg doesn't allow us,. we'll reload the file */
- g_free (p->loadedfilename);
- p->loadedfilename = NULL;
- init (o);
- }
+ decodeframe = frame;
+ if (frame > prevframe + 20 || frame < prevframe )
+ {
+ int64_t seek_target = av_rescale_q ((frame - 16) / o->frame_rate * AV_TIME_BASE, AV_TIME_BASE_Q,
p->video_st->time_base);
+ if (av_seek_frame (p->video_fcontext, p->video_stream, seek_target, (AVSEEK_FLAG_BACKWARD )) < 0)
+ fprintf (stderr, "video seek error!\n");
+ }
- while (decodeframe <= frame)
+ do
{
int got_picture = 0;
do
@@ -368,9 +345,9 @@ decode_frame (GeglOperation *operation,
p->coded_bytes = pkt.size;
p->coded_buf = pkt.data;
}
- decoded_bytes =
- avcodec_decode_video2 (p->video_st->codec, p->lavc_frame,
- &got_picture, &pkt);
+
+ decoded_bytes = avcodec_decode_video2 (p->video_st->codec, p->lavc_frame,
+ &got_picture, &pkt);
if (decoded_bytes < 0)
{
fprintf (stderr, "avcodec_decode_video failed for %s\n",
@@ -381,9 +358,15 @@ decode_frame (GeglOperation *operation,
if(got_picture)
{
if (pkt.pts < 0)
- p->prevpts += av_q2d (p->video_st->time_base);
+ {
+ decodeframe++;
+ fprintf (stderr, "+");
+ }
else
- p->prevpts = pkt.pts * av_q2d (p->video_st->time_base);
+ {
+ p->prevpts = av_frame_get_best_effort_timestamp (p->lavc_frame) * av_q2d
(p->video_st->time_base);
+ decodeframe = round (av_frame_get_best_effort_timestamp (p->lavc_frame) * av_q2d
(p->video_st->time_base) * o->frame_rate) - 1;
+ }
}
p->coded_buf += decoded_bytes;
@@ -391,9 +374,9 @@ decode_frame (GeglOperation *operation,
av_free_packet (&pkt);
}
while (!got_picture);
-
- decodeframe++;
}
+ while (decodeframe < frame);
+
p->prevframe = frame;
return 0;
}
@@ -485,7 +468,7 @@ prepare (GeglOperation *operation)
p->video_context->workaround_bugs = FF_BUG_AUTODETECT;
#if 1
- p->video_context->error_concealment = 0;
+ // p->video_context->error_concealment = 0;
#else
p->video_context->error_concealment = FF_EC_DEBLOCK | FF_EC_GUESS_MVS | FF_EC_FAVOR_INTER;
@@ -602,6 +585,7 @@ static void get_sample_data (Priv *p, long sample_no, float *left, float *right)
{
long no = 0;
GList *l;
+ return;
l = p->audio_track;
if (sample_no < 0)
return;
@@ -661,7 +645,7 @@ process (GeglOperation *operation,
long sample_start = 0;
- if (p->audio_context)
+ if (p->audio_context && 0)
{
o->audio->samplerate = p->audio_context->sample_rate;
o->audio->samples = samples_per_frame (o->frame,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]