[FFmpeg-devel] [PATCH] img2: added support for %t output pattern
Yuval Adam
yuv.adm at gmail.com
Mon Dec 19 10:21:38 CET 2011
Also reviewable on github:
https://github.com/yuvadm/FFmpeg/commit/3e94df886e63e0c185e5a244fceb0e0a37bf4800
>From 3e94df886e63e0c185e5a244fceb0e0a37bf4800 Mon Sep 17 00:00:00 2001
From: Yuval Adam <yuv.adm at gmail.com>
Date: Mon, 19 Dec 2011 10:46:02 +0200
Subject: [PATCH] img2: added support for %t output pattern
The image2 muxer now supports timestamps in output filenames.
When used in an output patterm '%t' will be replaced with the frames
timestamp in hours, minutes and seconds (hh:mm:ss).
Signed-off-by: Yuval Adam <yuv.adm at gmail.com>
---
doc/muxers.texi | 5 +++++
libavformat/avformat.h | 6 ++++--
libavformat/img2.c | 13 ++++++++-----
libavformat/utils.c | 32 +++++++++++++++++++++++++-------
4 files changed, 42 insertions(+), 14 deletions(-)
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 60a72d6..72212fe 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -109,6 +109,11 @@ If the pattern contains "%d" or "%0 at var{N}d", the
first filename of
the file list specified will contain the number 1, all the following
numbers will be sequential.
+The pattern may also contain "%t", this string specifies the timestamp
+of the frame in hours, minutes and seconds. Note that if two frames are
written at the
+same second, they will be overwritten, yielding a maximum output of 1 fps.
+The "%t" and "%d" patterns may not be used simultaneously.
+
The pattern may contain a suffix which is used to automatically
determine the format of the image files to write.
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 2ed6b56..a9ab0cc 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -2067,7 +2067,8 @@ attribute_deprecated int find_info_tag(char *arg, int
arg_size, const char *tag1
#endif
/**
- * Return in 'buf' the path with '%d' replaced by a number.
+ * Return in 'buf' the path with '%d' replaced by the frame number,
+ * and '%t' replaced by the frame timestamp.
*
* Also handles the '%0nd' format where 'n' is the total number
* of digits and '%%'.
@@ -2076,10 +2077,11 @@ attribute_deprecated int find_info_tag(char *arg,
int arg_size, const char *tag1
* @param buf_size destination buffer size
* @param path numbered sequence string
* @param number frame number
+ * @param ts frame timestamp in seconds
* @return 0 if OK, -1 on format error
*/
int av_get_frame_filename(char *buf, int buf_size,
- const char *path, int number);
+ const char *path, int number, int ts);
/**
* Check whether filename actually is a numbered sequence generator.
diff --git a/libavformat/img2.c b/libavformat/img2.c
index bc35591..8012e5b 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -142,7 +142,7 @@ static int find_image_range(int *pfirst_index, int
*plast_index,
/* find the first image */
for(first_index = 0; first_index < 5; first_index++) {
- if (av_get_frame_filename(buf, sizeof(buf), path, first_index) <
0){
+ if (av_get_frame_filename(buf, sizeof(buf), path, first_index, 0)
< 0){
*pfirst_index =
*plast_index = 1;
if (avio_check(buf, AVIO_FLAG_READ) > 0)
@@ -165,7 +165,7 @@ static int find_image_range(int *pfirst_index, int
*plast_index,
else
range1 = 2 * range;
if (av_get_frame_filename(buf, sizeof(buf), path,
- last_index + range1) < 0)
+ last_index + range1, 0) < 0)
goto fail;
if (avio_check(buf, AVIO_FLAG_READ) <= 0)
break;
@@ -310,7 +310,7 @@ static int read_packet(AVFormatContext *s1, AVPacket
*pkt)
if (s->img_number > s->img_last)
return AVERROR_EOF;
if (av_get_frame_filename(filename, sizeof(filename),
- s->path, s->img_number)<0 &&
s->img_number > 1)
+ s->path, s->img_number, 0)<0 &&
s->img_number > 1)
return AVERROR(EIO);
for(i=0; i<3; i++){
if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
@@ -389,12 +389,15 @@ static int write_packet(AVFormatContext *s, AVPacket
*pkt)
VideoData *img = s->priv_data;
AVIOContext *pb[3];
char filename[1024];
- AVCodecContext *codec= s->streams[ pkt->stream_index ]->codec;
+ AVStream *stream = s->streams[ pkt->stream_index ];
+ AVCodecContext *codec = stream->codec;
int i;
+ int ts = av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q) /
AV_TIME_BASE;
+
if (!img->is_pipe) {
if (av_get_frame_filename(filename, sizeof(filename),
- img->path, img->img_number) < 0 &&
img->img_number>1 && !img->updatefirst) {
+ img->path, img->img_number, ts) < 0 &&
img->img_number>1 && !img->updatefirst) {
av_log(s, AV_LOG_ERROR,
"Could not get frame filename number %d from pattern
'%s'\n",
img->img_number, img->path);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index f0df759..6db2db0 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -319,7 +319,7 @@ int av_append_packet(AVIOContext *s, AVPacket *pkt, int
size)
int av_filename_number_test(const char *filename)
{
char buf[1024];
- return filename && (av_get_frame_filename(buf, sizeof(buf), filename,
1)>=0);
+ return filename && (av_get_frame_filename(buf, sizeof(buf), filename,
1, 0)>=0);
}
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int
*score_ret)
@@ -3774,15 +3774,16 @@ int find_info_tag(char *arg, int arg_size, const
char *tag1, const char *info)
#endif
int av_get_frame_filename(char *buf, int buf_size,
- const char *path, int number)
+ const char *path, int number, int ts)
{
const char *p;
char *q, buf1[20], c;
- int nd, len, percentd_found;
+ int nd, len, percent_found;
+ int hours, mins, secs;
q = buf;
p = path;
- percentd_found = 0;
+ percent_found = 0;
for(;;) {
c = *p++;
if (c == '\0')
@@ -3800,9 +3801,9 @@ int av_get_frame_filename(char *buf, int buf_size,
case '%':
goto addchar;
case 'd':
- if (percentd_found)
+ if (percent_found)
goto fail;
- percentd_found = 1;
+ percent_found = 1;
snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
len = strlen(buf1);
if ((q - buf + len) > buf_size - 1)
@@ -3810,6 +3811,23 @@ int av_get_frame_filename(char *buf, int buf_size,
memcpy(q, buf1, len);
q += len;
break;
+ case 't':
+ if (percent_found)
+ goto fail;
+ percent_found = 1;
+ secs = ts % 60;
+ ts /= 60;
+ mins = ts % 60;
+ ts /= 60;
+ hours = ts;
+ snprintf(buf1, sizeof(buf1),
+ "%02d:%02d:%02d", hours, mins, secs);
+ len = strlen(buf1);
+ if ((q - buf + len) > buf_size - 1)
+ goto fail;
+ memcpy(q, buf1, len);
+ q += len;
+ break;
default:
goto fail;
}
@@ -3819,7 +3837,7 @@ int av_get_frame_filename(char *buf, int buf_size,
*q++ = c;
}
}
- if (!percentd_found)
+ if (!percent_found)
goto fail;
*q = '\0';
return 0;
--
1.7.2.2
--
Yuval Adam
http://y3xz.com
More information about the ffmpeg-devel
mailing list