[vlc-devel] [PATCH 2/2] demux: ogg: daala support
Tristan Matthews
le.businessman at gmail.com
Thu Aug 21 08:38:29 CEST 2014
---
modules/demux/ogg.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++
modules/demux/oggseek.c | 5 ++-
2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index b61366b..192e3e0 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -136,6 +136,7 @@ static void Ogg_ResetStream( logical_stream_t *p_stream );
static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t *p_headers, int i_headers );
/* Logical bitstream headers */
+static bool Ogg_ReadDaalaHeader( logical_stream_t *, ogg_packet * );
static bool Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
static bool Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
static bool Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
@@ -446,6 +447,13 @@ static int Demux( demux_t * p_demux )
Ogg_ReadTheoraHeader( p_stream, &oggpacket );
p_stream->i_secondary_header_packets = 0;
}
+ else if( p_stream->fmt.i_codec == VLC_CODEC_DAALA &&
+ oggpacket.bytes >= 6 &&
+ ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
+ {
+ Ogg_ReadDaalaHeader( p_stream, &oggpacket );
+ p_stream->i_secondary_header_packets = 0;
+ }
else if( p_stream->fmt.i_codec == VLC_CODEC_VORBIS &&
oggpacket.bytes >= 7 &&
! memcmp( oggpacket.packet, "\x01vorbis", 7 ) )
@@ -938,6 +946,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
else if( p_oggpacket->granulepos > 0 )
{
if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
+ p_stream->fmt.i_codec == VLC_CODEC_DAALA ||
p_stream->fmt.i_codec == VLC_CODEC_KATE ||
p_stream->fmt.i_codec == VLC_CODEC_VP8 ||
p_stream->fmt.i_codec == VLC_CODEC_DIRAC ||
@@ -1162,6 +1171,12 @@ static void Ogg_DecodePacket( demux_t *p_demux,
b_xiph = true;
break;
+ case VLC_CODEC_DAALA:
+ if( p_stream->i_packets_backup == 3 )
+ p_stream->b_force_backup = false;
+ b_xiph = true;
+ break;
+
case VLC_CODEC_SPEEX:
if( p_stream->i_packets_backup == 2 + p_stream->i_extra_headers_packets )
p_stream->b_force_backup = false;
@@ -1339,6 +1354,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
p_stream->fmt.i_codec != VLC_CODEC_FLAC &&
p_stream->fmt.i_codec != VLC_CODEC_TARKIN &&
p_stream->fmt.i_codec != VLC_CODEC_THEORA &&
+ p_stream->fmt.i_codec != VLC_CODEC_DAALA &&
p_stream->fmt.i_codec != VLC_CODEC_CMML &&
p_stream->fmt.i_codec != VLC_CODEC_DIRAC &&
p_stream->fmt.i_codec != VLC_CODEC_KATE )
@@ -1600,6 +1616,21 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
p_ogg->i_streams--;
}
}
+ /* Check for Daala header */
+ else if( oggpacket.bytes >= 6 &&
+ ! memcmp( oggpacket.packet, "\x80""daala", 6 ) )
+ {
+ if ( Ogg_ReadDaalaHeader( p_stream, &oggpacket ) )
+ msg_Dbg( p_demux,
+ "found daala header, bitrate: %i, rate: %f",
+ p_stream->fmt.i_bitrate, p_stream->f_rate );
+ else
+ {
+ msg_Dbg( p_demux, "found invalid Daala header" );
+ Ogg_LogicalStreamDelete( p_demux, p_stream );
+ p_ogg->i_streams--;
+ }
+ }
/* Check for Dirac header */
else if( ( oggpacket.bytes >= 5 &&
! memcmp( oggpacket.packet, "BBCD\x00", 5 ) ) ||
@@ -2381,6 +2412,7 @@ static void Ogg_ExtractMeta( demux_t *p_demux, es_format_t *p_fmt, const uint8_t
/* 3 headers with the 2° one being the comments */
case VLC_CODEC_VORBIS:
case VLC_CODEC_THEORA:
+ case VLC_CODEC_DAALA:
Ogg_ExtractXiphMeta( p_demux, p_fmt, p_headers, i_headers, 1+6 );
break;
case VLC_CODEC_OPUS:
@@ -2484,6 +2516,68 @@ static bool Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
return true;
}
+static bool Ogg_ReadDaalaHeader( logical_stream_t *p_stream,
+ ogg_packet *p_oggpacket )
+{
+ oggpack_buffer opb;
+ uint32_t i_timebase_numerator;
+ uint32_t i_timebase_denominator;
+ int i_keyframe_frequency_force;
+ uint8_t i_major;
+ uint8_t i_minor;
+ uint8_t i_subminor;
+ int i_version;
+
+ p_stream->fmt.i_cat = VIDEO_ES;
+ p_stream->fmt.i_codec = VLC_CODEC_DAALA;
+
+ /* Signal that we want to keep a backup of the daala
+ * stream headers. They will be used when switching between
+ * audio streams. */
+ p_stream->b_force_backup = true;
+
+ /* Cheat and get additionnal info ;) */
+ oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes );
+ oggpack_adv( &opb, 48 );
+
+ i_major = oggpack_read( &opb, 8 ); /* major version num */
+ i_minor = oggpack_read( &opb, 8 ); /* minor version num */
+ i_subminor = oggpack_read( &opb, 8 ); /* subminor version num */
+
+ oggpack_adv( &opb, 32 ); /* width */
+ oggpack_adv( &opb, 32 ); /* height */
+
+ oggpack_adv( &opb, 32 ); /* aspect numerator */
+ oggpack_adv( &opb, 32 ); /* aspect denominator */
+ i_timebase_numerator = oggpack_read( &opb, 32 );
+
+ i_timebase_denominator = oggpack_read( &opb, 32 );
+ i_timebase_denominator = __MAX( i_timebase_denominator, 1 );
+
+ p_stream->fmt.video.i_frame_rate = i_timebase_numerator;
+ p_stream->fmt.video.i_frame_rate_base = i_timebase_denominator;
+
+ oggpack_adv( &opb, 32 ); /* frame duration */
+
+ i_keyframe_frequency_force = 1 << oggpack_read( &opb, 8 );
+
+ /* granule_shift = i_log( frequency_force -1 ) */
+ p_stream->i_granule_shift = 0;
+ i_keyframe_frequency_force--;
+ while( i_keyframe_frequency_force )
+ {
+ p_stream->i_granule_shift++;
+ i_keyframe_frequency_force >>= 1;
+ }
+
+ i_version = i_major * 1000000 + i_minor * 1000 + i_subminor;
+ p_stream->i_keyframe_offset = 0;
+ p_stream->f_rate = ((double)i_timebase_numerator) / i_timebase_denominator;
+ if ( p_stream->f_rate == 0 ) return false;
+
+ return true;
+}
+
static bool Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
ogg_packet *p_oggpacket )
{
@@ -2790,6 +2884,14 @@ static void Ogg_ApplyContentType( logical_stream_t *p_stream, const char* psz_va
*b_force_backup = true;
}
+ else if( !strncmp(psz_value, "video/x-daala", 13) ||
+ !strncmp(psz_value, "video/daala", 11) )
+ {
+ p_stream->fmt.i_cat = VIDEO_ES;
+ p_stream->fmt.i_codec = VLC_CODEC_DAALA;
+
+ *b_force_backup = true;
+ }
else if( !strncmp(psz_value, "video/x-xvid", 12) )
{
p_stream->fmt.i_cat = VIDEO_ES;
diff --git a/modules/demux/oggseek.c b/modules/demux/oggseek.c
index 8ed3344..d5b6f49 100644
--- a/modules/demux/oggseek.c
+++ b/modules/demux/oggseek.c
@@ -452,6 +452,7 @@ bool Ogg_IsKeyFrame( logical_stream_t *p_stream, ogg_packet *p_packet )
else switch ( p_stream->fmt.i_codec )
{
case VLC_CODEC_THEORA:
+ case VLC_CODEC_DAALA: /* Same convention used in daala */
if ( p_packet->bytes <= 0 || p_packet->packet[0] & THEORA_FTYPE_NOTDATA )
return false;
else
@@ -471,7 +472,8 @@ int64_t Ogg_GetKeyframeGranule( logical_stream_t *p_stream, int64_t i_granule )
{
return -1; /* We have no way to know */
}
- else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
+ else if( p_stream->fmt.i_codec == VLC_CODEC_THEORA ||
+ p_stream->fmt.i_codec == VLC_CODEC_DAALA )
{
return ( i_granule >> p_stream->i_granule_shift ) << p_stream->i_granule_shift;
}
@@ -689,6 +691,7 @@ int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
else switch( p_stream->fmt.i_codec )
{
case VLC_CODEC_THEORA:
+ case VLC_CODEC_DAALA:
case VLC_CODEC_KATE:
{
ogg_int64_t iframe = i_granule >> p_stream->i_granule_shift;
--
1.9.3
More information about the vlc-devel
mailing list