@ -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 ) ) | |