vlc | branch: master | Francois Cartegnie <[email protected]> | Wed Aug 27 20:54:46 2014 +0900| [0e3f04662ab4e1de63efb9784b56f80c3ace85d3] | committer: Francois Cartegnie
demux: mp4: do chan bitmap reordering (fix #12002) > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=0e3f04662ab4e1de63efb9784b56f80c3ace85d3 --- modules/demux/mp4/libmp4.h | 49 ++++++++++++++++++++++++++++++++++++ modules/demux/mp4/mp4.c | 60 ++++++++++++++++++++++++++++++++++++++++---- modules/demux/mp4/mp4.h | 2 ++ 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h index 1451ce9..d2a5424 100644 --- a/modules/demux/mp4/libmp4.h +++ b/modules/demux/mp4/libmp4.h @@ -1038,6 +1038,55 @@ typedef struct } MP4_Box_data_avcC_t; +/* According to Apple's CoreAudio/CoreAudioTypes.h */ +#define MP4_CHAN_USE_CHANNELS_DESC 0 +#define MP4_CHAN_USE_CHANNELS_BITMAP (1<<16) + +#define MP4_CHAN_BITMAP_LEFT (1<<0) +#define MP4_CHAN_BITMAP_RIGHT (1<<1) +#define MP4_CHAN_BITMAP_CENTER (1<<2) +#define MP4_CHAN_BITMAP_LFESCREEN (1<<3) +#define MP4_CHAN_BITMAP_BACKLEFT (1<<4) +#define MP4_CHAN_BITMAP_BACKRIGHT (1<<5) +#define MP4_CHAN_BITMAP_LEFTCENTER (1<<6) +#define MP4_CHAN_BITMAP_RIGHTCENTER (1<<7) +#define MP4_CHAN_BITMAP_BACKCENTER (1<<8) +#define MP4_CHAN_BITMAP_SIDELEFT (1<<9) +#define MP4_CHAN_BITMAP_SIDERIGHT (1<<10) +#define MP4_CHAN_BITMAP_TOPCENTER (1<<11) +#define MP4_CHAN_BITMAP_TOPFRONTLEFT (1<<12) +#define MP4_CHAN_BITMAP_TOPFRONTENTER (1<<13) +#define MP4_CHAN_BITMAP_TOPFRONTRIGHT (1<<14) +#define MP4_CHAN_BITMAP_TOPBACKLEFT (1<<15) +#define MP4_CHAN_BITMAP_TOPBACKCENTER (1<<16) +#define MP4_CHAN_BITMAP_TOPBACKRIGHT (1<<17) + +#define MP4_CHAN_BITMAP_MAPPING_COUNT 18 +static const struct +{ + uint32_t i_bitmap; + uint32_t i_vlc; +} chan_bitmap_mapping[MP4_CHAN_BITMAP_MAPPING_COUNT] = { + { MP4_CHAN_BITMAP_LEFT, AOUT_CHAN_LEFT }, + { MP4_CHAN_BITMAP_RIGHT, AOUT_CHAN_RIGHT }, + { MP4_CHAN_BITMAP_CENTER, AOUT_CHAN_CENTER }, + { MP4_CHAN_BITMAP_LFESCREEN, AOUT_CHAN_LFE }, + { MP4_CHAN_BITMAP_BACKLEFT, AOUT_CHAN_REARLEFT }, + { MP4_CHAN_BITMAP_BACKRIGHT, AOUT_CHAN_REARRIGHT }, + { MP4_CHAN_BITMAP_LEFTCENTER, AOUT_CHAN_MIDDLELEFT }, + { MP4_CHAN_BITMAP_RIGHTCENTER, AOUT_CHAN_MIDDLERIGHT }, + { MP4_CHAN_BITMAP_BACKCENTER, AOUT_CHAN_REARCENTER }, + { MP4_CHAN_BITMAP_SIDELEFT, AOUT_CHAN_LEFT }, + { MP4_CHAN_BITMAP_SIDERIGHT, AOUT_CHAN_RIGHT }, + { MP4_CHAN_BITMAP_TOPCENTER, AOUT_CHAN_CENTER }, + { MP4_CHAN_BITMAP_TOPFRONTLEFT, AOUT_CHAN_LEFT }, + { MP4_CHAN_BITMAP_TOPFRONTENTER,AOUT_CHAN_CENTER }, + { MP4_CHAN_BITMAP_TOPFRONTRIGHT,AOUT_CHAN_RIGHT }, + { MP4_CHAN_BITMAP_TOPBACKLEFT, AOUT_CHAN_REARLEFT }, + { MP4_CHAN_BITMAP_TOPBACKCENTER,AOUT_CHAN_REARCENTER }, + { MP4_CHAN_BITMAP_TOPBACKRIGHT, AOUT_CHAN_REARRIGHT }, +}; + typedef struct { uint8_t i_version; diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c index 94fd6d2..656932c 100644 --- a/modules/demux/mp4/mp4.c +++ b/modules/demux/mp4/mp4.c @@ -36,6 +36,7 @@ #include <vlc_charset.h> /* EnsureUTF8 */ #include <vlc_meta.h> /* vlc_meta_t, vlc_meta_ */ #include <vlc_input.h> +#include <vlc_aout.h> #include <assert.h> #include "id3genres.h" /* for ATOM_gnre */ @@ -114,6 +115,8 @@ static void MP4_TrackCreate ( demux_t *, mp4_track_t *, MP4_Box_t *, bool b_for static int MP4_frg_TrackCreate( demux_t *, mp4_track_t *, MP4_Box_t *); static void MP4_TrackDestroy( mp4_track_t * ); +static void MP4_Block_Send( demux_t *, mp4_track_t *, block_t * ); + static int MP4_TrackSelect ( demux_t *, mp4_track_t *, mtime_t ); static void MP4_TrackUnselect(demux_t *, mp4_track_t * ); @@ -388,6 +391,18 @@ static void CreateTracksFromSmooBox( demux_t *p_demux ) } } +static void MP4_Block_Send( demux_t *p_demux, mp4_track_t *p_track, block_t *p_block ) +{ + if ( p_track->b_chans_reorder && aout_BitsPerSample( p_track->fmt.i_codec ) ) + { + aout_ChannelReorder( p_block->p_buffer, p_block->i_buffer, + p_track->fmt.audio.i_channels, + p_track->rgi_chans_reordering, + p_track->fmt.i_codec ); + } + es_out_Send( p_demux->out, p_track->p_es, p_block ); +} + /***************************************************************************** * Open: check file and initializes MP4 structures *****************************************************************************/ @@ -948,7 +963,7 @@ static int Demux( demux_t *p_demux ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, VLC_TS_0 + p_sys->i_pcr ); b_data_sent = true; } - es_out_Send( p_demux->out, tk->p_es, p_block ); + MP4_Block_Send( p_demux, tk, p_block ); } /* Next sample */ @@ -2357,6 +2372,41 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track, msg_Err( p_demux, "Invalid sample per packet value for qt_version 1. Broken muxer!" ); p_sample->data.p_sample_soun->i_qt_version = 0; } + + /* Lookup for then channels extension */ + const MP4_Box_t *p_chan = MP4_BoxGet( p_sample, "chan" ); + if ( p_chan ) + { + if ( BOXDATA(p_chan)->layout.i_channels_layout_tag == MP4_CHAN_USE_CHANNELS_BITMAP ) + { + uint32_t rgi_chans_sequence[AOUT_CHAN_MAX]; + uint16_t i_vlc_mapping = 0; + uint8_t i_channels = 0; + const uint32_t i_bitmap = BOXDATA(p_chan)->layout.i_channels_bitmap; + for (uint8_t i=0;i<MP4_CHAN_BITMAP_MAPPING_COUNT;i++) + { + if ( chan_bitmap_mapping[i].i_bitmap & i_bitmap ) + { + i_channels++; + if ( (chan_bitmap_mapping[i].i_vlc & i_vlc_mapping) || + i_channels > AOUT_CHAN_MAX ) + { + /* double mapping or unsupported number of channels */ + i_vlc_mapping = 0; + msg_Warn( p_demux, "discarding chan mapping" ); + break; + } + i_vlc_mapping |= chan_bitmap_mapping[i].i_vlc; + rgi_chans_sequence[i_channels - 1] = chan_bitmap_mapping[i].i_vlc; + } + } + p_track->b_chans_reorder = !! + aout_CheckChannelReorder( rgi_chans_sequence, NULL, i_vlc_mapping, + p_track->rgi_chans_reordering ); + } + + } + break; default: @@ -3900,7 +3950,7 @@ static void FlushChunk( demux_t *p_demux, mp4_track_t *tk ) else p_block->i_pts = VLC_TS_INVALID; - es_out_Send( p_demux->out, tk->p_es, p_block ); + MP4_Block_Send( p_demux, tk, p_block ); tk->i_sample++; } @@ -4364,7 +4414,7 @@ int DemuxFrg( demux_t *p_demux ) else p_block->i_pts = VLC_TS_INVALID; - es_out_Send( p_demux->out, tk->p_es, p_block ); + MP4_Block_Send( p_demux, tk, p_block ); tk->i_sample++; @@ -4870,7 +4920,7 @@ static int LeafParseTRUN( demux_t *p_demux, mp4_track_t *p_track, p_block->i_dts = VLC_TS_0 + i_nzdts; p_block->i_pts = VLC_TS_0 + i_nzpts; p_block->i_length = CLOCK_FREQ * dur / p_track->i_timescale; - es_out_Send( p_demux->out, p_track->p_es, p_block ); + MP4_Block_Send( p_demux, p_track, p_block ); } else free( p_block ); @@ -5111,7 +5161,7 @@ static int LeafParseMDATwithMOOV( demux_t *p_demux ) else p_block->i_pts = VLC_TS_INVALID; - es_out_Send( p_demux->out, p_track->p_es, p_block ); + MP4_Block_Send( p_demux, p_track, p_block ); if ( p_demux->p_sys->i_pcr < VLC_TS_0 ) { diff --git a/modules/demux/mp4/mp4.h b/modules/demux/mp4/mp4.h index 813dfd8..df95de9 100644 --- a/modules/demux/mp4/mp4.h +++ b/modules/demux/mp4/mp4.h @@ -73,6 +73,8 @@ typedef struct bool b_mac_encoding; es_format_t fmt; + uint8_t rgi_chans_reordering[AOUT_CHAN_MAX]; + bool b_chans_reorder; es_out_id_t *p_es; /* display size only ! */ _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
