You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

401 lines
9.5KB

  1. /*
  2. * Image format
  3. * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #include <unistd.h>
  20. #include "avformat.h"
  21. #include "os_support.h"
  22. typedef struct {
  23. int width;
  24. int height;
  25. int img_number;
  26. int img_size;
  27. AVImageFormat *img_fmt;
  28. int pix_fmt;
  29. int is_pipe;
  30. char path[1024];
  31. /* temporary usage */
  32. void *ptr;
  33. } VideoData;
  34. /* return -1 if no image found */
  35. static int find_image_range(int *pfirst_index, int *plast_index,
  36. const char *path)
  37. {
  38. char buf[1024];
  39. int range, last_index, range1, first_index;
  40. /* find the first image */
  41. for(first_index = 0; first_index < 5; first_index++) {
  42. if (get_frame_filename(buf, sizeof(buf), path, first_index) < 0)
  43. goto fail;
  44. if (url_exist(buf))
  45. break;
  46. }
  47. if (first_index == 5)
  48. goto fail;
  49. /* find the last image */
  50. last_index = first_index;
  51. for(;;) {
  52. range = 0;
  53. for(;;) {
  54. if (!range)
  55. range1 = 1;
  56. else
  57. range1 = 2 * range;
  58. if (get_frame_filename(buf, sizeof(buf), path,
  59. last_index + range1) < 0)
  60. goto fail;
  61. if (!url_exist(buf))
  62. break;
  63. range = range1;
  64. /* just in case... */
  65. if (range >= (1 << 30))
  66. goto fail;
  67. }
  68. /* we are sure than image last_index + range exists */
  69. if (!range)
  70. break;
  71. last_index += range;
  72. }
  73. *pfirst_index = first_index;
  74. *plast_index = last_index;
  75. return 0;
  76. fail:
  77. return -1;
  78. }
  79. static int image_probe(AVProbeData *p)
  80. {
  81. if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
  82. return AVPROBE_SCORE_MAX;
  83. else
  84. return 0;
  85. }
  86. static int read_header_alloc_cb(void *opaque, AVImageInfo *info)
  87. {
  88. VideoData *s = opaque;
  89. s->width = info->width;
  90. s->height = info->height;
  91. s->pix_fmt = info->pix_fmt;
  92. /* stop image reading but no error */
  93. return 1;
  94. }
  95. static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
  96. {
  97. VideoData *s = s1->priv_data;
  98. int ret, first_index, last_index;
  99. char buf[1024];
  100. ByteIOContext pb1, *f = &pb1;
  101. AVStream *st;
  102. st = av_new_stream(s1, 0);
  103. if (!st) {
  104. av_free(s);
  105. return -ENOMEM;
  106. }
  107. if (ap && ap->image_format)
  108. s->img_fmt = ap->image_format;
  109. strcpy(s->path, s1->filename);
  110. s->img_number = 0;
  111. /* find format */
  112. if (s1->iformat->flags & AVFMT_NOFILE)
  113. s->is_pipe = 0;
  114. else
  115. s->is_pipe = 1;
  116. if (!ap || !ap->frame_rate) {
  117. st->codec.frame_rate = 25;
  118. st->codec.frame_rate_base = 1;
  119. } else {
  120. st->codec.frame_rate = ap->frame_rate;
  121. st->codec.frame_rate_base = ap->frame_rate_base;
  122. }
  123. if (!s->is_pipe) {
  124. if (find_image_range(&first_index, &last_index, s->path) < 0)
  125. goto fail;
  126. s->img_number = first_index;
  127. /* compute duration */
  128. st->start_time = 0;
  129. st->duration = ((int64_t)AV_TIME_BASE *
  130. (last_index - first_index + 1) *
  131. st->codec.frame_rate_base) / st->codec.frame_rate;
  132. if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
  133. goto fail;
  134. if (url_fopen(f, buf, URL_RDONLY) < 0)
  135. goto fail;
  136. } else {
  137. f = &s1->pb;
  138. }
  139. ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
  140. if (ret < 0)
  141. goto fail1;
  142. if (!s->is_pipe) {
  143. url_fclose(f);
  144. } else {
  145. url_fseek(f, 0, SEEK_SET);
  146. }
  147. st->codec.codec_type = CODEC_TYPE_VIDEO;
  148. st->codec.codec_id = CODEC_ID_RAWVIDEO;
  149. st->codec.width = s->width;
  150. st->codec.height = s->height;
  151. st->codec.pix_fmt = s->pix_fmt;
  152. s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height);
  153. return 0;
  154. fail1:
  155. if (!s->is_pipe)
  156. url_fclose(f);
  157. fail:
  158. av_free(s);
  159. return -EIO;
  160. }
  161. static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
  162. {
  163. VideoData *s = opaque;
  164. if (info->width != s->width ||
  165. info->height != s->height)
  166. return -1;
  167. avpicture_fill(&info->pict, s->ptr, info->pix_fmt, info->width, info->height);
  168. return 0;
  169. }
  170. static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
  171. {
  172. VideoData *s = s1->priv_data;
  173. char filename[1024];
  174. int ret;
  175. ByteIOContext f1, *f;
  176. if (!s->is_pipe) {
  177. if (get_frame_filename(filename, sizeof(filename),
  178. s->path, s->img_number) < 0)
  179. return -EIO;
  180. f = &f1;
  181. if (url_fopen(f, filename, URL_RDONLY) < 0)
  182. return -EIO;
  183. } else {
  184. f = &s1->pb;
  185. if (url_feof(f))
  186. return -EIO;
  187. }
  188. av_new_packet(pkt, s->img_size);
  189. pkt->stream_index = 0;
  190. s->ptr = pkt->data;
  191. ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s);
  192. if (!s->is_pipe) {
  193. url_fclose(f);
  194. }
  195. if (ret < 0) {
  196. av_free_packet(pkt);
  197. return -EIO; /* signal EOF */
  198. } else {
  199. pkt->pts = av_rescale((int64_t)s->img_number * s1->streams[0]->codec.frame_rate_base, s1->pts_den, s1->streams[0]->codec.frame_rate) / s1->pts_num;
  200. s->img_number++;
  201. return 0;
  202. }
  203. }
  204. static int img_read_close(AVFormatContext *s1)
  205. {
  206. return 0;
  207. }
  208. /******************************************************/
  209. /* image output */
  210. static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
  211. {
  212. VideoData *img = s->priv_data;
  213. AVStream *st;
  214. AVImageFormat *img_fmt;
  215. int i;
  216. /* find output image format */
  217. if (ap && ap->image_format) {
  218. img_fmt = ap->image_format;
  219. } else {
  220. img_fmt = guess_image_format(s->filename);
  221. }
  222. if (!img_fmt)
  223. return -1;
  224. if (s->nb_streams != 1)
  225. return -1;
  226. st = s->streams[0];
  227. /* we select the first matching format */
  228. for(i=0;i<PIX_FMT_NB;i++) {
  229. if (img_fmt->supported_pixel_formats & (1 << i))
  230. break;
  231. }
  232. if (i >= PIX_FMT_NB)
  233. return -1;
  234. img->img_fmt = img_fmt;
  235. img->pix_fmt = i;
  236. st->codec.pix_fmt = img->pix_fmt;
  237. return 0;
  238. }
  239. static int img_write_header(AVFormatContext *s)
  240. {
  241. VideoData *img = s->priv_data;
  242. img->img_number = 1;
  243. strcpy(img->path, s->filename);
  244. /* find format */
  245. if (s->oformat->flags & AVFMT_NOFILE)
  246. img->is_pipe = 0;
  247. else
  248. img->is_pipe = 1;
  249. return 0;
  250. }
  251. static int img_write_packet(AVFormatContext *s, int stream_index,
  252. uint8_t *buf, int size, int force_pts)
  253. {
  254. VideoData *img = s->priv_data;
  255. AVStream *st = s->streams[stream_index];
  256. ByteIOContext pb1, *pb;
  257. AVPicture *picture;
  258. int width, height, ret;
  259. char filename[1024];
  260. AVImageInfo info;
  261. width = st->codec.width;
  262. height = st->codec.height;
  263. picture = (AVPicture *)buf;
  264. if (!img->is_pipe) {
  265. if (get_frame_filename(filename, sizeof(filename),
  266. img->path, img->img_number) < 0)
  267. return -EIO;
  268. pb = &pb1;
  269. if (url_fopen(pb, filename, URL_WRONLY) < 0)
  270. return -EIO;
  271. } else {
  272. pb = &s->pb;
  273. }
  274. info.width = width;
  275. info.height = height;
  276. info.pix_fmt = st->codec.pix_fmt;
  277. info.pict = *picture;
  278. ret = av_write_image(pb, img->img_fmt, &info);
  279. if (!img->is_pipe) {
  280. url_fclose(pb);
  281. }
  282. img->img_number++;
  283. return 0;
  284. }
  285. static int img_write_trailer(AVFormatContext *s)
  286. {
  287. return 0;
  288. }
  289. /* input */
  290. static AVInputFormat image_iformat = {
  291. "image",
  292. "image sequence",
  293. sizeof(VideoData),
  294. image_probe,
  295. img_read_header,
  296. img_read_packet,
  297. img_read_close,
  298. NULL,
  299. AVFMT_NOFILE | AVFMT_NEEDNUMBER,
  300. };
  301. static AVInputFormat imagepipe_iformat = {
  302. "imagepipe",
  303. "piped image sequence",
  304. sizeof(VideoData),
  305. NULL, /* no probe */
  306. img_read_header,
  307. img_read_packet,
  308. img_read_close,
  309. NULL,
  310. };
  311. /* output */
  312. static AVOutputFormat image_oformat = {
  313. "image",
  314. "image sequence",
  315. "",
  316. "",
  317. sizeof(VideoData),
  318. CODEC_ID_NONE,
  319. CODEC_ID_RAWVIDEO,
  320. img_write_header,
  321. img_write_packet,
  322. img_write_trailer,
  323. AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
  324. img_set_parameters,
  325. };
  326. static AVOutputFormat imagepipe_oformat = {
  327. "imagepipe",
  328. "piped image sequence",
  329. "",
  330. "",
  331. sizeof(VideoData),
  332. CODEC_ID_NONE,
  333. CODEC_ID_RAWVIDEO,
  334. img_write_header,
  335. img_write_packet,
  336. img_write_trailer,
  337. AVFMT_RAWPICTURE,
  338. img_set_parameters,
  339. };
  340. int img_init(void)
  341. {
  342. av_register_input_format(&image_iformat);
  343. av_register_output_format(&image_oformat);
  344. av_register_input_format(&imagepipe_iformat);
  345. av_register_output_format(&imagepipe_oformat);
  346. return 0;
  347. }