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.

399 lines
9.7KB

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