diff --git a/doc/muxers.texi b/doc/muxers.texi
index e77055e7ef..91997bd4fa 100644
|
a
|
b
|
If the pattern contains "%d" or "%0@var{N}d", the first filename of
|
| 1384 | 1384 | the file list specified will contain the number 1, all the following |
| 1385 | 1385 | numbers will be sequential. |
| 1386 | 1386 | |
| | 1387 | The pattern can also contain "%t" which writes out the timestamp of the |
| | 1388 | frame in the format "HH.mm.ss.fff" |
| | 1389 | |
| 1387 | 1390 | The pattern may contain a suffix which is used to automatically |
| 1388 | 1391 | determine the format of the image files to write. |
| 1389 | 1392 | |
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index cd7b0d941c..513de9e477 100644
|
a
|
b
|
void av_dump_format(AVFormatContext *ic,
|
| 2602 | 2602 | * @param path numbered sequence string |
| 2603 | 2603 | * @param number frame number |
| 2604 | 2604 | * @param flags AV_FRAME_FILENAME_FLAGS_* |
| | 2605 | * @param ts frame timestamp in seconds |
| 2605 | 2606 | * @return 0 if OK, -1 on format error |
| 2606 | 2607 | */ |
| 2607 | 2608 | int av_get_frame_filename2(char *buf, int buf_size, |
| 2608 | | const char *path, int number, int flags); |
| | 2609 | const char *path, int number, int flags, int64_t ts); |
| 2609 | 2610 | |
| 2610 | 2611 | int av_get_frame_filename(char *buf, int buf_size, |
| 2611 | 2612 | const char *path, int number); |
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index 7b5133d300..55dca272ea 100644
|
a
|
b
|
static int write_packet(AVFormatContext *s, AVPacket *pkt)
|
| 131 | 131 | AVIOContext *pb[4] = {0}; |
| 132 | 132 | char filename[1024]; |
| 133 | 133 | AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar; |
| | 134 | AVStream *stream = s->streams[ pkt->stream_index ]; |
| 134 | 135 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(par->format); |
| 135 | 136 | int ret, i; |
| 136 | 137 | int nb_renames = 0; |
| | 138 | int64_t ts = av_rescale_q(pkt->pts, stream->time_base, AV_TIME_BASE_Q); |
| 137 | 139 | AVDictionary *options = NULL; |
| 138 | 140 | |
| 139 | 141 | if (img->update) { |
| … |
… |
static int write_packet(AVFormatContext *s, AVPacket *pkt)
|
| 148 | 150 | return AVERROR(EINVAL); |
| 149 | 151 | } |
| 150 | 152 | } else if (img->frame_pts) { |
| 151 | | if (av_get_frame_filename2(filename, sizeof(filename), img->path, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) { |
| | 153 | if (av_get_frame_filename2(filename, sizeof(filename), img->path, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE, 0) < 0) { |
| 152 | 154 | av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames."); |
| 153 | 155 | return AVERROR(EINVAL); |
| 154 | 156 | } |
| 155 | 157 | } else if (av_get_frame_filename2(filename, sizeof(filename), img->path, |
| 156 | | img->img_number, |
| 157 | | AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0 && |
| | 158 | img->img_number, 0, |
| | 159 | ts) < 0 && |
| 158 | 160 | img->img_number > 1) { |
| 159 | 161 | av_log(s, AV_LOG_ERROR, |
| 160 | 162 | "Could not get frame filename number %d from pattern '%s'. " |
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0df14682a4..d2e7cb7d34 100644
|
a
|
b
|
uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
|
| 4589 | 4589 | return (sec * 1000000) + usec; |
| 4590 | 4590 | } |
| 4591 | 4591 | |
| 4592 | | int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags) |
| | 4592 | int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags, int64_t ts) |
| 4593 | 4593 | { |
| 4594 | 4594 | const char *p; |
| 4595 | 4595 | char *q, buf1[20], c; |
| 4596 | | int nd, len, percentd_found; |
| | 4596 | int nd, len, percentd_found, percentt_found; |
| | 4597 | int hours, mins, secs, ms; |
| 4597 | 4598 | |
| 4598 | 4599 | q = buf; |
| 4599 | 4600 | p = path; |
| 4600 | 4601 | percentd_found = 0; |
| | 4602 | percentt_found = 0; |
| 4601 | 4603 | for (;;) { |
| 4602 | 4604 | c = *p++; |
| 4603 | 4605 | if (c == '\0') |
| … |
… |
int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number
|
| 4629 | 4631 | memcpy(q, buf1, len); |
| 4630 | 4632 | q += len; |
| 4631 | 4633 | break; |
| | 4634 | case 't': |
| | 4635 | if (percentd_found) |
| | 4636 | goto fail; |
| | 4637 | if (ts < 0) |
| | 4638 | goto fail; |
| | 4639 | percentt_found = 1; |
| | 4640 | ms = (ts/1000)%1000; |
| | 4641 | ts /= AV_TIME_BASE; |
| | 4642 | secs = ts % 60; |
| | 4643 | ts /= 60; |
| | 4644 | mins = ts % 60; |
| | 4645 | ts /= 60; |
| | 4646 | hours = ts; |
| | 4647 | snprintf(buf1, sizeof(buf1), |
| | 4648 | "%02d.%02d.%02d.%03d", hours, mins, secs, ms); |
| | 4649 | len = strlen(buf1); |
| | 4650 | if ((q - buf + len) > buf_size - 1) |
| | 4651 | goto fail; |
| | 4652 | memcpy(q, buf1, len); |
| | 4653 | q += len; |
| | 4654 | break; |
| 4632 | 4655 | default: |
| 4633 | 4656 | goto fail; |
| 4634 | 4657 | } |
| … |
… |
addchar:
|
| 4638 | 4661 | *q++ = c; |
| 4639 | 4662 | } |
| 4640 | 4663 | } |
| 4641 | | if (!percentd_found) |
| | 4664 | if (!(percentd_found || percentt_found)) |
| 4642 | 4665 | goto fail; |
| 4643 | 4666 | *q = '\0'; |
| 4644 | 4667 | return 0; |
| … |
… |
fail:
|
| 4649 | 4672 | |
| 4650 | 4673 | int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) |
| 4651 | 4674 | { |
| 4652 | | return av_get_frame_filename2(buf, buf_size, path, number, 0); |
| | 4675 | return av_get_frame_filename2(buf, buf_size, path, number, 0, 0); |
| 4653 | 4676 | } |
| 4654 | 4677 | |
| 4655 | 4678 | void av_url_split(char *proto, int proto_size, |