Libav
img2dec.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 Libav.
7  *
8  * Libav 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  * Libav 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 Libav; 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/avstring.h"
24 #include "libavutil/log.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/parseutils.h"
28 #include "avformat.h"
29 #include "internal.h"
30 
31 typedef struct {
32  const AVClass *class;
33  int img_first;
34  int img_last;
36  int img_count;
37  int is_pipe;
38  char path[1024];
39  char *pixel_format;
40  char *video_size;
41  char *framerate;
42  int loop;
45 
46 static const int sizes[][2] = {
47  { 640, 480 },
48  { 720, 480 },
49  { 720, 576 },
50  { 352, 288 },
51  { 352, 240 },
52  { 160, 128 },
53  { 512, 384 },
54  { 640, 352 },
55  { 640, 240 },
56 };
57 
58 static int infer_size(int *width_ptr, int *height_ptr, int size)
59 {
60  int i;
61 
62  for (i = 0; i < FF_ARRAY_ELEMS(sizes); i++) {
63  if ((sizes[i][0] * sizes[i][1]) == size) {
64  *width_ptr = sizes[i][0];
65  *height_ptr = sizes[i][1];
66  return 0;
67  }
68  }
69 
70  return -1;
71 }
72 
73 /* return -1 if no image found */
74 static int find_image_range(int *pfirst_index, int *plast_index,
75  const char *path, int max_start)
76 {
77  char buf[1024];
78  int range, last_index, range1, first_index;
79 
80  /* find the first image */
81  for (first_index = 0; first_index < max_start; first_index++) {
82  if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) {
83  *pfirst_index =
84  *plast_index = 1;
85  if (avio_check(buf, AVIO_FLAG_READ) > 0)
86  return 0;
87  return -1;
88  }
89  if (avio_check(buf, AVIO_FLAG_READ) > 0)
90  break;
91  }
92  if (first_index == 5)
93  goto fail;
94 
95  /* find the last image */
96  last_index = first_index;
97  for (;;) {
98  range = 0;
99  for (;;) {
100  if (!range)
101  range1 = 1;
102  else
103  range1 = 2 * range;
104  if (av_get_frame_filename(buf, sizeof(buf), path,
105  last_index + range1) < 0)
106  goto fail;
107  if (avio_check(buf, AVIO_FLAG_READ) <= 0)
108  break;
109  range = range1;
110  /* just in case... */
111  if (range >= (1 << 30))
112  goto fail;
113  }
114  /* we are sure than image last_index + range exists */
115  if (!range)
116  break;
117  last_index += range;
118  }
119  *pfirst_index = first_index;
120  *plast_index = last_index;
121  return 0;
122 
123 fail:
124  return -1;
125 }
126 
128 {
129  if (p->filename && ff_guess_image2_codec(p->filename)) {
131  return AVPROBE_SCORE_MAX;
132  else
134  }
135  return 0;
136 }
137 
139 {
140  VideoDemuxData *s = s1->priv_data;
141  int first_index, last_index, ret = 0;
142  int width = 0, height = 0;
143  AVStream *st;
145  AVRational framerate;
146 
148 
149  st = avformat_new_stream(s1, NULL);
150  if (!st) {
151  return AVERROR(ENOMEM);
152  }
153 
154  if (s->pixel_format &&
155  (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) {
156  av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n",
157  s->pixel_format);
158  return AVERROR(EINVAL);
159  }
160  if (s->video_size &&
161  (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
162  av_log(s, AV_LOG_ERROR,
163  "Could not parse video size: %s.\n", s->video_size);
164  return ret;
165  }
166  if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) {
167  av_log(s, AV_LOG_ERROR,
168  "Could not parse framerate: %s.\n", s->framerate);
169  return ret;
170  }
171 
172  av_strlcpy(s->path, s1->filename, sizeof(s->path));
173  s->img_number = 0;
174  s->img_count = 0;
175 
176  /* find format */
177  if (s1->iformat->flags & AVFMT_NOFILE)
178  s->is_pipe = 0;
179  else {
180  s->is_pipe = 1;
182  }
183 
184  avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
185 
186  if (width && height) {
187  st->codec->width = width;
188  st->codec->height = height;
189  }
190 
191  if (!s->is_pipe) {
192  if (find_image_range(&first_index, &last_index, s->path,
193  FFMAX(s->start_number, 5)) < 0)
194  return AVERROR(ENOENT);
195  s->img_first = first_index;
196  s->img_last = last_index;
197  s->img_number = s->start_number != 1 ? s->start_number : first_index;
198  /* compute duration */
199  st->start_time = 0;
200  st->duration = last_index - first_index + 1;
201  }
202 
203  if (s1->video_codec_id) {
205  st->codec->codec_id = s1->video_codec_id;
206  } else if (s1->audio_codec_id) {
208  st->codec->codec_id = s1->audio_codec_id;
209  } else {
212  }
213  if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
214  pix_fmt != AV_PIX_FMT_NONE)
215  st->codec->pix_fmt = pix_fmt;
216 
217  return 0;
218 }
219 
221 {
222  VideoDemuxData *s = s1->priv_data;
223  char filename[1024];
224  int i;
225  int size[3] = { 0 }, ret[3] = { 0 };
226  AVIOContext *f[3] = { NULL };
227  AVCodecContext *codec = s1->streams[0]->codec;
228 
229  if (!s->is_pipe) {
230  /* loop over input */
231  if (s->loop && s->img_number > s->img_last) {
232  s->img_number = s->img_first;
233  }
234  if (s->img_number > s->img_last)
235  return AVERROR_EOF;
236  if (av_get_frame_filename(filename, sizeof(filename),
237  s->path,
238  s->img_number) < 0 && s->img_number > 1)
239  return AVERROR(EIO);
240  for (i = 0; i < 3; i++) {
241  if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
242  &s1->interrupt_callback, NULL) < 0) {
243  if (i >= 1)
244  break;
245  av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",
246  filename);
247  return AVERROR(EIO);
248  }
249  size[i] = avio_size(f[i]);
250 
251  if (codec->codec_id != AV_CODEC_ID_RAWVIDEO)
252  break;
253  filename[strlen(filename) - 1] = 'U' + i;
254  }
255 
256  if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width)
257  infer_size(&codec->width, &codec->height, size[0]);
258  } else {
259  f[0] = s1->pb;
260  if (f[0]->eof_reached)
261  return AVERROR(EIO);
262  size[0] = 4096;
263  }
264 
265  av_new_packet(pkt, size[0] + size[1] + size[2]);
266  pkt->stream_index = 0;
267  pkt->flags |= AV_PKT_FLAG_KEY;
268 
269  pkt->size = 0;
270  for (i = 0; i < 3; i++) {
271  if (f[i]) {
272  ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]);
273  if (!s->is_pipe)
274  avio_close(f[i]);
275  if (ret[i] > 0)
276  pkt->size += ret[i];
277  }
278  }
279 
280  if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) {
281  av_free_packet(pkt);
282  return AVERROR(EIO); /* signal EOF */
283  } else {
284  s->img_count++;
285  s->img_number++;
286  return 0;
287  }
288 }
289 
290 #define OFFSET(x) offsetof(VideoDemuxData, x)
291 #define DEC AV_OPT_FLAG_DECODING_PARAM
292 static const AVOption options[] = {
293  { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, DEC },
294  { "video_size", "", OFFSET(video_size), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, DEC },
295  { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, 0, 0, DEC },
296  { "loop", "", OFFSET(loop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
297  { "start_number", "first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, DEC },
298  { NULL },
299 };
300 
301 #if CONFIG_IMAGE2_DEMUXER
302 static const AVClass img2_class = {
303  .class_name = "image2 demuxer",
304  .item_name = av_default_item_name,
305  .option = options,
306  .version = LIBAVUTIL_VERSION_INT,
307 };
308 AVInputFormat ff_image2_demuxer = {
309  .name = "image2",
310  .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"),
311  .priv_data_size = sizeof(VideoDemuxData),
315  .flags = AVFMT_NOFILE,
316  .priv_class = &img2_class,
317 };
318 #endif
319 #if CONFIG_IMAGE2PIPE_DEMUXER
320 static const AVClass img2pipe_class = {
321  .class_name = "image2pipe demuxer",
322  .item_name = av_default_item_name,
323  .option = options,
324  .version = LIBAVUTIL_VERSION_INT,
325 };
326 AVInputFormat ff_image2pipe_demuxer = {
327  .name = "image2pipe",
328  .long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"),
329  .priv_data_size = sizeof(VideoDemuxData),
332  .priv_class = &img2pipe_class,
333 };
334 #endif