summaryrefslogtreecommitdiff
path: root/libavformat/matroskaenc.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-08-29 00:30:47 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-08-29 00:44:47 +0200
commit39cd9fdbf80292b3cf0aab20cacfdb18e85bb2b9 (patch)
tree489589a04d5684229f58615bd83bc5bd37948622 /libavformat/matroskaenc.c
parentfcc39099087e156196e3444ef479b2c778566405 (diff)
parent4d686fb721b485ebbc4c7779d927d876c1e630f7 (diff)
Merge commit '4d686fb721b485ebbc4c7779d927d876c1e630f7'
* commit '4d686fb721b485ebbc4c7779d927d876c1e630f7': matroskaenc: convert avstream stereo3d side data during encoding Conflicts: libavformat/matroskaenc.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/matroskaenc.c')
-rw-r--r--libavformat/matroskaenc.c133
1 files changed, 100 insertions, 33 deletions
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 98fe4af291..a0092f668d 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -46,6 +46,7 @@
#include "libavutil/random_seed.h"
#include "libavutil/samplefmt.h"
#include "libavutil/sha.h"
+#include "libavutil/stereo3d.h"
#include "libavcodec/xiph.h"
#include "libavcodec/mpeg4audio.h"
@@ -693,18 +694,96 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
return ret;
}
-static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, int st_mode,
- int mode)
+
+static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
+ AVStream *st, int mode)
{
- if ((mode == MODE_WEBM && st_mode > 3 && st_mode != 11)
- || st_mode >= MATROSKA_VIDEO_STEREO_MODE_COUNT) {
+ int i;
+ int ret = 0;
+ AVDictionaryEntry *tag;
+ MatroskaVideoStereoModeType format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
+
+ // convert metadata into proper side data and add it to the stream
+ if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
+ (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
+ int stereo_mode = atoi(tag->value);
+
+ for (i=0; i<MATROSKA_VIDEO_STEREO_MODE_COUNT; i++)
+ if (!strcmp(tag->value, ff_matroska_video_stereo_mode[i])){
+ stereo_mode = i;
+ break;
+ }
+
+ if (stereo_mode < MATROSKA_VIDEO_STEREOMODE_TYPE_NB &&
+ stereo_mode != 10 && stereo_mode != 12) {
+ int ret = ff_mkv_stereo3d_conv(st, stereo_mode);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ for (i = 0; i < st->nb_side_data; i++) {
+ AVPacketSideData sd = st->side_data[i];
+ if (sd.type == AV_PKT_DATA_STEREO3D) {
+ AVStereo3D *stereo = (AVStereo3D *)sd.data;
+
+ switch (stereo->type) {
+ case AV_STEREO3D_2D:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_MONO;
+ break;
+ case AV_STEREO3D_SIDEBYSIDE:
+ format = (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ ? MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT
+ : MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT;
+ break;
+ case AV_STEREO3D_TOPBOTTOM:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ break;
+ case AV_STEREO3D_CHECKERBOARD:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ break;
+ case AV_STEREO3D_LINES:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ break;
+ case AV_STEREO3D_COLUMNS:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format--;
+ break;
+ case AV_STEREO3D_FRAMESEQUENCE:
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR;
+ if (stereo->flags & AV_STEREO3D_FLAG_INVERT)
+ format++;
+ break;
+ }
+ ret = stereo->type;
+
+ break;
+ }
+ }
+
+ if (format == MATROSKA_VIDEO_STEREOMODE_TYPE_NB)
+ return ret;
+
+ if ((mode == MODE_WEBM &&
+ format > MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM &&
+ format != MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)
+ || format >= MATROSKA_VIDEO_STEREO_MODE_COUNT) {
av_log(s, AV_LOG_ERROR,
"The specified stereo mode is not valid.\n");
+ format = MATROSKA_VIDEO_STEREOMODE_TYPE_NB;
return AVERROR(EINVAL);
- } else
- put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
+ }
- return 0;
+ put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, format);
+
+ return ret;
}
static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
@@ -845,33 +924,21 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
- if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
- (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
- int st_mode = MATROSKA_VIDEO_STEREO_MODE_COUNT;
-
- for (j=0; j<MATROSKA_VIDEO_STEREO_MODE_COUNT; j++)
- if (!strcmp(tag->value, ff_matroska_video_stereo_mode[j])){
- st_mode = j;
- break;
- }
-
- if (mkv_write_stereo_mode(s, pb, st_mode, mkv->mode) < 0)
- return AVERROR(EINVAL);
+ // check both side data and metadata for stereo information,
+ // write the result to the bitstream if any is found
+ ret = mkv_write_stereo_mode(s, pb, st, mkv->mode);
+ if (ret < 0)
+ return ret;
- switch (st_mode) {
- case 1:
- case 8:
- case 9:
- case 11:
- display_width_div = 2;
- break;
- case 2:
- case 3:
- case 6:
- case 7:
- display_height_div = 2;
- break;
- }
+ switch (ret) {
+ case AV_STEREO3D_SIDEBYSIDE:
+ case AV_STEREO3D_COLUMNS:
+ display_width_div = 2;
+ break;
+ case AV_STEREO3D_TOPBOTTOM:
+ case AV_STEREO3D_LINES:
+ display_height_div = 2;
+ break;
}
if (((tag = av_dict_get(st->metadata, "alpha_mode", NULL, 0)) && atoi(tag->value)) ||