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.

251 lines
5.7KB

  1. /*
  2. * JPEG based formats
  3. * Copyright (c) 2000, 2001 Gerard Lantau.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program 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
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "avformat.h"
  20. /* Multipart JPEG */
  21. #define BOUNDARY_TAG "ffserver"
  22. static int mpjpeg_write_header(AVFormatContext *s)
  23. {
  24. UINT8 buf1[256];
  25. snprintf(buf1, sizeof(buf1), "--%s\n", BOUNDARY_TAG);
  26. put_buffer(&s->pb, buf1, strlen(buf1));
  27. put_flush_packet(&s->pb);
  28. return 0;
  29. }
  30. static int mpjpeg_write_packet(AVFormatContext *s, int stream_index,
  31. UINT8 *buf, int size, int force_pts)
  32. {
  33. UINT8 buf1[256];
  34. snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n");
  35. put_buffer(&s->pb, buf1, strlen(buf1));
  36. put_buffer(&s->pb, buf, size);
  37. snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG);
  38. put_buffer(&s->pb, buf1, strlen(buf1));
  39. put_flush_packet(&s->pb);
  40. return 0;
  41. }
  42. static int mpjpeg_write_trailer(AVFormatContext *s)
  43. {
  44. return 0;
  45. }
  46. AVFormat mpjpeg_format = {
  47. "mpjpeg",
  48. "Mime multipart JPEG format",
  49. "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG,
  50. "mjpg",
  51. CODEC_ID_NONE,
  52. CODEC_ID_MJPEG,
  53. mpjpeg_write_header,
  54. mpjpeg_write_packet,
  55. mpjpeg_write_trailer,
  56. };
  57. /*************************************/
  58. /* single frame JPEG */
  59. static int single_jpeg_write_header(AVFormatContext *s)
  60. {
  61. return 0;
  62. }
  63. static int single_jpeg_write_packet(AVFormatContext *s, int stream_index,
  64. UINT8 *buf, int size, int force_pts)
  65. {
  66. put_buffer(&s->pb, buf, size);
  67. put_flush_packet(&s->pb);
  68. return 1; /* no more data can be sent */
  69. }
  70. static int single_jpeg_write_trailer(AVFormatContext *s)
  71. {
  72. return 0;
  73. }
  74. AVFormat single_jpeg_format = {
  75. "singlejpeg",
  76. "single JPEG image",
  77. "image/jpeg",
  78. "jpg,jpeg",
  79. CODEC_ID_NONE,
  80. CODEC_ID_MJPEG,
  81. single_jpeg_write_header,
  82. single_jpeg_write_packet,
  83. single_jpeg_write_trailer,
  84. };
  85. /*************************************/
  86. /* multiple jpeg images */
  87. typedef struct JpegContext {
  88. char path[1024];
  89. int img_number;
  90. } JpegContext;
  91. static int jpeg_write_header(AVFormatContext *s1)
  92. {
  93. JpegContext *s;
  94. s = av_mallocz(sizeof(JpegContext));
  95. if (!s)
  96. return -1;
  97. s1->priv_data = s;
  98. nstrcpy(s->path, sizeof(s->path), s1->filename);
  99. s->img_number = 1;
  100. return 0;
  101. }
  102. static int jpeg_write_packet(AVFormatContext *s1, int stream_index,
  103. UINT8 *buf, int size, int force_pts)
  104. {
  105. JpegContext *s = s1->priv_data;
  106. char filename[1024];
  107. ByteIOContext f1, *pb = &f1;
  108. if (get_frame_filename(filename, sizeof(filename),
  109. s->path, s->img_number) < 0)
  110. return -EIO;
  111. if (url_fopen(pb, filename, URL_WRONLY) < 0)
  112. return -EIO;
  113. put_buffer(pb, buf, size);
  114. put_flush_packet(pb);
  115. url_fclose(pb);
  116. s->img_number++;
  117. return 0;
  118. }
  119. static int jpeg_write_trailer(AVFormatContext *s1)
  120. {
  121. JpegContext *s = s1->priv_data;
  122. free(s);
  123. return 0;
  124. }
  125. /***/
  126. static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap)
  127. {
  128. JpegContext *s;
  129. int i;
  130. char buf[1024];
  131. ByteIOContext pb1, *f = &pb1;
  132. AVStream *st;
  133. s = av_mallocz(sizeof(JpegContext));
  134. if (!s)
  135. return -1;
  136. s1->priv_data = s;
  137. nstrcpy(s->path, sizeof(s->path), s1->filename);
  138. s1->nb_streams = 1;
  139. st = av_mallocz(sizeof(AVStream));
  140. if (!st) {
  141. free(s);
  142. return -ENOMEM;
  143. }
  144. s1->streams[0] = st;
  145. s->img_number = 0;
  146. /* try to find the first image */
  147. for(i=0;i<5;i++) {
  148. if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0)
  149. goto fail;
  150. if (url_fopen(f, buf, URL_RDONLY) >= 0)
  151. break;
  152. s->img_number++;
  153. }
  154. if (i == 5)
  155. goto fail;
  156. url_fclose(f);
  157. st->codec.codec_type = CODEC_TYPE_VIDEO;
  158. st->codec.codec_id = CODEC_ID_MJPEG;
  159. if (!ap || !ap->frame_rate)
  160. st->codec.frame_rate = 25 * FRAME_RATE_BASE;
  161. else
  162. st->codec.frame_rate = ap->frame_rate;
  163. return 0;
  164. fail:
  165. free(s);
  166. return -EIO;
  167. }
  168. static int jpeg_read_packet(AVFormatContext *s1, AVPacket *pkt)
  169. {
  170. JpegContext *s = s1->priv_data;
  171. char filename[1024];
  172. int size;
  173. ByteIOContext f1, *f = &f1;
  174. if (get_frame_filename(filename, sizeof(filename),
  175. s->path, s->img_number) < 0)
  176. return -EIO;
  177. f = &f1;
  178. if (url_fopen(f, filename, URL_RDONLY) < 0)
  179. return -EIO;
  180. size = url_seek(url_fileno(f), 0, SEEK_END);
  181. url_seek(url_fileno(f), 0, SEEK_SET);
  182. av_new_packet(pkt, size);
  183. pkt->stream_index = 0;
  184. get_buffer(f, pkt->data, size);
  185. url_fclose(f);
  186. s->img_number++;
  187. return 0;
  188. }
  189. static int jpeg_read_close(AVFormatContext *s1)
  190. {
  191. JpegContext *s = s1->priv_data;
  192. free(s);
  193. return 0;
  194. }
  195. AVFormat jpeg_format = {
  196. "jpeg",
  197. "JPEG image",
  198. "image/jpeg",
  199. "jpg,jpeg",
  200. CODEC_ID_NONE,
  201. CODEC_ID_MJPEG,
  202. jpeg_write_header,
  203. jpeg_write_packet,
  204. jpeg_write_trailer,
  205. jpeg_read_header,
  206. jpeg_read_packet,
  207. jpeg_read_close,
  208. NULL,
  209. AVFMT_NOFILE | AVFMT_NEEDNUMBER,
  210. };