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.

349 lines
8.0KB

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