Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/demuxers.texi15
-rw-r--r--libavformat/mpjpegdec.c72
2 files changed, 84 insertions, 3 deletions
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index 349b531357..fb1e4fb3e5 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -450,6 +450,21 @@ to 1 (-1 means automatic setting, 1 means enabled, 0 means
disabled). Default value is -1.
@end table
+@section mpjpeg
+
+MJPEG encapsulated in multi-part MIME demuxer.
+
+This demuxer allows reading of MJPEG, where each frame is represented as a part of
+multipart/x-mixed-replace stream.
+@table @option
+
+@item strict_mime_boundary
+Default implementation applies a relaxed standard to multi-part MIME boundary detection,
+to prevent regression with numerous existing endpoints not generating a proper MIME
+MJPEG stream. Turning this option on by setting it to 1 will result in a stricter check
+of the boundary value.
+@end table
+
@section rawvideo
Raw video demuxer.
diff --git a/libavformat/mpjpegdec.c b/libavformat/mpjpegdec.c
index 9d5700ab6b..b644ee400f 100644
--- a/libavformat/mpjpegdec.c
+++ b/libavformat/mpjpegdec.c
@@ -20,6 +20,7 @@
*/
#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
#include "avformat.h"
#include "internal.h"
@@ -28,9 +29,11 @@
typedef struct MPJPEGDemuxContext {
+ const AVClass *class;
char *boundary;
char *searchstr;
int searchstr_len;
+ int strict_mime_boundary;
} MPJPEGDemuxContext;
@@ -242,6 +245,41 @@ static int parse_multipart_header(AVIOContext *pb,
}
+static char* mpjpeg_get_boundary(AVIOContext* pb)
+{
+ uint8_t *mime_type = NULL;
+ uint8_t *start;
+ uint8_t *end;
+ uint8_t *res = NULL;
+ int len;
+
+ /* get MIME type, and skip to the first parameter */
+ av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type);
+ start = mime_type;
+ while (start != NULL && *start != '\0') {
+ start = strchr(start, ';');
+ if (start)
+ start = start+1;
+
+ while (av_isspace(*start))
+ start++;
+
+ if (!av_stristart(start, "boundary=", &start)) {
+ end = strchr(start, ';');
+ if (end)
+ len = end - start - 1;
+ else
+ len = strlen(start);
+ res = av_strndup(start, len);
+ break;
+ }
+ }
+
+ av_freep(&mime_type);
+ return res;
+}
+
+
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
{
int size;
@@ -249,8 +287,17 @@ static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
MPJPEGDemuxContext *mpjpeg = s->priv_data;
if (mpjpeg->boundary == NULL) {
- mpjpeg->boundary = av_strdup("--");
- mpjpeg->searchstr = av_strdup("\r\n--");
+ uint8_t* boundary = NULL;
+ if (mpjpeg->strict_mime_boundary) {
+ boundary = mpjpeg_get_boundary(s->pb);
+ }
+ if (boundary != NULL) {
+ mpjpeg->boundary = boundary;
+ mpjpeg->searchstr = av_asprintf( "\r\n%s\r\n", boundary );
+ } else {
+ mpjpeg->boundary = av_strdup("--");
+ mpjpeg->searchstr = av_strdup("\r\n--");
+ }
if (!mpjpeg->boundary || !mpjpeg->searchstr) {
av_freep(&mpjpeg->boundary);
av_freep(&mpjpeg->searchstr);
@@ -309,6 +356,22 @@ static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+#define OFFSET(x) offsetof(MPJPEGDemuxContext, x)
+
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+const AVOption mpjpeg_options[] = {
+ { "strict_mime_boundary", "require MIME boundaries match", OFFSET(strict_mime_boundary), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC },
+ { NULL }
+};
+
+
+static const AVClass mpjpeg_demuxer_class = {
+ .class_name = "MPJPEG demuxer",
+ .item_name = av_default_item_name,
+ .option = mpjpeg_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_mpjpeg_demuxer = {
.name = "mpjpeg",
.long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG"),
@@ -318,5 +381,8 @@ AVInputFormat ff_mpjpeg_demuxer = {
.read_probe = mpjpeg_read_probe,
.read_header = mpjpeg_read_header,
.read_packet = mpjpeg_read_packet,
- .read_close = mpjpeg_read_close
+ .read_close = mpjpeg_read_close,
+ .priv_class = &mpjpeg_demuxer_class
};
+
+