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.

417 lines
10KB

  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;
  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. strcpy(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->frame_rate) {
  121. st->codec.frame_rate = 25;
  122. st->codec.frame_rate_base = 1;
  123. } else {
  124. st->codec.frame_rate = ap->frame_rate;
  125. st->codec.frame_rate_base = ap->frame_rate_base;
  126. }
  127. if (!s->is_pipe) {
  128. if (find_image_range(&first_index, &last_index, s->path) < 0)
  129. goto fail;
  130. s->img_first = first_index;
  131. s->img_last = last_index;
  132. s->img_number = first_index;
  133. /* compute duration */
  134. st->start_time = 0;
  135. st->duration = ((int64_t)AV_TIME_BASE *
  136. (last_index - first_index + 1) *
  137. st->codec.frame_rate_base) / st->codec.frame_rate;
  138. if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
  139. goto fail;
  140. if (url_fopen(f, buf, URL_RDONLY) < 0)
  141. goto fail;
  142. } else {
  143. f = &s1->pb;
  144. }
  145. ret = av_read_image(f, s1->filename, s->img_fmt, read_header_alloc_cb, s);
  146. if (ret < 0)
  147. goto fail1;
  148. if (!s->is_pipe) {
  149. url_fclose(f);
  150. } else {
  151. url_fseek(f, 0, SEEK_SET);
  152. }
  153. st->codec.codec_type = CODEC_TYPE_VIDEO;
  154. st->codec.codec_id = CODEC_ID_RAWVIDEO;
  155. st->codec.width = s->width;
  156. st->codec.height = s->height;
  157. st->codec.pix_fmt = s->pix_fmt;
  158. s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height);
  159. return 0;
  160. fail1:
  161. if (!s->is_pipe)
  162. url_fclose(f);
  163. fail:
  164. av_free(s);
  165. return -EIO;
  166. }
  167. static int read_packet_alloc_cb(void *opaque, AVImageInfo *info)
  168. {
  169. VideoData *s = opaque;
  170. if (info->width != s->width ||
  171. info->height != s->height)
  172. return -1;
  173. avpicture_fill(&info->pict, s->ptr, info->pix_fmt, info->width, info->height);
  174. return 0;
  175. }
  176. static int img_read_packet(AVFormatContext *s1, AVPacket *pkt)
  177. {
  178. VideoData *s = s1->priv_data;
  179. char filename[1024];
  180. int ret;
  181. ByteIOContext f1, *f;
  182. if (!s->is_pipe) {
  183. /* loop over input */
  184. if (loop_input && s->img_number > s->img_last) {
  185. s->img_number = s->img_first;
  186. }
  187. if (get_frame_filename(filename, sizeof(filename),
  188. s->path, s->img_number) < 0)
  189. return -EIO;
  190. f = &f1;
  191. if (url_fopen(f, filename, URL_RDONLY) < 0)
  192. return -EIO;
  193. } else {
  194. f = &s1->pb;
  195. if (url_feof(f))
  196. return -EIO;
  197. }
  198. av_new_packet(pkt, s->img_size);
  199. pkt->stream_index = 0;
  200. s->ptr = pkt->data;
  201. ret = av_read_image(f, filename, s->img_fmt, read_packet_alloc_cb, s);
  202. if (!s->is_pipe) {
  203. url_fclose(f);
  204. }
  205. if (ret < 0) {
  206. av_free_packet(pkt);
  207. return -EIO; /* signal EOF */
  208. } else {
  209. /* XXX: computing this pts is not necessary as it is done in
  210. the generic code too */
  211. pkt->pts = av_rescale((int64_t)s->img_count * s1->streams[0]->codec.frame_rate_base, s1->pts_den, s1->streams[0]->codec.frame_rate) / s1->pts_num;
  212. s->img_count++;
  213. s->img_number++;
  214. return 0;
  215. }
  216. }
  217. static int img_read_close(AVFormatContext *s1)
  218. {
  219. return 0;
  220. }
  221. /******************************************************/
  222. /* image output */
  223. static int img_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
  224. {
  225. VideoData *img = s->priv_data;
  226. AVStream *st;
  227. AVImageFormat *img_fmt;
  228. int i;
  229. /* find output image format */
  230. if (ap && ap->image_format) {
  231. img_fmt = ap->image_format;
  232. } else {
  233. img_fmt = guess_image_format(s->filename);
  234. }
  235. if (!img_fmt)
  236. return -1;
  237. if (s->nb_streams != 1)
  238. return -1;
  239. st = s->streams[0];
  240. /* we select the first matching format */
  241. for(i=0;i<PIX_FMT_NB;i++) {
  242. if (img_fmt->supported_pixel_formats & (1 << i))
  243. break;
  244. }
  245. if (i >= PIX_FMT_NB)
  246. return -1;
  247. img->img_fmt = img_fmt;
  248. img->pix_fmt = i;
  249. st->codec.pix_fmt = img->pix_fmt;
  250. return 0;
  251. }
  252. static int img_write_header(AVFormatContext *s)
  253. {
  254. VideoData *img = s->priv_data;
  255. img->img_number = 1;
  256. strcpy(img->path, s->filename);
  257. /* find format */
  258. if (s->oformat->flags & AVFMT_NOFILE)
  259. img->is_pipe = 0;
  260. else
  261. img->is_pipe = 1;
  262. return 0;
  263. }
  264. static int img_write_packet(AVFormatContext *s, int stream_index,
  265. const uint8_t *buf, int size, int64_t pts)
  266. {
  267. VideoData *img = s->priv_data;
  268. AVStream *st = s->streams[stream_index];
  269. ByteIOContext pb1, *pb;
  270. AVPicture *picture;
  271. int width, height, ret;
  272. char filename[1024];
  273. AVImageInfo info;
  274. width = st->codec.width;
  275. height = st->codec.height;
  276. picture = (AVPicture *)buf;
  277. if (!img->is_pipe) {
  278. if (get_frame_filename(filename, sizeof(filename),
  279. img->path, img->img_number) < 0)
  280. return -EIO;
  281. pb = &pb1;
  282. if (url_fopen(pb, filename, URL_WRONLY) < 0)
  283. return -EIO;
  284. } else {
  285. pb = &s->pb;
  286. }
  287. info.width = width;
  288. info.height = height;
  289. info.pix_fmt = st->codec.pix_fmt;
  290. info.interleaved = 0; /* FIXME: there should be a way to set it right */
  291. info.pict = *picture;
  292. ret = av_write_image(pb, img->img_fmt, &info);
  293. if (!img->is_pipe) {
  294. url_fclose(pb);
  295. }
  296. img->img_number++;
  297. return 0;
  298. }
  299. static int img_write_trailer(AVFormatContext *s)
  300. {
  301. return 0;
  302. }
  303. /* input */
  304. static AVInputFormat image_iformat = {
  305. "image",
  306. "image sequence",
  307. sizeof(VideoData),
  308. image_probe,
  309. img_read_header,
  310. img_read_packet,
  311. img_read_close,
  312. NULL,
  313. NULL,
  314. AVFMT_NOFILE | AVFMT_NEEDNUMBER,
  315. };
  316. static AVInputFormat imagepipe_iformat = {
  317. "imagepipe",
  318. "piped image sequence",
  319. sizeof(VideoData),
  320. NULL, /* no probe */
  321. img_read_header,
  322. img_read_packet,
  323. img_read_close,
  324. NULL,
  325. };
  326. /* output */
  327. static AVOutputFormat image_oformat = {
  328. "image",
  329. "image sequence",
  330. "",
  331. "",
  332. sizeof(VideoData),
  333. CODEC_ID_NONE,
  334. CODEC_ID_RAWVIDEO,
  335. img_write_header,
  336. img_write_packet,
  337. img_write_trailer,
  338. AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RAWPICTURE,
  339. img_set_parameters,
  340. };
  341. static AVOutputFormat imagepipe_oformat = {
  342. "imagepipe",
  343. "piped image sequence",
  344. "",
  345. "",
  346. sizeof(VideoData),
  347. CODEC_ID_NONE,
  348. CODEC_ID_RAWVIDEO,
  349. img_write_header,
  350. img_write_packet,
  351. img_write_trailer,
  352. AVFMT_RAWPICTURE,
  353. img_set_parameters,
  354. };
  355. int img_init(void)
  356. {
  357. av_register_input_format(&image_iformat);
  358. av_register_output_format(&image_oformat);
  359. av_register_input_format(&imagepipe_iformat);
  360. av_register_output_format(&imagepipe_oformat);
  361. return 0;
  362. }