aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Gavrilov <kirill@sview.ru>2014-01-29 21:22:24 +0400
committerMichael Niedermayer <michaelni@gmx.at>2014-01-30 00:17:02 +0100
commite9e7e685166e024466df8f9f10de12e74b327c82 (patch)
treec328cbf6ca4379b7d4a7f7cfec8dfa80ff012815
parent72afa381b3fa347f4149067845c6582469d8062e (diff)
downloadffmpeg-e9e7e685166e024466df8f9f10de12e74b327c82.tar.gz
mjpegdec: parse JPS extension and save relevant stereo3d information
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/mjpegdec.c49
-rw-r--r--libavcodec/mjpegdec.h3
2 files changed, 52 insertions, 0 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 6a74226713..0c30f89602 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -1554,6 +1554,45 @@ static int mjpeg_decode_app(MJpegDecodeContext *s)
goto out;
}
+ /* JPS extension by VRex */
+ if (s->start_code == APP3 && id == AV_RB32("_JPS") && len >= 10) {
+ int flags, layout, type;
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "_JPSJPS_\n");
+
+ skip_bits(&s->gb, 32); len -= 4; /* JPS_ */
+ skip_bits(&s->gb, 16); len -= 2; /* block length */
+ skip_bits(&s->gb, 8); /* reserved */
+ flags = get_bits(&s->gb, 8);
+ layout = get_bits(&s->gb, 8);
+ type = get_bits(&s->gb, 8);
+ len -= 4;
+
+ s->stereo3d = av_stereo3d_alloc();
+ if (!s->stereo3d) {
+ goto out;
+ }
+ if (type == 0) {
+ s->stereo3d->type = AV_STEREO3D_2D;
+ } else if (type == 1) {
+ switch (layout) {
+ case 0x01:
+ s->stereo3d->type = AV_STEREO3D_LINES;
+ break;
+ case 0x02:
+ s->stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
+ break;
+ case 0x03:
+ s->stereo3d->type = AV_STEREO3D_TOPBOTTOM;
+ break;
+ }
+ if (!(flags & 0x04)) {
+ s->stereo3d->flags = AV_STEREO3D_FLAG_INVERT;
+ }
+ }
+ goto out;
+ }
+
/* EXIF metadata */
if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
GetByteContext gbytes;
@@ -1787,6 +1826,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
int ret = 0;
av_dict_free(&s->exif_metadata);
+ av_freep(&s->stereo3d);
buf_ptr = buf;
buf_end = buf + buf_size;
@@ -2017,6 +2057,15 @@ the_end:
}
}
+ if (s->stereo3d) {
+ AVStereo3D *stereo = av_stereo3d_create_side_data(data);
+ if (stereo) {
+ stereo->type = s->stereo3d->type;
+ stereo->flags = s->stereo3d->flags;
+ }
+ av_freep(&s->stereo3d);
+ }
+
av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
av_dict_free(&s->exif_metadata);
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index 79a95f551c..1ec241b1e6 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -31,6 +31,7 @@
#include "libavutil/log.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/stereo3d.h"
#include "avcodec.h"
#include "get_bits.h"
@@ -122,6 +123,8 @@ typedef struct MJpegDecodeContext {
int extern_huff;
AVDictionary *exif_metadata;
+ AVStereo3D *stereo3d; ///!< stereoscopic information (cached, since it is read before frame allocation)
+
const AVPixFmtDescriptor *pix_desc;
} MJpegDecodeContext;