[vlc-commits] demux: mp4: add WMV3/WMA2 in mov support
Francois Cartegnie
git at videolan.org
Mon Oct 6 13:59:14 CEST 2014
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sun Oct 5 17:35:12 2014 +0200| [fe5fe6249b22f139a8302919a2279afbae083fe8] | committer: Francois Cartegnie
demux: mp4: add WMV3/WMA2 in mov support
aka flip4mac format.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=fe5fe6249b22f139a8302919a2279afbae083fe8
---
modules/demux/Makefile.am | 3 +-
modules/demux/mp4/mp4.c | 154 ++++++++++++++++++++++++++++++++++++++++++++-
modules/demux/mp4/mp4.h | 6 ++
3 files changed, 161 insertions(+), 2 deletions(-)
diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 432c8b0..b2bf46d 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -191,7 +191,8 @@ EXTRA_LTLIBRARIES += libmkv_plugin.la
libmp4_plugin_la_SOURCES = demux/mp4/mp4.c demux/mp4/mp4.h \
demux/mp4/libmp4.c demux/mp4/libmp4.h \
- demux/mp4/id3genres.h demux/mp4/languages.h
+ demux/mp4/id3genres.h demux/mp4/languages.h \
+ demux/asf/asfpacket.c demux/asf/asfpacket.h
libmp4_plugin_la_LIBADD = $(LIBM)
libmp4_plugin_la_LDFLAGS = $(AM_LDFLAGS)
if HAVE_ZLIB
diff --git a/modules/demux/mp4/mp4.c b/modules/demux/mp4/mp4.c
index 42c718d..eff7bf8 100644
--- a/modules/demux/mp4/mp4.c
+++ b/modules/demux/mp4/mp4.c
@@ -104,6 +104,12 @@ struct demux_sys_t
/* */
input_title_t *p_title;
+
+ /* ASF in MP4 */
+ asf_packet_sys_t asfpacketsys;
+ uint64_t i_preroll; /* foobar */
+ int64_t i_preroll_start;
+ mp4_track_t *p_current_track; /* avoids matching stream_number */
};
#define BOXDATA(type) type->data.type
@@ -145,6 +151,11 @@ static int LeafGetTrackAndChunkByMOOVPos( demux_t *p_demux, uint64_t *pi_pos,
mp4_track_t **pp_tk, unsigned int *pi_chunk );
static int LeafMapTrafTrunContextes( demux_t *p_demux, MP4_Box_t *p_moof );
+/* ASF Handlers */
+static asf_track_info_t * MP4ASF_GetTrackInfo( asf_packet_sys_t *p_packetsys, uint8_t i_stream_number );
+static void MP4ASF_Send(asf_packet_sys_t *p_packetsys, uint8_t i_stream_number, block_t **pp_frame);
+static void MP4ASF_ResetFrames( demux_sys_t *p_sys );
+
/* Helpers */
static uint32_t stream_ReadU32( stream_t *s, void *p_read, uint32_t i_toread )
@@ -483,7 +494,26 @@ static void MP4_Block_Send( demux_t *p_demux, mp4_track_t *p_track, block_t *p_b
p_track->rgi_chans_reordering,
p_track->fmt.i_codec );
}
- es_out_Send( p_demux->out, p_track->p_es, p_block );
+
+ /* ASF packets in mov */
+ if( p_track->p_asf )
+ {
+ /* Fake a new stream from MP4 block */
+ stream_t *p_stream = p_demux->s;
+ p_demux->s = stream_MemoryNew( p_demux, p_block->p_buffer, p_block->i_buffer, true );
+ if ( p_demux->s )
+ {
+ p_track->i_dts_backup = p_block->i_dts;
+ p_track->i_pts_backup = p_block->i_pts;
+ /* And demux it as ASF packet */
+ DemuxASFPacket( &p_demux->p_sys->asfpacketsys, p_block->i_buffer, p_block->i_buffer );
+ stream_Delete(p_demux->s);
+ }
+ block_Release(p_block);
+ p_demux->s = p_stream;
+ }
+ else
+ es_out_Send( p_demux->out, p_track->p_es, p_block );
}
/*****************************************************************************
@@ -859,6 +889,15 @@ static int Open( vlc_object_t * p_this )
/* */
LoadChapter( p_demux );
+ p_sys->asfpacketsys.p_demux = p_demux;
+ p_sys->asfpacketsys.pi_preroll = &p_sys->i_preroll;
+ p_sys->asfpacketsys.pi_preroll_start = &p_sys->i_preroll_start;
+ p_sys->asfpacketsys.pf_doskip = NULL;
+ p_sys->asfpacketsys.pf_send = MP4ASF_Send;
+ p_sys->asfpacketsys.pf_gettrackinfo = MP4ASF_GetTrackInfo;
+ p_sys->asfpacketsys.pf_updatetime = NULL;
+ p_sys->asfpacketsys.pf_setaspectratio = NULL;
+
return VLC_SUCCESS;
error:
@@ -1118,6 +1157,7 @@ static int Seek( demux_t *p_demux, mtime_t i_date )
}
MP4_UpdateSeekpoint( p_demux );
+ MP4ASF_ResetFrames( p_sys );
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
return VLC_SUCCESS;
@@ -1220,6 +1260,7 @@ static int LeafSeekToTime( demux_t *p_demux, mtime_t i_nztime )
return VLC_EGENERIC;
}
+ MP4ASF_ResetFrames( p_sys );
/* And set next display time in that trun/fragment */
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, VLC_TS_0 + i_nztime );
return VLC_SUCCESS;
@@ -2976,6 +3017,56 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
break;
}
+ case ATOM_WMA2:
+ {
+ MP4_Box_t *p_WMA2 = MP4_BoxGet( p_sample, "wave/WMA2" );
+ if( p_WMA2 && BOXDATA(p_WMA2) )
+ {
+ p_track->fmt.audio.i_channels = BOXDATA(p_WMA2)->Format.nChannels;
+ p_track->fmt.audio.i_rate = BOXDATA(p_WMA2)->Format.nSamplesPerSec;
+ p_track->fmt.i_bitrate = BOXDATA(p_WMA2)->Format.nAvgBytesPerSec * 8;
+ p_track->fmt.audio.i_blockalign = BOXDATA(p_WMA2)->Format.nBlockAlign;
+ p_track->fmt.audio.i_bitspersample = BOXDATA(p_WMA2)->Format.wBitsPerSample;
+ p_track->fmt.i_extra = BOXDATA(p_WMA2)->i_extra;
+ if( p_track->fmt.i_extra > 0 )
+ {
+ p_track->fmt.p_extra = malloc( BOXDATA(p_WMA2)->i_extra );
+ memcpy( p_track->fmt.p_extra, BOXDATA(p_WMA2)->p_extra,
+ p_track->fmt.i_extra );
+ }
+ p_track->p_asf = MP4_BoxGet( p_sample, "wave/ASF " );
+ }
+ else
+ {
+ msg_Err( p_demux, "missing WMA2 %4.4s", (char*) &p_sample->p_father->i_type );
+ assert(false);
+ }
+ break;
+ }
+
+ case ATOM_WMV3:
+ {
+ MP4_Box_t *p_strf = MP4_BoxGet( p_sample, "strf", 0 );
+ if ( p_strf && BOXDATA(p_strf) )
+ {
+ p_track->fmt.i_codec = VLC_CODEC_WMV3;
+ p_track->fmt.video.i_width = BOXDATA(p_strf)->bmiHeader.biWidth;
+ p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
+ p_track->fmt.video.i_height = BOXDATA(p_strf)->bmiHeader.biHeight;
+ p_track->fmt.video.i_visible_height =p_track->fmt.video.i_height;
+ p_track->fmt.video.i_bits_per_pixel = BOXDATA(p_strf)->bmiHeader.biBitCount;
+ p_track->fmt.i_extra = BOXDATA(p_strf)->i_extra;
+ if( p_track->fmt.i_extra > 0 )
+ {
+ p_track->fmt.p_extra = malloc( BOXDATA(p_strf)->i_extra );
+ memcpy( p_track->fmt.p_extra, BOXDATA(p_strf)->p_extra,
+ p_track->fmt.i_extra );
+ }
+ p_track->p_asf = MP4_BoxGet( p_sample, "ASF " );
+ }
+ break;
+ }
+
default:
msg_Dbg( p_demux, "Unrecognized FourCC %4.4s", (char *)&p_sample->i_type );
break;
@@ -3469,6 +3560,9 @@ static void MP4_TrackDestroy( mp4_track_t *p_track )
{
FREENULL( p_track->p_sample_size );
}
+
+ if ( p_track->asfinfo.p_frame )
+ block_ChainRelease( p_track->asfinfo.p_frame );
}
static int MP4_TrackSelect( demux_t *p_demux, mp4_track_t *p_track,
@@ -5612,4 +5706,62 @@ static int DemuxAsLeaf( demux_t *p_demux )
return 1;
}
+/* ASF Handlers */
+inline static mp4_track_t *MP4ASF_GetTrack( asf_packet_sys_t *p_packetsys,
+ uint8_t i_stream_number )
+{
+ demux_sys_t *p_sys = p_packetsys->p_demux->p_sys;
+ for ( unsigned int i=0; i<p_sys->i_tracks; i++ )
+ {
+ if ( p_sys->track[i].p_asf &&
+ i_stream_number == p_sys->track[i].BOXDATA(p_asf)->i_stream_number )
+ {
+ return &p_sys->track[i];
+ }
+ }
+ return NULL;
+}
+
+static asf_track_info_t * MP4ASF_GetTrackInfo( asf_packet_sys_t *p_packetsys,
+ uint8_t i_stream_number )
+{
+ mp4_track_t *p_track = MP4ASF_GetTrack( p_packetsys, i_stream_number );
+ if ( p_track )
+ return &p_track->asfinfo;
+ else
+ return NULL;
+}
+
+static void MP4ASF_Send( asf_packet_sys_t *p_packetsys, uint8_t i_stream_number,
+ block_t **pp_frame )
+{
+ mp4_track_t *p_track = MP4ASF_GetTrack( p_packetsys, i_stream_number );
+ if ( !p_track )
+ {
+ block_Release( *pp_frame );
+ }
+ else
+ {
+ block_t *p_gather = block_ChainGather( *pp_frame );
+ p_gather->i_dts = p_track->i_dts_backup;
+ p_gather->i_pts = p_track->i_pts_backup;
+ es_out_Send( p_packetsys->p_demux->out, p_track->p_es, p_gather );
+ }
+
+ *pp_frame = NULL;
+}
+
+static void MP4ASF_ResetFrames( demux_sys_t *p_sys )
+{
+ for ( unsigned int i=0; i<p_sys->i_tracks; i++ )
+ {
+ mp4_track_t *p_track = &p_sys->track[i];
+ if( p_track->asfinfo.p_frame )
+ {
+ block_ChainRelease( p_track->asfinfo.p_frame );
+ p_track->asfinfo.p_frame = NULL;
+ }
+ }
+}
+
#undef BOXDATA
diff --git a/modules/demux/mp4/mp4.h b/modules/demux/mp4/mp4.h
index df95de9..da164e0 100644
--- a/modules/demux/mp4/mp4.h
+++ b/modules/demux/mp4/mp4.h
@@ -31,6 +31,7 @@
#include <vlc_common.h>
#include "libmp4.h"
+#include "../asf/asfpacket.h"
/* Contain all information about a chunk */
typedef struct
@@ -134,6 +135,11 @@ typedef struct
uint64_t i_traf_base_offset;
} context;
+ /* ASF packets handling */
+ MP4_Box_t *p_asf;
+ mtime_t i_dts_backup;
+ mtime_t i_pts_backup;
+ asf_track_info_t asfinfo;
} mp4_track_t;
typedef struct mp4_fragment_t mp4_fragment_t;
More information about the vlc-commits
mailing list