Hi,
Since I needed a looping overlay I patched vsrc_movie and added
an extra timestamp option where the overlay movie should stop
and restart at the given start timestamp.
Zeger Knops
Index: vsrc_movie.c
===================================================================
--- vsrc_movie.c (revision 4305)
+++ vsrc_movie.c (working copy)
@@ -30,6 +30,7 @@
typedef struct {
// Filter parameters
int64_t seek_point; //< seekpoint in microseconds
+ int64_t loop; //< start loop in microseconds
char format_name[16];
char file_name[255];
// Needed to load movies
@@ -38,7 +39,7 @@
AVCodecContext *codec_ctx;
int is_done;
AVFrame *frame;
-
+ int loop_cnt, pck_cnt;
int w, h;
AVFilterPicRef *pic;
} MovieContext;
@@ -131,9 +132,9 @@
MovieContext *mv = ctx->priv;
if(args) {
- int num_fields = sscanf(args, "%"PRId64":%15[^:]:%255s",
- &mv->seek_point, mv->format_name, mv->file_name);
- if (3 == num_fields)
+ int num_fields = sscanf(args, "%"PRId64":%15[^:]:%255[^:]:%"PRId64,
+ &mv->seek_point, mv->format_name, mv->file_name, &mv->loop);
+ if (num_fields > 2)
/* av_log(ctx, AV_LOG_INFO,
"init() args:'%s'\n\tseek:%lld format:%s name:%s\n",
args, mv->seek_point, mv->format_name, mv->file_name); */
@@ -142,7 +143,7 @@
return movie_init(ctx);
}
else
- av_log(ctx, AV_LOG_ERROR, "init() expected 3 arguments:'%s'\n", args);
+ av_log(ctx, AV_LOG_ERROR, "init() expected at least 3 arguments:'%s'\n", args);
return -1;
}
@@ -165,6 +166,21 @@
return 0;
}
+static void reset_loop( AVFilterLink *link )
+{
+ int64_t timestamp;
+
+ MovieContext *mv = link->src->priv;
+
+ // seek to seek point to start loop
+ timestamp = mv->seek_point;
+ // add the stream start time, should it exist
+ if (mv->format_ctx->start_time != AV_NOPTS_VALUE)
+ timestamp += mv->format_ctx->start_time;
+ av_seek_frame(mv->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD);
+ mv->loop_cnt++;
+}
+
int movie_get_frame(AVFilterLink *link)
{
AVPacket packet;
@@ -195,14 +211,17 @@
sizeof(mv->frame->linesize));
// Advance in the time line
- mv->pic->pts = av_rescale_q(packet.pts,
+ mv->pic->pts = av_rescale_q(packet.pts + mv->loop_cnt * ( mv->pck_cnt + 1 ),
mv->format_ctx->streams[mv->video_stream]->time_base,
AV_TIME_BASE_Q);
- /* av_log(link->src, AV_LOG_INFO,
- "movie_get_frame(%s) packet pts:%lld %lf vfpts:%lld\n",
- mv->file_name, packet.pts, (double)packet.pts *
- av_q2d(mv->format_ctx->streams[mv->video_stream]->time_base),
- mv->pic->pts);*/
+
+ if ( !mv->loop_cnt )
+ mv->pck_cnt++;
+
+ if ( mv->loop && av_rescale_q(packet.pts,
+ mv->format_ctx->streams[mv->video_stream]->time_base,
+ AV_TIME_BASE_Q) > mv->loop )
+ reset_loop( link );
// We got it. Free the packet since we are returning
av_free_packet(&packet);
@@ -207,6 +226,12 @@
// We got it. Free the packet since we are returning
av_free_packet(&packet);
+ /*av_log(link->src, AV_LOG_INFO,
+ "movie_get_frame(%s) packet pts:%lld %lf vfpts:%lld\n",
+ mv->file_name, packet.pts, (double)packet.pts *
+ av_q2d(mv->format_ctx->streams[mv->video_stream]->time_base),
+ mv->pic->pts);*/
+
return 0;
}
}
@@ -213,9 +238,14 @@
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
- // On multi-frame source we should stop the mixing process when
- // the movie source does not have more frames
- mv->is_done = 1;
+
+ if ( mv->loop )
+ reset_loop( link );
+ else
+ // On multi-frame source we should stop the mixing process when
+ // the movie source does not have more frames
+ mv->is_done = 1;
+
return 0;
}
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc