Commit cf8b24f0 authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

demux: mp4: support 360° v2 spatial metadata

as found here https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.mdSigned-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 1afd117f
......@@ -346,6 +346,7 @@ int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
}
/* Set 360 video mode */
p_track->fmt.video.projection_mode = PROJECTION_MODE_RECTANGULAR;
const MP4_Box_t *p_uuid = MP4_BoxGet( p_track->p_track, "uuid" );
for( ; p_uuid; p_uuid = p_uuid->p_next)
{
......@@ -355,6 +356,44 @@ int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
p_track->fmt.video.projection_mode = p_uuid->data.p_360->i_projection_mode;
}
const MP4_Box_t *p_st3d = MP4_BoxGet( p_sample, "st3d" );
if (p_st3d && BOXDATA(p_st3d))
{
switch( BOXDATA(p_st3d)->i_stereo_mode )
{
case ST3D_MONOSCOPIC:
p_track->fmt.video.multiview_mode = MULTIVIEW_2D;
break;
case ST3D_STEREOSCOPIC_TOP_BOTTOM:
p_track->fmt.video.multiview_mode = MULTIVIEW_STEREO_TB;
break;
case ST3D_STEREOSCOPIC_LEFT_RIGHT:
p_track->fmt.video.multiview_mode = MULTIVIEW_STEREO_SBS;
break;
default:
msg_Warn( p_demux, "Unknown stereo mode %d", BOXDATA(p_st3d)->i_stereo_mode );
break;
}
}
const MP4_Box_t *p_prhd = MP4_BoxGet( p_sample, "sv3d/proj/prhd" );
if (p_prhd && BOXDATA(p_prhd))
{
p_track->fmt.video.f_pose_yaw_degrees
= BOXDATA(p_prhd)->f_pose_yaw_degrees;
p_track->fmt.video.f_pose_pitch_degrees
= BOXDATA(p_prhd)->f_pose_pitch_degrees;
p_track->fmt.video.f_pose_roll_degrees
= BOXDATA(p_prhd)->f_pose_roll_degrees;
}
const MP4_Box_t *p_equi = MP4_BoxGet( p_sample, "sv3d/proj/equi" );
const MP4_Box_t *p_cbmp = MP4_BoxGet( p_sample, "sv3d/proj/cbmp" );
if (p_equi && BOXDATA(p_equi))
p_track->fmt.video.projection_mode = PROJECTION_MODE_EQUIRECTANGULAR;
else if (p_cbmp && BOXDATA(p_cbmp))
p_track->fmt.video.projection_mode = PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD;
/* It's a little ugly but .. there are special cases */
switch( p_sample->i_type )
{
......
......@@ -767,6 +767,58 @@ static int MP4_ReadBox_uuid( stream_t *p_stream, MP4_Box_t *p_box )
return 1;
}
static int MP4_ReadBox_st3d( stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_READBOX_ENTER( MP4_Box_data_st3d_t, NULL );
MP4_Box_data_st3d_t *p_data = p_box->data.p_st3d;
MP4_GET1BYTE( p_data->i_stereo_mode );
MP4_READBOX_EXIT( 1 );
}
static int MP4_ReadBox_prhd( stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_READBOX_ENTER( MP4_Box_data_prhd_t, NULL );
MP4_Box_data_prhd_t *p_data = p_box->data.p_prhd;
int32_t fixed16_16;
MP4_GET4BYTES( fixed16_16 );
p_data->f_pose_yaw_degrees = (float) fixed16_16 / 65536.0f;
MP4_GET4BYTES( fixed16_16 );
p_data->f_pose_pitch_degrees = (float) fixed16_16 / 65536.0f;
MP4_GET4BYTES( fixed16_16 );
p_data->f_pose_roll_degrees = (float) fixed16_16 / 65536.0f;
MP4_READBOX_EXIT( 1 );
}
static int MP4_ReadBox_equi( stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_READBOX_ENTER( MP4_Box_data_equi_t, NULL );
MP4_Box_data_equi_t *p_data = p_box->data.p_equi;
MP4_GET4BYTES( p_data->i_projection_bounds_top );
MP4_GET4BYTES( p_data->i_projection_bounds_bottom );
MP4_GET4BYTES( p_data->i_projection_bounds_left );
MP4_GET4BYTES( p_data->i_projection_bounds_right );
MP4_READBOX_EXIT( 1 );
}
static int MP4_ReadBox_cbmp( stream_t *p_stream, MP4_Box_t *p_box )
{
MP4_READBOX_ENTER( MP4_Box_data_cbmp_t, NULL );
MP4_Box_data_cbmp_t *p_data = p_box->data.p_cbmp;
MP4_GET4BYTES( p_data->i_layout );
MP4_GET4BYTES( p_data->i_padding );
MP4_READBOX_EXIT( 1 );
}
static void MP4_FreeBox_sidx( MP4_Box_t *p_box )
{
FREENULL( p_box->data.p_sidx->p_items );
......@@ -4411,6 +4463,16 @@ static const struct
{ ATOM_mfro, MP4_ReadBox_mfro, ATOM_mfra },
{ ATOM_uuid, MP4_ReadBox_uuid, 0 },
/* spatial/360°/VR */
{ ATOM_st3d, MP4_ReadBox_st3d, ATOM_avc1 },
{ ATOM_st3d, MP4_ReadBox_st3d, ATOM_mp4v },
{ ATOM_sv3d, MP4_ReadBoxContainer, ATOM_avc1 },
{ ATOM_sv3d, MP4_ReadBoxContainer, ATOM_mp4v },
{ ATOM_proj, MP4_ReadBoxContainer, ATOM_sv3d },
{ ATOM_prhd, MP4_ReadBox_prhd, ATOM_proj },
{ ATOM_equi, MP4_ReadBox_equi, ATOM_proj },
{ ATOM_cbmp, MP4_ReadBox_cbmp, ATOM_proj },
/* Last entry */
{ 0, MP4_ReadBox_default, 0 }
};
......
......@@ -118,6 +118,13 @@ typedef int64_t stime_t;
#define ATOM_tfra VLC_FOURCC( 't', 'f', 'r', 'a' )
#define ATOM_keys VLC_FOURCC( 'k', 'e', 'y', 's' )
#define ATOM_st3d VLC_FOURCC( 's', 't', '3', 'd' )
#define ATOM_sv3d VLC_FOURCC( 's', 'v', '3', 'd' )
#define ATOM_proj VLC_FOURCC( 'p', 'r', 'o', 'j' )
#define ATOM_prhd VLC_FOURCC( 'p', 'r', 'h', 'd' )
#define ATOM_cbmp VLC_FOURCC( 'c', 'b', 'm', 'p' )
#define ATOM_equi VLC_FOURCC( 'e', 'q', 'u', 'i' )
#define ATOM_nmhd VLC_FOURCC( 'n', 'm', 'h', 'd' )
#define ATOM_mp2v VLC_FOURCC( 'm', 'p', '2', 'v' )
#define ATOM_mp4v VLC_FOURCC( 'm', 'p', '4', 'v' )
......@@ -1544,6 +1551,38 @@ typedef struct
uint32_t i_projection_mode;
} MP4_Box_data_360_t;
typedef struct
{
enum {
ST3D_MONOSCOPIC = 0,
ST3D_STEREOSCOPIC_TOP_BOTTOM = 1,
ST3D_STEREOSCOPIC_LEFT_RIGHT = 2,
} e_stereo_mode;
uint8_t i_stereo_mode;
} MP4_Box_data_st3d_t;
typedef struct
{
float f_pose_yaw_degrees;
float f_pose_pitch_degrees;
float f_pose_roll_degrees;
} MP4_Box_data_prhd_t;
typedef struct
{
uint32_t i_projection_bounds_top;
uint32_t i_projection_bounds_bottom;
uint32_t i_projection_bounds_left;
uint32_t i_projection_bounds_right;
} MP4_Box_data_equi_t;
typedef struct
{
uint32_t i_layout;
uint32_t i_padding;
} MP4_Box_data_cbmp_t;
/*
typedef struct MP4_Box_data__s
{
......@@ -1650,6 +1689,10 @@ typedef union MP4_Box_data_s
MP4_Box_data_ASF_t *p_asf; /* flip4mac asf streams indicator */
MP4_Box_data_360_t *p_360;
MP4_Box_data_st3d_t *p_st3d;
MP4_Box_data_prhd_t *p_prhd;
MP4_Box_data_equi_t *p_equi;
MP4_Box_data_cbmp_t *p_cbmp;
/* for generic handlers */
MP4_Box_data_binary_t *p_binary;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment