From cd734d3adc4e26c15c0e9ddecb5af8e39ccb3d37 Mon Sep 17 00:00:00 2001 From: Francois Cartegnie <fcvlcdev@free.fr> Date: Wed, 24 Sep 2014 19:30:51 +0200 Subject: [PATCH] demux: mp4: add support for EIA-608 (fix #6775) --- modules/demux/mp4/libmp4.h | 3 ++ modules/demux/mp4/mp4.c | 72 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/modules/demux/mp4/libmp4.h b/modules/demux/mp4/libmp4.h index d8ec68446598..d4b68a31cef9 100644 --- a/modules/demux/mp4/libmp4.h +++ b/modules/demux/mp4/libmp4.h @@ -215,6 +215,9 @@ #define ATOM_tx3g VLC_FOURCC( 't', 'x', '3', 'g' ) #define ATOM_subp VLC_FOURCC( 's', 'u', 'b', 'p' ) #define ATOM_sbtl VLC_FOURCC( 's', 'b', 't', 'l' ) +#define ATOM_clcp VLC_FOURCC( 'c', 'l', 'c', 'p' ) +#define ATOM_c608 VLC_FOURCC( 'c', '6', '0', '8' ) +#define ATOM_c708 VLC_FOURCC( 'c', '7', '0', '8' ) #define ATOM_0xa9nam VLC_FOURCC( 0xa9, 'n', 'a', 'm' ) #define ATOM_0xa9aut VLC_FOURCC( 0xa9, 'a', 'u', 't' ) diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c index 655cb8cc1c3b..fa0819fbcd46 100644 --- a/modules/demux/mp4/mp4.c +++ b/modules/demux/mp4/mp4.c @@ -392,6 +392,62 @@ static void CreateTracksFromSmooBox( demux_t *p_demux ) } } +static block_t * MP4_EIA608_Convert( block_t * p_block ) +{ + /* Rebuild codec data from encap */ + size_t i_copied = 0; + size_t i_remaining = p_block->i_buffer; + uint32_t i_bytes = 0; + block_t *p_newblock; + + if ( i_remaining < 10 || + !(i_bytes = GetDWBE(p_block->p_buffer)) || + (i_bytes + 8 > i_remaining) || + memcmp("cdat", &p_block->p_buffer[4], 4) || + !(p_newblock = block_Alloc( i_remaining * 3 - 8 )) ) + { + p_block->i_buffer = 0; + return p_block; + } + + uint8_t *p_write = p_newblock->p_buffer; + uint8_t *p_read = &p_block->p_buffer[8]; + i_bytes -= 8; + i_remaining -= 8; + + do + { + p_write[i_copied++] = 0; /* cc1 == field 0 */ + p_write[i_copied++] = p_read[0]; + p_write[i_copied++] = p_read[1]; + p_read += 2; + i_bytes -= 2; + i_remaining -= 2; + } while( i_bytes >= 2 ); + + if ( i_remaining >= 10 && + (i_bytes = GetDWBE(p_read)) && + (i_bytes + 8 <= i_remaining) && + !memcmp("cdt2", &p_read[4], 4) ) + { + p_read += 8; + i_bytes -= 8; + i_remaining -= 8; + do + { + p_write[i_copied++] = 0; /* cc1 == field 0 */ + p_write[i_copied++] = p_read[0]; + p_write[i_copied++] = p_read[1]; + p_read += 2; + i_bytes -= 2; + } while( i_bytes >= 2 ); + } + + block_Release( p_block ); + p_newblock->i_buffer = i_copied; + return p_newblock; +} + static block_t * MP4_Block_Read( demux_t *p_demux, const mp4_track_t *p_track, int i_size ) { block_t *p_block = stream_Block( p_demux->s, i_size ); @@ -407,7 +463,9 @@ static block_t * MP4_Block_Read( demux_t *p_demux, const mp4_track_t *p_track, i case VLC_CODEC_SPU: /* accept as-is */ break; - + case VLC_CODEC_EIA608_1: + p_block = MP4_EIA608_Convert( p_block ); + break; default: p_block->i_buffer = 0; break; @@ -2438,7 +2496,6 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track, break; } - /* It's a little ugly but .. there are special cases */ switch( p_sample->i_type ) { @@ -2516,6 +2573,12 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track, p_track->fmt.i_codec = VLC_CODEC_H263; break; + case( ATOM_c608 ): /* EIA608 closed captions */ + //case( ATOM_c708 ): /* EIA708 closed captions */ + p_track->fmt.i_codec = VLC_CODEC_EIA608_1; + p_track->fmt.i_cat = SPU_ES; + break; + case( VLC_FOURCC( 't', 'e', 'x', 't' ) ): case( VLC_FOURCC( 't', 'x', '3', 'g' ) ): { @@ -3219,6 +3282,11 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track, p_track->fmt.i_cat = SPU_ES; break; + /* closed captions */ + case( ATOM_clcp ): + p_track->fmt.i_cat = SPU_ES; + break; + default: return; } -- GitLab