Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
4f7285b1
Commit
4f7285b1
authored
Mar 13, 2004
by
Gildas Bazin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/demux/ogg.c: Added Annodex support (www.annodex.net). Patch courtesy of Andre Pang.
parent
d537e26b
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
250 additions
and
73 deletions
+250
-73
modules/demux/ogg.c
modules/demux/ogg.c
+250
-73
No files found.
modules/demux/ogg.c
View file @
4f7285b1
...
...
@@ -2,9 +2,10 @@
* ogg.c : ogg stream demux module for vlc
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
* $Id
: ogg.c,v 1.58 2004/02/15 13:16:43 gbazin Exp
$
* $Id$
*
* Author: Gildas Bazin <gbazin@netcourrier.com>
* Authors: Gildas Bazin <gbazin@netcourrier.com>
* Andre Pang <Andre.Pang@csiro.au> (Annodex support)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -65,6 +66,9 @@ typedef struct logical_stream_s
int
b_reinit
;
int
i_theora_keyframe_granule_shift
;
/* for Annodex logical bitstreams */
int
secondary_header_packets
;
}
logical_stream_t
;
struct
demux_sys_t
...
...
@@ -146,6 +150,14 @@ static int Ogg_BeginningOfStream( input_thread_t *p_input, demux_sys_t *p_ogg);
static
int
Ogg_FindLogicalStreams
(
input_thread_t
*
p_input
,
demux_sys_t
*
p_ogg
);
static
void
Ogg_EndOfStream
(
input_thread_t
*
p_input
,
demux_sys_t
*
p_ogg
);
/* Logical bitstream headers */
static
void
Ogg_ReadTheoraHeader
(
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
);
static
void
Ogg_ReadVorbisHeader
(
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
);
static
void
Ogg_ReadAnnodexHeader
(
vlc_object_t
*
,
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
);
/*****************************************************************************
* Module descriptor
*****************************************************************************/
...
...
@@ -265,6 +277,19 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
return
;
}
if
(
p_oggpacket
->
bytes
>=
7
&&
!
strncmp
(
&
p_oggpacket
->
packet
[
0
],
"Annodex"
,
7
)
)
{
/* it's an Annodex packet -- skip it (do nothing) */
return
;
}
else
if
(
p_oggpacket
->
bytes
>=
7
&&
!
strncmp
(
&
p_oggpacket
->
packet
[
0
],
"AnxData"
,
7
)
)
{
/* it's an AnxData packet -- skip it (do nothing) */
return
;
}
if
(
p_stream
->
b_force_backup
)
{
ogg_packet
*
p_packet_backup
;
...
...
@@ -477,7 +502,8 @@ static void Ogg_DecodePacket( input_thread_t *p_input,
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
's'
,
'p'
,
'x'
,
' '
)
&&
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
'f'
,
'l'
,
'a'
,
'c'
)
&&
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
't'
,
'a'
,
'r'
,
'k'
)
&&
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
)
)
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
)
&&
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
'c'
,
'm'
,
'm'
,
'l'
)
)
{
/* We remove the header from the packet */
i_header_len
=
(
*
p_oggpacket
->
packet
&
PACKET_LEN_BITS01
)
>>
6
;
...
...
@@ -583,25 +609,8 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
if
(
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
1
],
"vorbis"
,
6
)
)
{
oggpack_buffer
opb
;
Ogg_ReadVorbisHeader
(
p_stream
,
&
oggpacket
);
msg_Dbg
(
p_input
,
"found vorbis header"
);
p_stream
->
fmt
.
i_cat
=
AUDIO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
);
/* Signal that we want to keep a backup of the vorbis
* stream headers. They will be used when switching between
* audio streams. */
p_stream
->
b_force_backup
=
1
;
/* Cheat and get additionnal info ;) */
oggpack_readinit
(
&
opb
,
oggpacket
.
packet
,
oggpacket
.
bytes
);
oggpack_adv
(
&
opb
,
88
);
p_stream
->
fmt
.
audio
.
i_channels
=
oggpack_read
(
&
opb
,
8
);
p_stream
->
f_rate
=
p_stream
->
fmt
.
audio
.
i_rate
=
oggpack_read
(
&
opb
,
32
);
oggpack_adv
(
&
opb
,
32
);
p_stream
->
fmt
.
i_bitrate
=
oggpack_read
(
&
opb
,
32
);
}
/* Check for Speex header */
else
if
(
oggpacket
.
bytes
>=
7
&&
...
...
@@ -652,62 +661,11 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
else
if
(
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
1
],
"theora"
,
6
)
)
{
bs_t
bitstream
;
int
i_fps_numerator
;
int
i_fps_denominator
;
int
i_keyframe_frequency_force
;
msg_Dbg
(
p_input
,
"found theora header"
);
p_stream
->
fmt
.
i_cat
=
VIDEO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
);
/* Signal that we want to keep a backup of the vorbis
* stream headers. They will be used when switching between
* audio streams. */
p_stream
->
b_force_backup
=
1
;
/* Cheat and get additionnal info ;) */
bs_init
(
&
bitstream
,
oggpacket
.
packet
,
oggpacket
.
bytes
);
bs_skip
(
&
bitstream
,
56
);
bs_read
(
&
bitstream
,
8
);
/* major version num */
bs_read
(
&
bitstream
,
8
);
/* minor version num */
bs_read
(
&
bitstream
,
8
);
/* subminor version num */
bs_read
(
&
bitstream
,
16
)
/*<< 4*/
;
/* width */
bs_read
(
&
bitstream
,
16
)
/*<< 4*/
;
/* height */
bs_read
(
&
bitstream
,
24
);
/* frame width */
bs_read
(
&
bitstream
,
24
);
/* frame height */
bs_read
(
&
bitstream
,
8
);
/* x offset */
bs_read
(
&
bitstream
,
8
);
/* y offset */
Ogg_ReadTheoraHeader
(
p_stream
,
&
oggpacket
);
i_fps_numerator
=
bs_read
(
&
bitstream
,
32
);
i_fps_denominator
=
bs_read
(
&
bitstream
,
32
);
bs_read
(
&
bitstream
,
24
);
/* aspect_numerator */
bs_read
(
&
bitstream
,
24
);
/* aspect_denominator */
i_keyframe_frequency_force
=
1
<<
bs_read
(
&
bitstream
,
5
);
bs_read
(
&
bitstream
,
8
);
/* colorspace */
p_stream
->
fmt
.
i_bitrate
=
bs_read
(
&
bitstream
,
24
);
bs_read
(
&
bitstream
,
6
);
/* quality */
/* granule_shift = i_log( frequency_force -1 ) */
p_stream
->
i_theora_keyframe_granule_shift
=
0
;
i_keyframe_frequency_force
--
;
while
(
i_keyframe_frequency_force
)
{
p_stream
->
i_theora_keyframe_granule_shift
++
;
i_keyframe_frequency_force
>>=
1
;
}
p_stream
->
f_rate
=
((
float
)
i_fps_numerator
)
/
i_fps_denominator
;
msg_Dbg
(
p_input
,
"found theora header, bitrate: %i, rate: %f"
,
p_stream
->
fmt
.
i_bitrate
,
p_stream
->
f_rate
);
/* Save this data in p_extra for ffmpeg */
p_stream
->
fmt
.
i_extra
=
oggpacket
.
bytes
;
p_stream
->
fmt
.
p_extra
=
malloc
(
oggpacket
.
bytes
);
memcpy
(
p_stream
->
fmt
.
p_extra
,
oggpacket
.
packet
,
oggpacket
.
bytes
);
}
/* Check for Tarkin header */
else
if
(
oggpacket
.
bytes
>=
7
&&
...
...
@@ -729,6 +687,23 @@ static int Ogg_FindLogicalStreams( input_thread_t *p_input, demux_sys_t *p_ogg)
"found tarkin header, bitrate: %i, rate: %f"
,
p_stream
->
fmt
.
i_bitrate
,
p_stream
->
f_rate
);
}
/* Check for Annodex header */
else
if
(
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
0
],
"Annodex"
,
7
)
)
{
Ogg_ReadAnnodexHeader
(
VLC_OBJECT
(
p_input
),
p_stream
,
&
oggpacket
);
/* kill annodex track */
free
(
p_stream
);
p_ogg
->
i_streams
--
;
}
/* Check for Annodex header */
else
if
(
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
0
],
"AnxData"
,
7
)
)
{
Ogg_ReadAnnodexHeader
(
VLC_OBJECT
(
p_input
),
p_stream
,
&
oggpacket
);
}
else
if
(
oggpacket
.
bytes
>=
142
&&
!
strncmp
(
&
oggpacket
.
packet
[
1
],
"Direct Show Samples embedded in Ogg"
,
35
))
...
...
@@ -1093,6 +1068,14 @@ static int Ogg_BeginningOfStream( input_thread_t *p_input, demux_sys_t *p_ogg)
if
(
p_stream
->
fmt
.
i_codec
!=
VLC_FOURCC
(
'f'
,
'l'
,
'a'
,
'c'
)
)
p_stream
->
p_es
=
es_out_Add
(
p_input
->
p_es_out
,
&
p_stream
->
fmt
);
if
(
p_stream
->
fmt
.
i_codec
==
VLC_FOURCC
(
'c'
,
'm'
,
'm'
,
'l'
)
)
{
/* Set the CMML stream active */
es_out_Control
(
p_input
->
p_es_out
,
ES_OUT_SET_ES
,
p_stream
->
p_es
);
}
vlc_mutex_lock
(
&
p_input
->
stream
.
stream_lock
);
p_input
->
stream
.
i_mux_rate
+=
(
p_stream
->
fmt
.
i_bitrate
/
(
8
*
50
));
vlc_mutex_unlock
(
&
p_input
->
stream
.
stream_lock
);
...
...
@@ -1229,6 +1212,31 @@ static int Demux( input_thread_t * p_input )
while
(
ogg_stream_packetout
(
&
p_stream
->
os
,
&
oggpacket
)
>
0
)
{
/* Read info from any secondary header packets, if there are any */
if
(
p_stream
->
secondary_header_packets
>
0
)
{
if
(
p_stream
->
fmt
.
i_codec
==
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
)
&&
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
1
],
"theora"
,
6
)
)
{
Ogg_ReadTheoraHeader
(
p_stream
,
&
oggpacket
);
p_stream
->
secondary_header_packets
=
0
;
}
else
if
(
p_stream
->
fmt
.
i_codec
==
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
)
&&
oggpacket
.
bytes
>=
7
&&
!
strncmp
(
&
oggpacket
.
packet
[
1
],
"vorbis"
,
6
)
)
{
Ogg_ReadVorbisHeader
(
p_stream
,
&
oggpacket
);
p_stream
->
secondary_header_packets
=
0
;
}
else
if
(
p_stream
->
fmt
.
i_codec
==
VLC_FOURCC
(
'c'
,
'm'
,
'm'
,
'l'
)
)
{
p_stream
->
secondary_header_packets
=
0
;
}
p_stream
->
secondary_header_packets
--
;
}
if
(
p_stream
->
b_reinit
)
{
/* If synchro is re-initialized we need to drop all the packets
...
...
@@ -1314,3 +1322,172 @@ static int Control( input_thread_t *p_input, int i_query, va_list args )
return
demux_vaControlDefault
(
p_input
,
i_query
,
args
);
}
}
static
void
Ogg_ReadTheoraHeader
(
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
)
{
bs_t
bitstream
;
int
i_fps_numerator
;
int
i_fps_denominator
;
int
i_keyframe_frequency_force
;
p_stream
->
fmt
.
i_cat
=
VIDEO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
);
/* Signal that we want to keep a backup of the vorbis
* stream headers. They will be used when switching between
* audio streams. */
p_stream
->
b_force_backup
=
1
;
/* Cheat and get additionnal info ;) */
bs_init
(
&
bitstream
,
p_oggpacket
->
packet
,
p_oggpacket
->
bytes
);
bs_skip
(
&
bitstream
,
56
);
bs_read
(
&
bitstream
,
8
);
/* major version num */
bs_read
(
&
bitstream
,
8
);
/* minor version num */
bs_read
(
&
bitstream
,
8
);
/* subminor version num */
bs_read
(
&
bitstream
,
16
)
/*<< 4*/
;
/* width */
bs_read
(
&
bitstream
,
16
)
/*<< 4*/
;
/* height */
bs_read
(
&
bitstream
,
24
);
/* frame width */
bs_read
(
&
bitstream
,
24
);
/* frame height */
bs_read
(
&
bitstream
,
8
);
/* x offset */
bs_read
(
&
bitstream
,
8
);
/* y offset */
i_fps_numerator
=
bs_read
(
&
bitstream
,
32
);
i_fps_denominator
=
bs_read
(
&
bitstream
,
32
);
bs_read
(
&
bitstream
,
24
);
/* aspect_numerator */
bs_read
(
&
bitstream
,
24
);
/* aspect_denominator */
i_keyframe_frequency_force
=
1
<<
bs_read
(
&
bitstream
,
5
);
bs_read
(
&
bitstream
,
8
);
/* colorspace */
p_stream
->
fmt
.
i_bitrate
=
bs_read
(
&
bitstream
,
24
);
bs_read
(
&
bitstream
,
6
);
/* quality */
/* granule_shift = i_log( frequency_force -1 ) */
p_stream
->
i_theora_keyframe_granule_shift
=
0
;
i_keyframe_frequency_force
--
;
while
(
i_keyframe_frequency_force
)
{
p_stream
->
i_theora_keyframe_granule_shift
++
;
i_keyframe_frequency_force
>>=
1
;
}
p_stream
->
f_rate
=
((
float
)
i_fps_numerator
)
/
i_fps_denominator
;
/* Save this data in p_extra for ffmpeg */
p_stream
->
fmt
.
i_extra
=
p_oggpacket
->
bytes
;
p_stream
->
fmt
.
p_extra
=
malloc
(
p_oggpacket
->
bytes
);
memcpy
(
p_stream
->
fmt
.
p_extra
,
p_oggpacket
->
packet
,
p_oggpacket
->
bytes
);
}
static
void
Ogg_ReadVorbisHeader
(
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
)
{
oggpack_buffer
opb
;
p_stream
->
fmt
.
i_cat
=
AUDIO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
);
/* Signal that we want to keep a backup of the vorbis
* stream headers. They will be used when switching between
* audio streams. */
p_stream
->
b_force_backup
=
1
;
/* Cheat and get additionnal info ;) */
oggpack_readinit
(
&
opb
,
p_oggpacket
->
packet
,
p_oggpacket
->
bytes
);
oggpack_adv
(
&
opb
,
88
);
p_stream
->
fmt
.
audio
.
i_channels
=
oggpack_read
(
&
opb
,
8
);
p_stream
->
f_rate
=
p_stream
->
fmt
.
audio
.
i_rate
=
oggpack_read
(
&
opb
,
32
);
oggpack_adv
(
&
opb
,
32
);
p_stream
->
fmt
.
i_bitrate
=
oggpack_read
(
&
opb
,
32
);
}
static
void
Ogg_ReadAnnodexHeader
(
vlc_object_t
*
p_this
,
logical_stream_t
*
p_stream
,
ogg_packet
*
p_oggpacket
)
{
if
(
!
strncmp
(
&
p_oggpacket
->
packet
[
0
],
"Annodex"
,
7
)
)
{
Ogg_ReadTheoraHeader
(
p_stream
,
p_oggpacket
);
oggpack_buffer
opb
;
uint16_t
major_version
;
uint16_t
minor_version
;
uint64_t
timebase_numerator
;
uint64_t
timebase_denominator
;
oggpack_readinit
(
&
opb
,
p_oggpacket
->
packet
,
p_oggpacket
->
bytes
);
oggpack_adv
(
&
opb
,
8
*
8
);
/* "Annodex\0" header */
major_version
=
oggpack_read
(
&
opb
,
2
*
8
);
/* major version */
minor_version
=
oggpack_read
(
&
opb
,
2
*
8
);
/* minor version */
timebase_numerator
=
GetQWLE
(
&
p_oggpacket
->
packet
[
16
]
);
timebase_denominator
=
GetQWLE
(
&
p_oggpacket
->
packet
[
24
]
);
}
else
if
(
!
strncmp
(
&
p_oggpacket
->
packet
[
0
],
"AnxData"
,
7
)
)
{
uint64_t
granule_rate_numerator
;
uint64_t
granule_rate_denominator
;
char
content_type_string
[
1024
];
/* Read in Annodex header fields */
granule_rate_numerator
=
GetQWLE
(
&
p_oggpacket
->
packet
[
8
]
);
granule_rate_denominator
=
GetQWLE
(
&
p_oggpacket
->
packet
[
16
]
);
p_stream
->
secondary_header_packets
=
GetDWLE
(
&
p_oggpacket
->
packet
[
24
]
);
msg_Dbg
(
p_this
,
"anxdata packet info: %qd/%qd, %d"
,
granule_rate_numerator
,
granule_rate_denominator
,
p_stream
->
secondary_header_packets
);
/* we are guaranteed that the first header field will be
* the content-type (by the Annodex standard) */
sscanf
(
&
p_oggpacket
->
packet
[
28
],
"Content-Type: %1024s
\r\n
"
,
content_type_string
);
p_stream
->
f_rate
=
(
float
)
granule_rate_numerator
/
(
float
)
granule_rate_denominator
;
/* What type of file do we have?
* strcmp is safe to use here because we've extracted
* content_type_string from the stream manually */
if
(
!
strncmp
(
content_type_string
,
"audio/x-wav"
,
11
)
)
{
/* n.b. WAVs are unsupported right now */
p_stream
->
fmt
.
i_cat
=
UNKNOWN_ES
;
}
else
if
(
!
strncmp
(
content_type_string
,
"audio/x-vorbis"
,
14
)
)
{
p_stream
->
fmt
.
i_cat
=
AUDIO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'v'
,
'o'
,
'r'
,
'b'
);
p_stream
->
b_force_backup
=
1
;
}
else
if
(
!
strncmp
(
content_type_string
,
"video/x-theora"
,
14
)
)
{
p_stream
->
fmt
.
i_cat
=
VIDEO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
't'
,
'h'
,
'e'
,
'o'
);
p_stream
->
b_force_backup
=
1
;
}
else
if
(
!
strncmp
(
content_type_string
,
"video/x-xvid"
,
14
)
)
{
p_stream
->
fmt
.
i_cat
=
VIDEO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'x'
,
'v'
,
'i'
,
'd'
);
p_stream
->
b_force_backup
=
1
;
}
else
if
(
!
strncmp
(
content_type_string
,
"video/mpeg"
,
14
)
)
{
/* n.b. MPEG streams are unsupported right now */
p_stream
->
fmt
.
i_cat
=
VIDEO_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'm'
,
'p'
,
'g'
,
'v'
);
}
else
if
(
!
strncmp
(
content_type_string
,
"text/x-cmml"
,
11
)
)
{
ogg_stream_packetout
(
&
p_stream
->
os
,
p_oggpacket
);
p_stream
->
fmt
.
i_cat
=
SPU_ES
;
p_stream
->
fmt
.
i_codec
=
VLC_FOURCC
(
'c'
,
'm'
,
'm'
,
'l'
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment