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.

246 lines
5.5KB

  1. /*
  2. * Miscellaneous MJPEG based formats
  3. * Copyright (c) 2000 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,
  31. int stream_index, UINT8 *buf, int size)
  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)
  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)
  104. {
  105. JpegContext *s = s1->priv_data;
  106. char filename[1024];
  107. ByteIOContext f1, *pb = &f1;
  108. snprintf(filename, sizeof(filename), s->path, s->img_number);
  109. if (url_fopen(pb, filename, URL_WRONLY) < 0)
  110. return -EIO;
  111. put_buffer(pb, buf, size);
  112. put_flush_packet(pb);
  113. url_fclose(pb);
  114. s->img_number++;
  115. return 0;
  116. }
  117. static int jpeg_write_trailer(AVFormatContext *s1)
  118. {
  119. JpegContext *s = s1->priv_data;
  120. free(s);
  121. return 0;
  122. }
  123. /***/
  124. static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap)
  125. {
  126. JpegContext *s;
  127. int i;
  128. char buf[1024];
  129. ByteIOContext pb1, *f = &pb1;
  130. AVStream *st;
  131. s = av_mallocz(sizeof(JpegContext));
  132. if (!s)
  133. return -1;
  134. s1->priv_data = s;
  135. nstrcpy(s->path, sizeof(s->path), s1->filename);
  136. s1->nb_streams = 1;
  137. st = av_mallocz(sizeof(AVStream));
  138. if (!st) {
  139. free(s);
  140. return -ENOMEM;
  141. }
  142. s1->streams[0] = st;
  143. s->img_number = 0;
  144. /* try to find the first image */
  145. for(i=0;i<5;i++) {
  146. snprintf(buf, sizeof(buf), s->path, s->img_number);
  147. if (url_fopen(f, buf, URL_RDONLY) >= 0)
  148. break;
  149. s->img_number++;
  150. }
  151. if (i == 5)
  152. goto fail;
  153. url_fclose(f);
  154. st->codec.codec_type = CODEC_TYPE_VIDEO;
  155. st->codec.codec_id = CODEC_ID_MJPEG;
  156. if (!ap || !ap->frame_rate)
  157. st->codec.frame_rate = 25 * FRAME_RATE_BASE;
  158. else
  159. st->codec.frame_rate = ap->frame_rate;
  160. return 0;
  161. fail:
  162. free(s);
  163. return -EIO;
  164. }
  165. static int jpeg_read_packet(AVFormatContext *s1, AVPacket *pkt)
  166. {
  167. JpegContext *s = s1->priv_data;
  168. char filename[1024];
  169. int size;
  170. ByteIOContext f1, *f = &f1;
  171. snprintf(filename, sizeof(filename), s->path, s->img_number);
  172. f = &f1;
  173. if (url_fopen(f, filename, URL_RDONLY) < 0)
  174. return -EIO;
  175. size = url_seek(url_fileno(f), 0, SEEK_END);
  176. url_seek(url_fileno(f), 0, SEEK_SET);
  177. av_new_packet(pkt, size);
  178. pkt->stream_index = 0;
  179. get_buffer(f, pkt->data, size);
  180. url_fclose(f);
  181. s->img_number++;
  182. return 0;
  183. }
  184. static int jpeg_read_close(AVFormatContext *s1)
  185. {
  186. JpegContext *s = s1->priv_data;
  187. free(s);
  188. return 0;
  189. }
  190. AVFormat jpeg_format = {
  191. "jpeg",
  192. "JPEG image",
  193. "image/jpeg",
  194. "jpg,jpeg",
  195. CODEC_ID_NONE,
  196. CODEC_ID_MJPEG,
  197. jpeg_write_header,
  198. jpeg_write_packet,
  199. jpeg_write_trailer,
  200. jpeg_read_header,
  201. jpeg_read_packet,
  202. jpeg_read_close,
  203. NULL,
  204. AVFMT_NOFILE,
  205. };