FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mpjpegdec.c
Go to the documentation of this file.
1 /*
2  * Multipart JPEG format
3  * Copyright (c) 2015 Luca Barbato
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/avstring.h"
23 
24 #include "avformat.h"
25 #include "internal.h"
26 
27 static int get_line(AVIOContext *pb, char *line, int line_size)
28 {
29  int i = ff_get_line(pb, line, line_size);
30 
31  if (i > 1 && line[i - 2] == '\r')
32  line[i - 2] = '\0';
33 
34  if (pb->error)
35  return pb->error;
36 
37  if (pb->eof_reached)
38  return AVERROR_EOF;
39 
40  return 0;
41 }
42 
43 static int split_tag_value(char **tag, char **value, char *line)
44 {
45  char *p = line;
46 
47  while (*p != '\0' && *p != ':')
48  p++;
49  if (*p != ':')
50  return AVERROR_INVALIDDATA;
51 
52  *p = '\0';
53  *tag = line;
54 
55  p++;
56 
57  while (av_isspace(*p))
58  p++;
59 
60  *value = p;
61 
62  return 0;
63 }
64 
65 static int check_content_type(char *line)
66 {
67  char *tag, *value;
68  int ret = split_tag_value(&tag, &value, line);
69 
70  if (ret < 0)
71  return ret;
72 
73  if (av_strcasecmp(tag, "Content-type") ||
74  av_strcasecmp(value, "image/jpeg"))
75  return AVERROR_INVALIDDATA;
76 
77  return 0;
78 }
79 
81 {
82  AVIOContext *pb;
83  char line[128] = { 0 };
84  int ret = 0;
85 
86  if (p->buf_size < 2 || p->buf[0] != '-' || p->buf[1] != '-')
87  return 0;
88 
89  pb = avio_alloc_context(p->buf, p->buf_size, 0, NULL, NULL, NULL, NULL);
90  if (!pb)
91  return AVERROR(ENOMEM);
92 
93  while (!pb->eof_reached) {
94  ret = get_line(pb, line, sizeof(line));
95  if (ret < 0)
96  break;
97 
98  ret = check_content_type(line);
99  if (!ret) {
100  ret = AVPROBE_SCORE_MAX;
101  break;
102  }
103  }
104 
105  av_free(pb);
106 
107  return ret;
108 }
109 
111 {
112  AVStream *st;
113  char boundary[70 + 2 + 1];
114  int64_t pos = avio_tell(s->pb);
115  int ret;
116 
117 
118  ret = get_line(s->pb, boundary, sizeof(boundary));
119  if (ret < 0)
120  return ret;
121 
122  if (strncmp(boundary, "--", 2))
123  return AVERROR_INVALIDDATA;
124 
125  st = avformat_new_stream(s, NULL);
126 
129 
130  avpriv_set_pts_info(st, 60, 1, 25);
131 
132  avio_seek(s->pb, pos, SEEK_SET);
133 
134  return 0;
135 }
136 
137 static int parse_content_length(const char *value)
138 {
139  long int val = strtol(value, NULL, 10);
140 
141  if (val == LONG_MIN || val == LONG_MAX)
142  return AVERROR(errno);
143  if (val > INT_MAX)
144  return AVERROR(ERANGE);
145  return val;
146 }
147 
149 {
150  char line[128];
151  int found_content_type = 0;
152  int ret, size = -1;
153 
154  ret = get_line(s->pb, line, sizeof(line));
155  if (ret < 0)
156  return ret;
157 
158  if (strncmp(line, "--", 2))
159  return AVERROR_INVALIDDATA;
160 
161  while (!s->pb->eof_reached) {
162  char *tag, *value;
163 
164  ret = get_line(s->pb, line, sizeof(line));
165  if (ret < 0)
166  return ret;
167 
168  if (line[0] == '\0')
169  break;
170 
171  ret = split_tag_value(&tag, &value, line);
172  if (ret < 0)
173  return ret;
174 
175  if (!av_strcasecmp(tag, "Content-type")) {
176  if (av_strcasecmp(value, "image/jpeg")) {
177  av_log(s, AV_LOG_ERROR,
178  "Unexpected %s : %s\n",
179  tag, value);
180  return AVERROR_INVALIDDATA;
181  } else
182  found_content_type = 1;
183  } else if (!av_strcasecmp(tag, "Content-Length")) {
184  size = parse_content_length(value);
185  if (size < 0)
186  return size;
187  }
188  }
189 
190  if (!found_content_type || size < 0) {
191  return AVERROR_INVALIDDATA;
192  }
193 
194  return size;
195 }
196 
198 {
199  int ret;
200  int size = parse_multipart_header(s);
201 
202  if (size < 0)
203  return size;
204 
205  ret = av_get_packet(s->pb, pkt, size);
206  if (ret < 0)
207  return ret;
208 
209  // trailing empty line
210  avio_skip(s->pb, 2);
211 
212  return 0;
213 }
214 
216  .name = "mpjpeg",
217  .long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG"),
218  .mime_type = "multipart/x-mixed-replace",
219  .extensions = "mjpg",
220  .read_probe = mpjpeg_read_probe,
221  .read_header = mpjpeg_read_header,
222  .read_packet = mpjpeg_read_packet,
223 };
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:634
const char * s
Definition: avisynth_c.h:631
Bytestream IO Context.
Definition: avio.h:111
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4006
static int get_line(AVIOContext *pb, char *line, int line_size)
Definition: mpjpegdec.c:27
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:203
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:276
static int split_tag_value(char **tag, char **value, char *line)
Definition: mpjpegdec.c:43
static AVPacket pkt
Format I/O context.
Definition: avformat.h:1272
int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
Definition: avstring.c:330
static int parse_multipart_header(AVFormatContext *s)
Definition: mpjpegdec.c:148
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:3672
uint32_t tag
Definition: movenc.c:1333
#define AVERROR_EOF
End of file.
Definition: error.h:55
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:241
ptrdiff_t size
Definition: opengl_enc.c:101
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:365
static int mpjpeg_read_header(AVFormatContext *s)
Definition: mpjpegdec.c:110
#define av_log(a,...)
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:111
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:175
Definition: graph2dot.c:48
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:861
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:451
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:450
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:213
ret
Definition: avfilter.c:974
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:109
AVInputFormat ff_mpjpeg_demuxer
Definition: mpjpegdec.c:215
static int mpjpeg_read_probe(AVProbeData *p)
Definition: mpjpegdec.c:80
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
Definition: aviobuf.c:697
Stream structure.
Definition: avformat.h:842
enum AVMediaType codec_type
Definition: avcodec.h:1249
enum AVCodecID codec_id
Definition: avcodec.h:1258
AVIOContext * pb
I/O context.
Definition: avformat.h:1314
static int check_content_type(char *line)
Definition: mpjpegdec.c:65
int error
contains the error code or 0 if no error happened
Definition: avio.h:145
This structure contains the data a format has to probe a file.
Definition: avformat.h:448
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:460
Main libavformat public API header.
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: mpjpegdec.c:197
#define av_free(p)
int eof_reached
true if eof reached
Definition: avio.h:139
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:628
static int parse_content_length(const char *value)
Definition: mpjpegdec.c:137
This structure stores compressed data.
Definition: avcodec.h:1139