[vlc-commits] demux: mp4: do chan bitmap reordering (fix #12002)
Francois Cartegnie
git at videolan.org
Sat Aug 30 05:30:41 CEST 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | 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 ! */
More information about the vlc-commits
mailing list