FFmpeg  4.4.4
img2enc.c
Go to the documentation of this file.
1 /*
2  * Image format
3  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4  * Copyright (c) 2004 Michael Niedermayer
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/avstring.h"
26 #include "libavutil/dict.h"
27 #include "libavutil/log.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/pixdesc.h"
31 #include "avformat.h"
32 #include "avio_internal.h"
33 #include "internal.h"
34 #include "img2.h"
35 
36 typedef struct VideoMuxData {
37  const AVClass *class; /**< Class for private options. */
39  int split_planes; /**< use independent file for each Y, U, V plane */
40  char path[1024];
41  char tmp[4][1024];
42  char target[4][1024];
43  int update;
45  int frame_pts;
46  const char *muxer;
49 } VideoMuxData;
50 
52 {
53  VideoMuxData *img = s->priv_data;
54  AVStream *st = s->streams[0];
56 
57  av_strlcpy(img->path, s->url, sizeof(img->path));
58 
59  if (st->codecpar->codec_id == AV_CODEC_ID_GIF) {
60  img->muxer = "gif";
61  } else if (st->codecpar->codec_id == AV_CODEC_ID_FITS) {
62  img->muxer = "fits";
63  } else if (st->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO) {
64  const char *str = strrchr(img->path, '.');
65  img->split_planes = str
66  && !av_strcasecmp(str + 1, "y")
67  && s->nb_streams == 1
68  && desc
69  &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR)
70  && desc->nb_components >= 3;
71  }
72 
73  return 0;
74 }
75 
77 {
78  VideoMuxData *img = s->priv_data;
79  AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
80  AVStream *st;
81  AVPacket pkt2;
82  AVFormatContext *fmt = NULL;
83  int ret;
84 
85  /* URL is not used directly as we are overriding the IO context later. */
86  ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->url);
87  if (ret < 0)
88  return ret;
89  st = avformat_new_stream(fmt, NULL);
90  if (!st) {
91  ret = AVERROR(ENOMEM);
92  goto out;
93  }
94  st->id = pkt->stream_index;
95 
96  fmt->pb = pb;
97 
98  ret = av_packet_ref(&pkt2, pkt);
99  if (ret < 0)
100  goto out;
101  pkt2.stream_index = 0;
102 
103  if ((ret = avcodec_parameters_copy(st->codecpar, par)) < 0 ||
104  (ret = avformat_write_header(fmt, NULL)) < 0 ||
105  (ret = av_interleaved_write_frame(fmt, &pkt2)) < 0 ||
106  (ret = av_write_trailer(fmt))) {}
107 
108  av_packet_unref(&pkt2);
109 out:
111  return ret;
112 }
113 
115 {
116  VideoMuxData *img = s->priv_data;
117  if (img->muxer) {
118  int ret = write_muxed_file(s, s->pb, pkt);
119  if (ret < 0)
120  return ret;
121  } else {
122  avio_write(s->pb, pkt->data, pkt->size);
123  }
124  img->img_number++;
125  return 0;
126 }
127 
129 {
130  VideoMuxData *img = s->priv_data;
131  AVIOContext *pb[4] = {0};
132  char filename[1024];
133  AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
135  int ret, i;
136  int nb_renames = 0;
138 
139  if (img->update) {
140  av_strlcpy(filename, img->path, sizeof(filename));
141  } else if (img->use_strftime) {
142  time_t now0;
143  struct tm *tm, tmpbuf;
144  time(&now0);
145  tm = localtime_r(&now0, &tmpbuf);
146  if (!strftime(filename, sizeof(filename), img->path, tm)) {
147  av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
148  return AVERROR(EINVAL);
149  }
150  } else if (img->frame_pts) {
151  if (av_get_frame_filename2(filename, sizeof(filename), img->path, pkt->pts, AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) {
152  av_log(s, AV_LOG_ERROR, "Cannot write filename by pts of the frames.");
153  return AVERROR(EINVAL);
154  }
155  } else if (av_get_frame_filename2(filename, sizeof(filename), img->path,
156  img->img_number,
158  img->img_number > 1) {
160  "Could not get frame filename number %d from pattern '%s'. "
161  "Use '-frames:v 1' for a single image, or '-update' option, or use a pattern such as %%03d within the filename.\n",
162  img->img_number, img->path);
163  return AVERROR(EINVAL);
164  }
165  for (i = 0; i < 4; i++) {
166  av_dict_copy(&options, img->protocol_opts, 0);
167  snprintf(img->tmp[i], sizeof(img->tmp[i]), "%s.tmp", filename);
168  av_strlcpy(img->target[i], filename, sizeof(img->target[i]));
169  if (s->io_open(s, &pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, &options) < 0) {
170  av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", img->use_rename ? img->tmp[i] : filename);
171  ret = AVERROR(EIO);
172  goto fail;
173  }
174  if (options) {
175  av_log(s, AV_LOG_ERROR, "Could not recognize some protocol options\n");
176  ret = AVERROR(EINVAL);
177  goto fail;
178  }
179 
180  if (!img->split_planes || i+1 >= desc->nb_components)
181  break;
182  filename[strlen(filename) - 1] = "UVAx"[i];
183  }
184  if (img->use_rename)
185  nb_renames = i + 1;
186 
187  if (img->split_planes) {
188  int ysize = par->width * par->height;
189  int usize = AV_CEIL_RSHIFT(par->width, desc->log2_chroma_w) * AV_CEIL_RSHIFT(par->height, desc->log2_chroma_h);
190  if (desc->comp[0].depth >= 9) {
191  ysize *= 2;
192  usize *= 2;
193  }
194  avio_write(pb[0], pkt->data , ysize);
195  avio_write(pb[1], pkt->data + ysize , usize);
196  avio_write(pb[2], pkt->data + ysize + usize, usize);
197  ff_format_io_close(s, &pb[1]);
198  ff_format_io_close(s, &pb[2]);
199  if (desc->nb_components > 3) {
200  avio_write(pb[3], pkt->data + ysize + 2*usize, ysize);
201  ff_format_io_close(s, &pb[3]);
202  }
203  } else if (img->muxer) {
204  ret = write_muxed_file(s, pb[0], pkt);
205  if (ret < 0)
206  goto fail;
207  } else {
208  avio_write(pb[0], pkt->data, pkt->size);
209  }
210  avio_flush(pb[0]);
211  ff_format_io_close(s, &pb[0]);
212  for (i = 0; i < nb_renames; i++) {
213  int ret = ff_rename(img->tmp[i], img->target[i], s);
214  if (ret < 0)
215  return ret;
216  }
217 
218  img->img_number++;
219  return 0;
220 
221 fail:
223  for (i = 0; i < FF_ARRAY_ELEMS(pb); i++)
224  if (pb[i])
225  ff_format_io_close(s, &pb[i]);
226  return ret;
227 }
228 
229 static int query_codec(enum AVCodecID id, int std_compliance)
230 {
231  int i;
232  for (i = 0; ff_img_tags[i].id != AV_CODEC_ID_NONE; i++)
233  if (ff_img_tags[i].id == id)
234  return 1;
235 
236  // Anything really can be stored in img2
237  return std_compliance < FF_COMPLIANCE_NORMAL;
238 }
239 
240 #define OFFSET(x) offsetof(VideoMuxData, x)
241 #define ENC AV_OPT_FLAG_ENCODING_PARAM
242 static const AVOption muxoptions[] = {
243  { "update", "continuously overwrite one file", OFFSET(update), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
244  { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, ENC },
245  { "strftime", "use strftime for filename", OFFSET(use_strftime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
246  { "frame_pts", "use current frame pts for filename", OFFSET(frame_pts), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
247  { "atomic_writing", "write files atomically (using temporary files and renames)", OFFSET(use_rename), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, ENC },
248  { "protocol_opts", "specify protocol options for the opened files", OFFSET(protocol_opts), AV_OPT_TYPE_DICT, {0}, 0, 0, ENC },
249  { NULL },
250 };
251 
252 #if CONFIG_IMAGE2_MUXER
253 static const AVClass img2mux_class = {
254  .class_name = "image2 muxer",
255  .item_name = av_default_item_name,
256  .option = muxoptions,
257  .version = LIBAVUTIL_VERSION_INT,
258 };
259 
261  .name = "image2",
262  .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
263  .extensions = "bmp,dpx,exr,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pfm,pgm,pgmyuv,png,"
264  "ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
265  "sunras,xbm,xface,pix,y",
266  .priv_data_size = sizeof(VideoMuxData),
267  .video_codec = AV_CODEC_ID_MJPEG,
272  .priv_class = &img2mux_class,
273 };
274 #endif
275 #if CONFIG_IMAGE2PIPE_MUXER
277  .name = "image2pipe",
278  .long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
279  .priv_data_size = sizeof(VideoMuxData),
280  .video_codec = AV_CODEC_ID_MJPEG,
285 };
286 #endif
static av_always_inline void update(SilenceDetectContext *s, AVFrame *insamples, int is_silence, int current_sample, int64_t nb_samples_notify, AVRational time_base)
AVOutputFormat ff_image2_muxer
AVOutputFormat ff_image2pipe_muxer
simple assert() macros that are a bit more flexible than ISO C assert().
#define FF_COMPLIANCE_NORMAL
Definition: avcodec.h:1604
Main libavformat public API header.
int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat, const char *format_name, const char *filename)
Allocate an AVFormatContext for an output format.
Definition: mux.c:136
#define AVFMT_NODIMENSIONS
Format does not need width/height.
Definition: avformat.h:466
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:458
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition: avformat.h:462
int ff_rename(const char *url_src, const char *url_dst, void *logctx)
Wrap avpriv_io_move and log if error happens.
Definition: avio.c:668
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:675
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:225
void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:245
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define s(width, name)
Definition: cbs_vp9.c:257
#define fail()
Definition: checkasm.h:133
int avcodec_parameters_copy(AVCodecParameters *dst, const AVCodecParameters *src)
Copy the contents of src to dst.
Definition: codec_par.c:72
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define NULL
Definition: coverity.c:32
Public dictionary API.
const OptionDef options[]
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_DICT
Definition: opt.h:232
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
@ AV_CODEC_ID_RAWVIDEO
Definition: codec_id.h:62
@ AV_CODEC_ID_GIF
Definition: codec_id.h:146
@ AV_CODEC_ID_NONE
Definition: codec_id.h:47
@ AV_CODEC_ID_FITS
Definition: codec_id.h:285
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:56
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:641
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: utils.c:4436
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4509
av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options)
Allocate the stream private data and write the stream header to an output media file.
Definition: mux.c:506
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
Write a packet to an output media file ensuring correct interleaving.
Definition: mux.c:1259
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1274
int av_get_frame_filename2(char *buf, int buf_size, const char *path, int number, int flags)
Return in 'buf' the path with 'd' replaced by a number.
Definition: utils.c:4736
#define AV_FRAME_FILENAME_FLAGS_MULTIPLE
Allow multiple d.
Definition: avformat.h:2809
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:215
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const IdStrMap ff_img_tags[]
Definition: img2.c:27
static const AVOption muxoptions[]
Definition: img2enc.c:242
static int write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: img2enc.c:128
static int write_packet_pipe(AVFormatContext *s, AVPacket *pkt)
Definition: img2enc.c:114
static int write_muxed_file(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)
Definition: img2enc.c:76
static int query_codec(enum AVCodecID id, int std_compliance)
Definition: img2enc.c:229
static int write_header(AVFormatContext *s)
Definition: img2enc.c:51
#define ENC
Definition: img2enc.c:241
#define OFFSET(x)
Definition: img2enc.c:240
int i
Definition: input.c:407
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5692
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
const char * desc
Definition: libsvtav1.c:79
AVOptions.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
#define AV_PIX_FMT_FLAG_PLANAR
At least one pixel component is not in the first data plane.
Definition: pixdesc.h:144
#define FF_ARRAY_ELEMS(a)
#define snprintf
Definition: snprintf.h:34
Describe the class of an AVClass context structure.
Definition: log.h:67
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
This struct describes the properties of an encoded stream.
Definition: codec_par.h:52
int width
Video only.
Definition: codec_par.h:126
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
Format I/O context.
Definition: avformat.h:1232
AVIOContext * pb
I/O context.
Definition: avformat.h:1274
Bytestream IO Context.
Definition: avio.h:161
AVOption.
Definition: opt.h:248
const char * name
Definition: avformat.h:491
This structure stores compressed data.
Definition: packet.h:346
int stream_index
Definition: packet.h:371
int size
Definition: packet.h:370
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:362
uint8_t * data
Definition: packet.h:369
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
Stream structure.
Definition: avformat.h:873
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1038
int id
Format-specific stream ID.
Definition: avformat.h:880
enum AVCodecID id
Definition: img2.h:68
const char * muxer
Definition: img2enc.c:46
int update
Definition: img2enc.c:43
int frame_pts
Definition: img2enc.c:45
int use_strftime
Definition: img2enc.c:44
int use_rename
Definition: img2enc.c:47
char target[4][1024]
Definition: img2enc.c:42
AVDictionary * protocol_opts
Definition: img2enc.c:48
int img_number
Definition: img2enc.c:38
int split_planes
use independent file for each Y, U, V plane
Definition: img2enc.c:39
char path[1024]
Definition: img2enc.c:40
char tmp[4][1024]
Definition: img2enc.c:41
#define av_log(a,...)
FILE * out
Definition: movenc.c:54
AVPacket * pkt
Definition: movenc.c:59
#define localtime_r
Definition: time_internal.h:46
#define img