Skip to content

Commit

Permalink
demux: ogg: daala support
Browse files Browse the repository at this point in the history
  • Loading branch information
tmatth committed Aug 28, 2014
1 parent 774d273 commit 1d3d323
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 1 deletion.
102 changes: 102 additions & 0 deletions modules/demux/ogg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 * );
Expand Down Expand Up @@ -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 ) )
Expand Down Expand Up @@ -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 ||
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 ) ) ||
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion modules/demux/oggseek.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 1d3d323

Please sign in to comment.