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.

412 lines
9.9KB

  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 "avformat.h"
  20. /* XXX: this is a hack */
  21. int loop_input = 0;
  22. typedef struct {
  23. int width;
  24. int height;
  25. int img_first;
  26. int img_last;
  27. int img_number;
  28. int img_count;
  29. int img_size;
  30. AVImageFormat *img_fmt;
  31. int pix_fmt;
  32. int is_pipe;
  33. char path[1024];
  34. /* temporary usage */
  35. void *ptr;
  36. } VideoData;
  37. /* return -1 if no image found */
  38. static int find_image_range(int *pfirst_index, int *plast_index,
  39. const char *path)
  40. {
  41. char buf[1024];
  42. int range, last_index, range1, first_index;
  43. /* find the first image */
  44. for(first_index = 0; first_index < 5; first_index++) {
  45. if (get_frame_filename(buf, sizeof(buf), path, first_index) < 0)
  46. goto fail;
  47. if (url_exist(buf))
  48. break;
  49. }
  50. if (first_index == 5)
  51. goto fail;
  52. /* find the last image */
  53. last_index = first_index;
  54. for(;;) {
  55. range = 0;
  56. for(;;) {
  57. if (!range)
  58. range1 = 1;
  59. else
  60. range1 = 2 * range;
  61. if (get_frame_filename(buf, sizeof(buf), path,
  62. last_index + range1) < 0)
  63. goto fail;
  64. if (!url_exist(buf))
  65. break;
  66. range = range1;
  67. /* just in case... */
  68. if (range >= (1 << 30))
  69. goto fail;
  70. }
  71. /* we are sure than image last_index + range exists */
  72. if (!range)
  73. break;
  74. last_index += range;
  75. }
  76. *pfirst_index = first_index;
  77. *plast_index = last_index;
  78. return 0;
  79. fail:
  80. return -1;
  81. }
  82. static int image_probe(AVProbeData *p)
  83. {
  84. if (filename_number_test(p->filename) >= 0 && guess_image_format(p->filename))
  85. return AVPROBE_SCORE_MAX-1;
  86. else
  87. return 0;
  88. }
  89. static int read_header_alloc_cb(void *opaque, AVImageInfo *info)
  90. {
  91. VideoData *s = opaque;
  92. s->width = info->width;
  93. s->height = info->height;
  94. s->pix_fmt = info->pix_fmt;
  95. /* stop image reading but no error */
  96. return 1;
  97. }
  98. static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap)
  99. {
  100. VideoData *s = s1->priv_data;
  101. int ret, first_index, last_index;
  102. char buf[1024];
  103. ByteIOContext pb1, *f = &pb1;
  104. AVStream *st;
  105. st = av_new_stream(s1, 0);
  106. if (!st) {
  107. av_free(s);
  108. return -ENOMEM;
  109. }
  110. if (ap && ap->image_format)
  111. s->img_fmt = ap->image_format;
  112. pstrcpy(s->path, sizeof(s->path), s1->filename);
  113. s->img_number = 0;
  114. s->img_count = 0;
  115. /* find format */
  116. if (s1->iformat->flags & AVFMT_NOFILE)
  117. s->is_pipe = 0;
  118. else
  119. s->is_pipe = 1;
  120. if (!ap || !ap->time_base.num) {
  121. st->codec.time_base= (AVRational){1,25};
  122. } else {
  123. st->codec.time_base= ap->time_base;
  124. }
  125. if (!s->is_pipe) {
  126. if (find_image_range(&first_index, &last_index, s->path) < 0)
  127. goto fail;
  128. s->img_first = first_index;
  129. s->img_last = last_index;
  130. s->img_number = first_index;
  131. /* compute duration */
  132. st->start_time = 0;
  133. st->duration = last_index - first_index + 1;
  134. if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
  135. goto fail;
  136. if (url_fopen(f, buf, URL_RDONLY) < 0)
  137. goto fail;
  138. } else {
  139. f = &s1->pb;
  140. }
  141. ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
  142. if (ret < 0)
  143. goto fail1;
  144. if (!s->is_pipe) {
  145. url_fclose(f);
  146. } else {
  147. url_fseek(f, 0, SEEK_SET);
  148. }
  149. st->codec.codec_type = CODEC_TYPE_VIDEO;
  150. st->codec.codec_id = CODEC_ID_RAWVIDEO;
  151. st->codec.width = s->width;
  152. st->codec.height = s->height;
  153. st->codec.pix_fmt = s->pix_fmt;
  154. s->img_size = avpicture_get_size(s->pix_fmt, (s->width+15)&(~15), (s->height+15)&(~15));
  155. return 0;
  156. fail1:
  157. if (!s->is_pipe)
  158. url_fclose(f);
  159. fail:
  160. av_free(s);
  161. return AVERROR_IO;
  162. }
  163. static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
  164. {
  165. VideoData *s = opaque;
  166. if (info->width != s->width ||
  167. info->height != s->height)
  168. return -1;
  169. avpicture_fill(&info->pict, s->ptr, info->pix_fmt, (info->width+15)&(~15), (info->height+15)&(~15));
  170. return 0;
  171. }
  172. static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
  173. {
  174. VideoData *s = s1->priv_data;
  175. char filename[1024];
  176. int ret;
  177. ByteIOContext f1, *f;
  178. if (!s->is_pipe) {
  179. /* loop over input */
  180. if (loop_input && s->img_number > s->img_last) {
  181. s->img_number = s->img_first;
  182. }
  183. if (get_frame_filename(filename, sizeof(filename),
  184. s->path, s->img_number) < 0)
  185. return AVERROR_IO;
  186. f = &f1;
  187. if (url_fopen(f, filename, URL_RDONLY) < 0)
  188. return AVERROR_IO;
  189. } else {
  190. f = &s1->pb;
  191. if (url_feof(f))
  192. return AVERROR_IO;
  193. }
  194. av_new_packet(pkt, s->img_size);
  195. pkt->stream_index = 0;
  196. s->ptr = pkt->data;
  197. ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s);
  198. if (!s->is_pipe) {
  199. url_fclose(f);
  200. }
  201. if (ret < 0) {
  202. av_free_packet(pkt);
  203. return AVERROR_IO; /* signal EOF */
  204. } else {
  205. /* XXX: computing this pts is not necessary as it is done in
  206. the generic code too */
  207. pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec.time_base.num, s1->streams[0]->time_base.den, s1->streams[0]->codec.time_base.den) / s1->streams[0]->time_base.num;
  208. s->img_count++;
  209. s->img_number++;
  210. return 0;
  211. }
  212. }
  213. static int img_read_close(AVFormatContext *s1)
  214. {
  215. return 0;
  216. }
  217. /******************************************************/
  218. /* image output */
  219. static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
  220. {
  221. VideoData *img = s->priv_data;
  222. AVStream *st;
  223. AVImageFormat *img_fmt;
  224. int i;
  225. /* find output image format */
  226. if (ap && ap->image_format) {
  227. img_fmt = ap->image_format;
  228. } else {
  229. img_fmt = guess_image_format(s->filename);
  230. }
  231. if (!img_fmt)
  232. return -1;
  233. if (s->nb_streams != 1)
  234. return -1;
  235. st = s->streams[0];
  236. /* we select the first matching format */
  237. for(i=0;i<PIX_FMT_NB;i++) {
  238. if (img_fmt->supported_pixel_formats & (1 << i))
  239. break;
  240. }
  241. if (i >= PIX_FMT_NB)
  242. return -1;
  243. img->img_fmt = img_fmt;
  244. img->pix_fmt = i;
  245. st->codec.pix_fmt = img->pix_fmt;
  246. return 0;
  247. }
  248. static int img_write_header(AVFormatContext *s)
  249. {
  250. VideoData *img = s->priv_data;
  251. img->img_number = 1;
  252. pstrcpy(img->path, sizeof(img->path), s->filename);
  253. /* find format */
  254. if (s->oformat->flags & AVFMT_NOFILE)
  255. img->is_pipe = 0;
  256. else
  257. img->is_pipe = 1;
  258. return 0;
  259. }
  260. static int img_write_packet(AVFormatContext *s, AVPacket *pkt)
  261. {
  262. VideoData *img = s->priv_data;
  263. AVStream *st = s->streams[pkt->stream_index];
  264. ByteIOContext pb1, *pb;
  265. AVPicture *picture;
  266. int width, height, ret;
  267. char filename[1024];
  268. AVImageInfo info;
  269. width = st->codec.width;
  270. height = st->codec.height;
  271. picture = (AVPicture *)pkt->data;
  272. if (!img->is_pipe) {
  273. if (get_frame_filename(filename, sizeof(filename),
  274. img->path, img->img_number) < 0)
  275. return AVERROR_IO;
  276. pb = &pb1;
  277. if (url_fopen(pb, filename, URL_WRONLY) < 0)
  278. return AVERROR_IO;
  279. } else {
  280. pb = &s->pb;
  281. }
  282. info.width = width;
  283. info.height = height;
  284. info.pix_fmt = st->codec.pix_fmt;
  285. info.interleaved = 0; /* FIXME: there should be a way to set it right */
  286. info.pict = *picture;
  287. ret = av_write_image(pb, img->img_fmt, &info);
  288. if (!img->is_pipe) {
  289. url_fclose(pb);
  290. }
  291. img->img_number++;
  292. return 0;
  293. }
  294. static int img_write_trailer(AVFormatContext *s)
  295. {
  296. return 0;
  297. }
  298. /* input */
  299. static AVInputFormat image_iformat = {
  300. "image",
  301. "image sequence",
  302. sizeof(VideoData),
  303. image_probe,
  304. img_read_header,
  305. img_read_packet,
  306. img_read_close,
  307. NULL,
  308. NULL,
  309. AVFMT_NOFILE | AVFMT_NEEDNUMBER,
  310. };
  311. static AVInputFormat imagepipe_iformat = {
  312. "imagepipe",
  313. "piped image sequence",
  314. sizeof(VideoData),
  315. NULL, /* no probe */
  316. img_read_header,
  317. img_read_packet,
  318. img_read_close,
  319. NULL,
  320. };
  321. /* output */
  322. static AVOutputFormat image_oformat = {
  323. "image",
  324. "image sequence",
  325. "",
  326. "",
  327. sizeof(VideoData),
  328. CODEC_ID_NONE,
  329. CODEC_ID_RAWVIDEO,
  330. img_write_header,
  331. img_write_packet,
  332. img_write_trailer,
  333. AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
  334. img_set_parameters,
  335. };
  336. static AVOutputFormat imagepipe_oformat = {
  337. "imagepipe",
  338. "piped image sequence",
  339. "",
  340. "",
  341. sizeof(VideoData),
  342. CODEC_ID_NONE,
  343. CODEC_ID_RAWVIDEO,
  344. img_write_header,
  345. img_write_packet,
  346. img_write_trailer,
  347. AVFMT_RAWPICTURE,
  348. img_set_parameters,
  349. };
  350. int img_init(void)
  351. {
  352. av_register_input_format(&image_iformat);
  353. av_register_output_format(&image_oformat);
  354. av_register_input_format(&imagepipe_iformat);
  355. av_register_output_format(&imagepipe_oformat);
  356. return 0;
  357. }