Commit 1fdde890 authored by Laurent Aimar's avatar Laurent Aimar

* mkv: more ebml element parsing.

parent 7c0d8351
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mkv.cpp : matroska demuxer * mkv.cpp : matroska demuxer
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * Copyright (C) 2001 VideoLAN
* $Id: mkv.cpp,v 1.14 2003/06/25 20:37:37 fenrir Exp $ * $Id: mkv.cpp,v 1.15 2003/06/26 16:46:19 fenrir Exp $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
#include "matroska/KaxTracks.h" #include "matroska/KaxTracks.h"
#include "matroska/KaxTrackAudio.h" #include "matroska/KaxTrackAudio.h"
#include "matroska/KaxTrackVideo.h" #include "matroska/KaxTrackVideo.h"
#include "matroska/KaxTrackEntryData.h"
#include "ebml/StdIOCallback.h" #include "ebml/StdIOCallback.h"
...@@ -175,6 +176,7 @@ typedef struct ...@@ -175,6 +176,7 @@ typedef struct
{ {
int i_cat; int i_cat;
vlc_bool_t b_default; vlc_bool_t b_default;
vlc_bool_t b_enabled;
int i_number; int i_number;
int i_extra_data; int i_extra_data;
...@@ -186,6 +188,7 @@ typedef struct ...@@ -186,6 +188,7 @@ typedef struct
vlc_fourcc_t i_codec; vlc_fourcc_t i_codec;
uint64_t i_default_duration; uint64_t i_default_duration;
float f_timecodescale;
/* video */ /* video */
int i_width; int i_width;
int i_height; int i_height;
...@@ -210,6 +213,14 @@ typedef struct ...@@ -210,6 +213,14 @@ typedef struct
/* hack : it's for seek */ /* hack : it's for seek */
vlc_bool_t b_search_keyframe; vlc_bool_t b_search_keyframe;
/* informative */
char *psz_name;
char *psz_codec_name;
char *psz_codec_settings;
char *psz_codec_info_url;
char *psz_codec_download_url;
} mkv_track_t; } mkv_track_t;
typedef struct typedef struct
...@@ -478,7 +489,8 @@ static int Activate( vlc_object_t * p_this ) ...@@ -478,7 +489,8 @@ static int Activate( vlc_object_t * p_this )
#define tk p_sys->track[p_sys->i_track - 1] #define tk p_sys->track[p_sys->i_track - 1]
memset( &tk, 0, sizeof( mkv_track_t ) ); memset( &tk, 0, sizeof( mkv_track_t ) );
tk.i_cat = UNKNOWN_ES; tk.i_cat = UNKNOWN_ES;
tk.b_default = VLC_FALSE; tk.b_default = VLC_TRUE;
tk.b_enabled = VLC_TRUE;
tk.i_number = p_sys->i_track - 1; tk.i_number = p_sys->i_track - 1;
tk.i_extra_data = 0; tk.i_extra_data = 0;
tk.p_extra_data = NULL; tk.p_extra_data = NULL;
...@@ -486,11 +498,18 @@ static int Activate( vlc_object_t * p_this ) ...@@ -486,11 +498,18 @@ static int Activate( vlc_object_t * p_this )
tk.psz_codec = NULL; tk.psz_codec = NULL;
tk.psz_language = NULL; tk.psz_language = NULL;
tk.i_default_duration = 0; tk.i_default_duration = 0;
tk.f_timecodescale = 1.0;
tk.b_inited = VLC_FALSE; tk.b_inited = VLC_FALSE;
tk.i_data_init = 0; tk.i_data_init = 0;
tk.p_data_init = NULL; tk.p_data_init = NULL;
tk.psz_name = NULL;
tk.psz_codec_name = NULL;
tk.psz_codec_settings = NULL;
tk.psz_codec_info_url = NULL;
tk.psz_codec_download_url = NULL;
p_sys->ep->Down(); p_sys->ep->Down();
while( ( el3 = p_sys->ep->Get() ) != NULL ) while( ( el3 = p_sys->ep->Get() ) != NULL )
...@@ -510,14 +529,6 @@ static int Activate( vlc_object_t * p_this ) ...@@ -510,14 +529,6 @@ static int Activate( vlc_object_t * p_this )
msg_Dbg( p_input, "| | | + Track UID=%u", uint32( tuid ) ); msg_Dbg( p_input, "| | | + Track UID=%u", uint32( tuid ) );
} }
else if( EbmlId( *el3 ) == KaxTrackDefaultDuration::ClassInfos.GlobalId )
{
KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)el3;
defd.ReadData( p_sys->es->I_O() );
tk.i_default_duration = uint64(defd);
msg_Dbg( p_input, "| | | + Track Default Duration=%lld", uint64(defd) );
}
else if( EbmlId( *el3 ) == KaxTrackType::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackType::ClassInfos.GlobalId )
{ {
char *psz_type; char *psz_type;
...@@ -545,47 +556,142 @@ static int Activate( vlc_object_t * p_this ) ...@@ -545,47 +556,142 @@ static int Activate( vlc_object_t * p_this )
msg_Dbg( p_input, "| | | + Track Type=%s", psz_type ); msg_Dbg( p_input, "| | | + Track Type=%s", psz_type );
} }
else if( EbmlId( *el3 ) == KaxTrackAudio::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackFlagEnabled::ClassInfos.GlobalId )
{ {
msg_Dbg( p_input, "| | | + Track Audio" ); KaxTrackFlagEnabled &fenb = *(KaxTrackFlagEnabled*)el3;
tk.i_channels = 0; fenb.ReadData( p_sys->es->I_O() );
tk.i_samplerate = 0;
tk.i_bitspersample = 0;
p_sys->ep->Down(); tk.b_enabled = uint32( fenb );
msg_Dbg( p_input, "| | | + Track Enabled=%u", uint32( fenb ) );
}
else if( EbmlId( *el3 ) == KaxTrackFlagDefault::ClassInfos.GlobalId )
{
KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)el3;
fdef.ReadData( p_sys->es->I_O() );
while( ( el4 = p_sys->ep->Get() ) != NULL ) tk.b_default = uint32( fdef );
msg_Dbg( p_input, "| | | + Track Default=%u", uint32( fdef ) );
}
else if( EbmlId( *el3 ) == KaxTrackFlagLacing::ClassInfos.GlobalId )
{ {
if( EbmlId( *el4 ) == KaxAudioSamplingFreq::ClassInfos.GlobalId ) KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)el3;
lac.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track Lacing=%d", uint32( lac ) );
}
else if( EbmlId( *el3 ) == KaxTrackMinCache::ClassInfos.GlobalId )
{ {
KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4; KaxTrackMinCache &cmin = *(KaxTrackMinCache*)el3;
afreq.ReadData( p_sys->es->I_O() ); cmin.ReadData( p_sys->es->I_O() );
tk.i_samplerate = (int)float( afreq ); msg_Dbg( p_input, "| | | + Track MinCache=%d", uint32( cmin ) );
msg_Dbg( p_input, "| | | | + afreq=%d", tk.i_samplerate );
} }
else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackMaxCache::ClassInfos.GlobalId )
{ {
KaxAudioChannels &achan = *(KaxAudioChannels*)el4; KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)el3;
achan.ReadData( p_sys->es->I_O() ); cmax.ReadData( p_sys->es->I_O() );
tk.i_channels = uint8( achan ); msg_Dbg( p_input, "| | | + Track MaxCache=%d", uint32( cmax ) );
msg_Dbg( p_input, "| | | | + achan=%u", uint8( achan ) );
} }
else if( EbmlId( *el4 ) == KaxAudioBitDepth::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackDefaultDuration::ClassInfos.GlobalId )
{ {
KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)el4; KaxTrackDefaultDuration &defd = *(KaxTrackDefaultDuration*)el3;
abits.ReadData( p_sys->es->I_O() ); defd.ReadData( p_sys->es->I_O() );
tk.i_bitspersample = uint8( abits ); tk.i_default_duration = uint64(defd);
msg_Dbg( p_input, "| | | | + abits=%u", uint8( abits ) ); msg_Dbg( p_input, "| | | + Track Default Duration=%lld", uint64(defd) );
} }
else else if( EbmlId( *el3 ) == KaxTrackTimecodeScale::ClassInfos.GlobalId )
{ {
msg_Dbg( p_input, "| | | | + Unknown (%s)", typeid(*el4).name() ); KaxTrackTimecodeScale &ttcs = *(KaxTrackTimecodeScale*)el3;
ttcs.ReadData( p_sys->es->I_O() );
tk.f_timecodescale = float( ttcs );
msg_Dbg( p_input, "| | | + Track TimeCodeScale=%f", tk.f_timecodescale );
}
else if( EbmlId( *el3 ) == KaxTrackName::ClassInfos.GlobalId )
{
KaxTrackName &tname = *(KaxTrackName*)el3;
tname.ReadData( p_sys->es->I_O() );
tk.psz_name = UTF8ToStr( UTFstring( tname ) );
msg_Dbg( p_input, "| | | + Track Name=%s", tk.psz_name );
} }
else if( EbmlId( *el3 ) == KaxTrackLanguage::ClassInfos.GlobalId )
{
KaxTrackLanguage &lang = *(KaxTrackLanguage*)el3;
lang.ReadData( p_sys->es->I_O() );
tk.psz_language = strdup( string( lang ).c_str() );
msg_Dbg( p_input, "| | | + Track Language=`%s'", string( lang ).c_str() );
} }
p_sys->ep->Up(); else if( EbmlId( *el3 ) == KaxCodecID::ClassInfos.GlobalId )
{
KaxCodecID &codecid = *(KaxCodecID*)el3;
codecid.ReadData( p_sys->es->I_O() );
tk.psz_codec = strdup( string( codecid ).c_str() );
msg_Dbg( p_input, "| | | + Track CodecId=%s", string( codecid ).c_str() );
}
else if( EbmlId( *el3 ) == KaxCodecPrivate::ClassInfos.GlobalId )
{
KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)el3;
cpriv.ReadData( p_sys->es->I_O() );
tk.i_extra_data = cpriv.GetSize();
if( tk.i_extra_data > 0 )
{
tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data );
memcpy( tk.p_extra_data, cpriv.GetBuffer(), tk.i_extra_data );
}
msg_Dbg( p_input, "| | | + Track CodecPrivate size=%lld", cpriv.GetSize() );
}
else if( EbmlId( *el3 ) == KaxCodecName::ClassInfos.GlobalId )
{
KaxCodecName &cname = *(KaxCodecName*)el3;
cname.ReadData( p_sys->es->I_O() );
tk.psz_codec_name = UTF8ToStr( UTFstring( cname ) );
msg_Dbg( p_input, "| | | + Track Codec Name=%s", tk.psz_codec_name );
}
else if( EbmlId( *el3 ) == KaxCodecSettings::ClassInfos.GlobalId )
{
KaxCodecSettings &cset = *(KaxCodecSettings*)el3;
cset.ReadData( p_sys->es->I_O() );
tk.psz_codec_settings = UTF8ToStr( UTFstring( cset ) );
msg_Dbg( p_input, "| | | + Track Codec Settings=%s", tk.psz_codec_settings );
}
else if( EbmlId( *el3 ) == KaxCodecInfoURL::ClassInfos.GlobalId )
{
KaxCodecInfoURL &ciurl = *(KaxCodecInfoURL*)el3;
ciurl.ReadData( p_sys->es->I_O() );
tk.psz_codec_info_url = strdup( string( ciurl ).c_str() );
msg_Dbg( p_input, "| | | + Track Codec Info URL=%s", tk.psz_codec_info_url );
}
else if( EbmlId( *el3 ) == KaxCodecDownloadURL::ClassInfos.GlobalId )
{
KaxCodecDownloadURL &cdurl = *(KaxCodecDownloadURL*)el3;
cdurl.ReadData( p_sys->es->I_O() );
tk.psz_codec_download_url = strdup( string( cdurl ).c_str() );
msg_Dbg( p_input, "| | | + Track Codec Info URL=%s", tk.psz_codec_download_url );
}
else if( EbmlId( *el3 ) == KaxCodecDecodeAll::ClassInfos.GlobalId )
{
KaxCodecDecodeAll &cdall = *(KaxCodecDecodeAll*)el3;
cdall.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track Codec Decode All=%u <== UNUSED", uint8( cdall ) );
}
else if( EbmlId( *el3 ) == KaxTrackOverlay::ClassInfos.GlobalId )
{
KaxTrackOverlay &tovr = *(KaxTrackOverlay*)el3;
tovr.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track Overlay=%u <== UNUSED", uint32( tovr ) );
} }
else if( EbmlId( *el3 ) == KaxTrackVideo::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackVideo::ClassInfos.GlobalId )
{ {
...@@ -600,7 +706,21 @@ static int Activate( vlc_object_t * p_this ) ...@@ -600,7 +706,21 @@ static int Activate( vlc_object_t * p_this )
while( ( el4 = p_sys->ep->Get() ) != NULL ) while( ( el4 = p_sys->ep->Get() ) != NULL )
{ {
if( EbmlId( *el4 ) == KaxVideoPixelWidth::ClassInfos.GlobalId ) if( EbmlId( *el4 ) == KaxVideoFlagInterlaced::ClassInfos.GlobalId )
{
KaxVideoFlagInterlaced &fint = *(KaxVideoFlagInterlaced*)el4;
fint.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | | + Track Video Interlaced=%u", uint8( fint ) );
}
else if( EbmlId( *el4 ) == KaxVideoStereoMode::ClassInfos.GlobalId )
{
KaxVideoStereoMode &stereo = *(KaxVideoStereoMode*)el4;
stereo.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | | + Track Video Stereo Mode=%u", uint8( stereo ) );
}
else if( EbmlId( *el4 ) == KaxVideoPixelWidth::ClassInfos.GlobalId )
{ {
KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)el4; KaxVideoPixelWidth &vwidth = *(KaxVideoPixelWidth*)el4;
vwidth.ReadData( p_sys->es->I_O() ); vwidth.ReadData( p_sys->es->I_O() );
...@@ -640,71 +760,76 @@ static int Activate( vlc_object_t * p_this ) ...@@ -640,71 +760,76 @@ static int Activate( vlc_object_t * p_this )
tk.f_fps = float( vfps ); tk.f_fps = float( vfps );
msg_Dbg( p_input, " | | | + fps=%f", float( vfps ) ); msg_Dbg( p_input, " | | | + fps=%f", float( vfps ) );
} }
else else if( EbmlId( *el4 ) == KaxVideoDisplayUnit::ClassInfos.GlobalId )
{ {
msg_Dbg( p_input, "| | | | + Unknown (%s)", typeid(*el4).name() ); KaxVideoDisplayUnit &vdmode = *(KaxVideoDisplayUnit*)el4;
} vdmode.ReadData( p_sys->es->I_O() );
}
p_sys->ep->Up(); msg_Dbg( p_input, "| | | | + Track Video Display Unit=%s",
uint8( vdmode ) == 0 ? "pixels" : ( uint8( vdmode ) == 1 ? "centimeters": "inches" ) );
} }
else if( EbmlId( *el3 ) == KaxCodecID::ClassInfos.GlobalId ) else if( EbmlId( *el4 ) == KaxVideoAspectRatio::ClassInfos.GlobalId )
{ {
KaxCodecID &codecid = *(KaxCodecID*)el3; KaxVideoAspectRatio &ratio = *(KaxVideoAspectRatio*)el4;
codecid.ReadData( p_sys->es->I_O() ); ratio.ReadData( p_sys->es->I_O() );
tk.psz_codec = strdup( string( codecid ).c_str() ); msg_Dbg( p_input, " | | | + Track Video Aspect Ratio Type=%u", uint8( ratio ) );
msg_Dbg( p_input, "| | | + Track CodecId=%s", string( codecid ).c_str() );
} }
else if( EbmlId( *el3 ) == KaxCodecPrivate::ClassInfos.GlobalId ) else if( EbmlId( *el4 ) == KaxVideoGamma::ClassInfos.GlobalId )
{ {
KaxCodecPrivate &cpriv = *(KaxCodecPrivate*)el3; KaxVideoGamma &gamma = *(KaxVideoGamma*)el4;
cpriv.ReadData( p_sys->es->I_O() ); gamma.ReadData( p_sys->es->I_O() );
tk.i_extra_data = cpriv.GetSize(); msg_Dbg( p_input, " | | | + fps=%f", float( gamma ) );
if( tk.i_extra_data > 0 ) }
else
{ {
tk.p_extra_data = (uint8_t*)malloc( tk.i_extra_data ); msg_Dbg( p_input, "| | | | + Unknown (%s)", typeid(*el4).name() );
memcpy( tk.p_extra_data, cpriv.GetBuffer(), tk.i_extra_data );
} }
msg_Dbg( p_input, "| | | + Track CodecPrivate size=%lld", cpriv.GetSize() );
} }
else if( EbmlId( *el3 ) == KaxTrackFlagDefault::ClassInfos.GlobalId ) p_sys->ep->Up();
{
KaxTrackFlagDefault &fdef = *(KaxTrackFlagDefault*)el3;
fdef.ReadData( p_sys->es->I_O() );
tk.b_default = uint32( fdef );
msg_Dbg( p_input, "| | | + Track Default=%u", uint32( fdef ) );
} }
else if( EbmlId( *el3 ) == KaxTrackLanguage::ClassInfos.GlobalId ) else if( EbmlId( *el3 ) == KaxTrackAudio::ClassInfos.GlobalId )
{ {
KaxTrackLanguage &lang = *(KaxTrackLanguage*)el3; msg_Dbg( p_input, "| | | + Track Audio" );
tk.i_channels = 0;
tk.i_samplerate = 0;
tk.i_bitspersample = 0;
lang.ReadData( p_sys->es->I_O() ); p_sys->ep->Down();
tk.psz_language = strdup( string( lang ).c_str() ); while( ( el4 = p_sys->ep->Get() ) != NULL )
msg_Dbg( p_input, "| | | + Track Language=`%s'", string( lang ).c_str() );
}
else if( EbmlId( *el3 ) == KaxTrackFlagLacing::ClassInfos.GlobalId )
{ {
KaxTrackFlagLacing &lac = *(KaxTrackFlagLacing*)el3; if( EbmlId( *el4 ) == KaxAudioSamplingFreq::ClassInfos.GlobalId )
lac.ReadData( p_sys->es->I_O() ); {
KaxAudioSamplingFreq &afreq = *(KaxAudioSamplingFreq*)el4;
afreq.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track Lacing=%d", uint32( lac ) ); tk.i_samplerate = (int)float( afreq );
msg_Dbg( p_input, "| | | | + afreq=%d", tk.i_samplerate );
} }
else if( EbmlId( *el3 ) == KaxTrackMinCache::ClassInfos.GlobalId ) else if( EbmlId( *el4 ) == KaxAudioChannels::ClassInfos.GlobalId )
{ {
KaxTrackMinCache &cmin = *(KaxTrackMinCache*)el3; KaxAudioChannels &achan = *(KaxAudioChannels*)el4;
cmin.ReadData( p_sys->es->I_O() ); achan.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track MinCache=%d", uint32( cmin ) ); tk.i_channels = uint8( achan );
msg_Dbg( p_input, "| | | | + achan=%u", uint8( achan ) );
} }
else if( EbmlId( *el3 ) == KaxTrackMaxCache::ClassInfos.GlobalId ) else if( EbmlId( *el4 ) == KaxAudioBitDepth::ClassInfos.GlobalId )
{ {
KaxTrackMaxCache &cmax = *(KaxTrackMaxCache*)el3; KaxAudioBitDepth &abits = *(KaxAudioBitDepth*)el4;
cmax.ReadData( p_sys->es->I_O() ); abits.ReadData( p_sys->es->I_O() );
msg_Dbg( p_input, "| | | + Track MaxCache=%d", uint32( cmax ) ); tk.i_bitspersample = uint8( abits );
msg_Dbg( p_input, "| | | | + abits=%u", uint8( abits ) );
}
else
{
msg_Dbg( p_input, "| | | | + Unknown (%s)", typeid(*el4).name() );
}
}
p_sys->ep->Up();
} }
else else
{ {
...@@ -1289,7 +1414,7 @@ static int BlockGet( input_thread_t *p_input, KaxBlock **pp_block, int64_t *pi_r ...@@ -1289,7 +1414,7 @@ static int BlockGet( input_thread_t *p_input, KaxBlock **pp_block, int64_t *pi_r
/* add it to the index */ /* add it to the index */
if( p_sys->i_index == 0 || if( p_sys->i_index == 0 ||
( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < p_sys->cluster->GetElementPosition() ) ) ( p_sys->i_index > 0 && p_sys->index[p_sys->i_index - 1].i_position < (int64_t)p_sys->cluster->GetElementPosition() ) )
{ {
IndexAppendCluster( p_input, p_sys->cluster ); IndexAppendCluster( p_input, p_sys->cluster );
} }
...@@ -1547,7 +1672,7 @@ static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent) ...@@ -1547,7 +1672,7 @@ static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent)
{ {
int64_t i_pos = i_percent * p_input->stream.p_selected_area->i_size / 100; int64_t i_pos = i_percent * p_input->stream.p_selected_area->i_size / 100;
msg_Warn( p_input, "imprecise way of seeking" ); msg_Dbg( p_input, "imprecise way of seeking" );
for( i_index = 0; i_index < p_sys->i_index; i_index++ ) for( i_index = 0; i_index < p_sys->i_index; i_index++ )
{ {
if( p_sys->index[i_index].i_position >= i_pos) if( p_sys->index[i_index].i_position >= i_pos)
...@@ -1578,7 +1703,7 @@ static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent) ...@@ -1578,7 +1703,7 @@ static void Seek( input_thread_t *p_input, mtime_t i_date, int i_percent)
/* add it to the index */ /* add it to the index */
IndexAppendCluster( p_input, cluster ); IndexAppendCluster( p_input, cluster );
if( cluster->GetElementPosition() >= i_pos ) if( (int64_t)cluster->GetElementPosition() >= i_pos )
{ {
p_sys->cluster = cluster; p_sys->cluster = cluster;
p_sys->ep->Down(); p_sys->ep->Down();
...@@ -2289,6 +2414,27 @@ static void InformationsCreate( input_thread_t *p_input ) ...@@ -2289,6 +2414,27 @@ static void InformationsCreate( input_thread_t *p_input )
sprintf( psz_cat, "Stream %d", i_track ); sprintf( psz_cat, "Stream %d", i_track );
p_cat = input_InfoCategory( p_input, psz_cat); p_cat = input_InfoCategory( p_input, psz_cat);
if( tk.psz_name )
{
input_AddInfo( p_cat, _("Name"), "%s", tk.psz_name );
}
if( tk.psz_codec_name )
{
input_AddInfo( p_cat, _("Codec Name"), "%s", tk.psz_codec_name );
}
if( tk.psz_codec_settings )
{
input_AddInfo( p_cat, _("Codec Setting"), "%s", tk.psz_codec_settings );
}
if( tk.psz_codec_info_url )
{
input_AddInfo( p_cat, _("Codec Info"), "%s", tk.psz_codec_info_url );
}
if( tk.psz_codec_download_url )
{
input_AddInfo( p_cat, _("Codec Download"), "%s", tk.psz_codec_download_url );
}
switch( tk.i_cat ) switch( tk.i_cat )
{ {
case AUDIO_ES: case AUDIO_ES:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment