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