diff --git a/modules/demux/mp4/essetup.c b/modules/demux/mp4/essetup.c index bc37414251eaa075c8d51eec03c4d41dc382d0ab..263f75f405b8a077206260266688fb0bcfc8946f 100644 --- a/modules/demux/mp4/essetup.c +++ b/modules/demux/mp4/essetup.c @@ -1033,6 +1033,35 @@ int SetupAudioES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample ) break; } + case ATOM_ipcm: + case ATOM_fpcm: + { + const MP4_Box_t *p_pcmC = MP4_BoxGet( p_sample, "pcmC" ); + if( p_pcmC ) + { + const vlc_fourcc_t lookup = p_sample->i_type + + BOXDATA(p_pcmC)->i_sample_size + + (BOXDATA(p_pcmC)->i_format_flags & 0x01); + const vlc_fourcc_t lookuptable[10][2] = + { + { ATOM_fpcm + 32 + 0, VLC_CODEC_F32B }, + { ATOM_fpcm + 32 + 1, VLC_CODEC_F32L }, + { ATOM_fpcm + 64 + 0, VLC_CODEC_F64B }, + { ATOM_fpcm + 64 + 1, VLC_CODEC_F64L }, + { ATOM_ipcm + 16 + 0, VLC_CODEC_S16B }, + { ATOM_ipcm + 16 + 1, VLC_CODEC_S16L }, + { ATOM_ipcm + 24 + 0, VLC_CODEC_S24B }, + { ATOM_ipcm + 24 + 1, VLC_CODEC_S24L }, + { ATOM_ipcm + 32 + 0, VLC_CODEC_S32B }, + { ATOM_ipcm + 32 + 1, VLC_CODEC_S32L }, + }; + for( size_t i = 0; i<10; i++ ) + if( lookuptable[i][0] == lookup ) + p_track->fmt.i_codec = lookuptable[i][1]; + } + break; + } + case ATOM_in24: p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ? VLC_CODEC_S24L : VLC_CODEC_S24B; diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c index f66c3ddb4ba255451206c5f2b42a4f3e89720fbe..5f7a90ed3c7f00e8bce517d3310043ae66b08ad9 100644 --- a/modules/demux/mp4/libmp4.c +++ b/modules/demux/mp4/libmp4.c @@ -2560,6 +2560,20 @@ static int MP4_ReadBox_enda( stream_t *p_stream, MP4_Box_t *p_box ) MP4_READBOX_EXIT( 1 ); } +static int MP4_ReadBox_pcmC( stream_t *p_stream, MP4_Box_t *p_box ) +{ + MP4_READBOX_ENTER( MP4_Box_data_pcmC_t, NULL ); + if(i_read != 6) + MP4_READBOX_EXIT( 0 ); + uint32_t temp; + MP4_GET4BYTES(temp); + if(temp != 0) /* support only v0 */ + MP4_READBOX_EXIT( 0 ); + MP4_GET1BYTE(p_box->data.p_pcmC->i_format_flags); + MP4_GET1BYTE(p_box->data.p_pcmC->i_sample_size); + MP4_READBOX_EXIT( 1 ); +} + static void MP4_FreeBox_sample_soun( MP4_Box_t *p_box ) { FREENULL( p_box->data.p_sample_soun->p_qt_description ); @@ -4562,6 +4576,7 @@ static const struct { ATOM_fiel, MP4_ReadBox_fiel, 0 }, { ATOM_glbl, MP4_ReadBox_Binary, ATOM_FFV1 }, { ATOM_enda, MP4_ReadBox_enda, 0 }, + { ATOM_pcmC, MP4_ReadBox_pcmC, 0 }, /* ISO-IEC 23003-5 */ { ATOM_iods, MP4_ReadBox_iods, 0 }, { ATOM_pasp, MP4_ReadBox_pasp, 0 }, { ATOM_btrt, MP4_ReadBox_btrt, 0 }, /* codecs bitrate stsd/????/btrt */ diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h index 884eb8aef90c281d7c41c471fe63738988d33197..087ce07d45ee2dbd979cbfc65d31a547b42ba5b9 100644 --- a/modules/demux/mp4/libmp4.h +++ b/modules/demux/mp4/libmp4.h @@ -204,6 +204,11 @@ typedef int64_t stime_t; #define ATOM_fLaC VLC_FOURCC( 'f', 'L', 'a', 'C' ) #define ATOM_dfLa VLC_FOURCC( 'd', 'f', 'L', 'a' ) +/* ISO-IEC 23003-5 */ +#define ATOM_fpcm VLC_FOURCC( 'f', 'p', 'c', 'm' ) +#define ATOM_ipcm VLC_FOURCC( 'i', 'p', 'c', 'm' ) +#define ATOM_pcmC VLC_FOURCC( 'p', 'c', 'm', 'C' ) + /* XiphQT */ #define ATOM_fCtS VLC_FOURCC( 'f', 'C', 't', 'S' ) #define ATOM_vCtH VLC_FOURCC( 'v', 'C', 't', 'H' ) @@ -1476,6 +1481,12 @@ typedef struct } MP4_Box_data_enda_t; +typedef struct +{ + uint8_t i_format_flags; + uint8_t i_sample_size; +} MP4_Box_data_pcmC_t; + typedef struct { uint32_t i_entry_count; @@ -1703,6 +1714,7 @@ typedef union MP4_Box_data_s MP4_Box_data_fiel_t *p_fiel; MP4_Box_data_chan_t *p_chan; MP4_Box_data_enda_t *p_enda; + MP4_Box_data_pcmC_t *p_pcmC; MP4_Box_data_keys_t *p_keys; MP4_Box_data_iods_t *p_iods; MP4_Box_data_btrt_t *p_btrt;