Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
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
Commits
6a74f9fb
Commit
6a74f9fb
authored
Dec 12, 2001
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Next Generation Buffer Manager, for PS plug-in.
parent
279f805a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
386 additions
and
438 deletions
+386
-438
include/config.h.in
include/config.h.in
+3
-0
include/input_ext-dec.h
include/input_ext-dec.h
+5
-1
include/input_ext-plugins.h
include/input_ext-plugins.h
+354
-1
plugins/mpeg_system/input_ps.c
plugins/mpeg_system/input_ps.c
+24
-436
No files found.
include/config.h.in
View file @
6a74f9fb
...
@@ -175,6 +175,9 @@
...
@@ -175,6 +175,9 @@
/* Maximum length of a hostname or source name */
/* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100
#define INPUT_MAX_SOURCE_LENGTH 100
/* Maximum memory the input is allowed to use (20 MB) */
#define INPUT_MAX_ALLOCATION 20971520
/* Default network protocol */
/* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
...
...
include/input_ext-dec.h
View file @
6a74f9fb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.4
2 2001/12/10 04:53:10 sam
Exp $
* $Id: input_ext-dec.h,v 1.4
3 2001/12/12 11:18:38 massiot
Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr>
...
@@ -44,6 +44,7 @@ typedef struct data_packet_s
...
@@ -44,6 +44,7 @@ typedef struct data_packet_s
{
{
/* Nothing before this line, the code relies on that */
/* Nothing before this line, the code relies on that */
byte_t
*
p_buffer
;
/* raw data packet */
byte_t
*
p_buffer
;
/* raw data packet */
byte_t
*
p_buffer_end
;
long
l_size
;
/* buffer size */
long
l_size
;
/* buffer size */
/* Decoders information */
/* Decoders information */
...
@@ -83,6 +84,9 @@ typedef struct pes_packet_s
...
@@ -83,6 +84,9 @@ typedef struct pes_packet_s
p_next fields of the data_packet_t struct) */
p_next fields of the data_packet_t struct) */
data_packet_t
*
p_first
;
/* The first packet contained by this
data_packet_t
*
p_first
;
/* The first packet contained by this
* PES (used by decoders). */
* PES (used by decoders). */
/* Chained list used by the input buffers manager */
struct
pes_packet_s
*
p_next
;
}
pes_packet_t
;
}
pes_packet_t
;
/*****************************************************************************
/*****************************************************************************
...
...
include/input_ext-plugins.h
View file @
6a74f9fb
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
* but exported to plug-ins
* but exported to plug-ins
*****************************************************************************
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: input_ext-plugins.h,v 1.
8 2001/12/10 04:53:10 sam
Exp $
* $Id: input_ext-plugins.h,v 1.
9 2001/12/12 11:18:38 massiot
Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
*
...
@@ -197,6 +197,359 @@ void input_NetlistDeletePES( void *,
...
@@ -197,6 +197,359 @@ void input_NetlistDeletePES( void *,
void
input_NetlistEnd
(
struct
input_thread_s
*
);
void
input_NetlistEnd
(
struct
input_thread_s
*
);
/*
* Optional Next Generation buffer manager
*
* Either buffers can only be used in one data packet (PS case), or buffers
* contain several data packets (DVD case). In the first case, buffers are
* embedded into data packets, otherwise they are allocated separately and
* shared with a refcount. --Meuuh
*/
/* Number of buffers for the calculation of the mean */
#define INPUT_BRESENHAM_NB 50
/* Flags */
#define BUFFERS_NOFLAGS 0
#define BUFFERS_SHARED 1
#define BUFFERS_UNIQUE_SIZE 2
/*****************************************************************************
* input_buffers_t: defines a LIFO per data type to keep
*****************************************************************************/
#define PACKETS_LIFO( TYPE, NAME ) \
struct \
{ \
TYPE * p_stack; \
unsigned int i_depth; \
} NAME;
#define BUFFERS_LIFO( TYPE, NAME ) \
struct \
{ \
TYPE * p_stack;
/* First item in the LIFO */
\
unsigned int i_depth;
/* Number of items in the LIFO */
\
unsigned int i_average_size;
/* Average size of the items (Bresenham) */
\
} NAME;
#define DECLARE_BUFFERS_EMBEDDED( FLAGS, NB_LIFO ) \
typedef struct input_buffers_s \
{ \
vlc_mutex_t lock; \
PACKETS_LIFO( pes_packet_t, pes ) \
BUFFERS_LIFO( data_packet_t, data[NB_LIFO] ) \
size_t i_allocated; \
} input_buffers_t;
#define DECLARE_BUFFERS_SHARED( FLAGS, NB_LIFO ) \
typedef struct data_buffer_s \
{ \
int i_refcount; \
int i_size; \
struct data_buffers_s * p_next; \
byte_t payload_start; \
} data_buffer_t; \
\
typedef struct input_buffers_s \
{ \
vlc_mutex_t lock; \
PACKETS_LIFO( pes_packet_t, pes ) \
PACKETS_LIFO( data_packet_t, data ) \
BUFFERS_LIFO( data_buffers_t, buffers[NB_LIFO] ) \
size_t i_allocated; \
} input_buffers_t;
/*****************************************************************************
* input_BuffersInit: initialize the cache structures, return a pointer to it
*****************************************************************************/
#define DECLARE_BUFFERS_INIT( FLAGS, NB_LIFO ) \
static void * input_BuffersInit( void ) \
{ \
input_buffers_t * p_buffers = malloc( sizeof( input_buffers_t ) ); \
\
if( p_buffers == NULL ) \
{ \
return( NULL ); \
} \
\
memset( p_buffers, 0, sizeof( input_buffers_t ) ); \
vlc_mutex_init( &p_buffers->lock ); \
\
return (void *)p_buffers; \
}
/*****************************************************************************
* input_BuffersEnd: free all cached structures
*****************************************************************************/
#define DECLARE_BUFFERS_END( FLAGS, NB_LIFO ) \
static void input_BuffersEnd( void * _p_buffers ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
\
if( _p_buffers != NULL ) \
{ \
pes_packet_t * p_pes = p_buffers->pes.p_stack; \
int i; \
\
if( p_main->b_stats ) \
{ \
int i; \
for( i = 0; i < NB_LIFO; i++ ) \
{ \
intf_StatMsg( \
"input buffers stats: data[%d]: %d bytes, %d packets", \
i, p_buffers->data[i].i_average_size, \
p_buffers->data[i].i_depth ); \
} \
} \
\
/* Free PES */
\
while( p_pes != NULL ) \
{ \
pes_packet_t * p_next = p_pes->p_next; \
free( p_pes ); \
p_pes = p_next; \
} \
\
for( i = 0; i < NB_LIFO; i++ ) \
{ \
data_packet_t * p_data = p_buffers->data[i].p_stack; \
\
/* Free data packets */
\
while( p_data != NULL ) \
{ \
data_packet_t * p_next = p_data->p_next; \
p_buffers->i_allocated -= p_data->p_buffer_end \
- p_data->p_buffer; \
free( p_data ); \
p_data = p_next; \
} \
} \
\
if( p_buffers->i_allocated ) \
{ \
intf_ErrMsg( "input buffers error: %d bytes have not been" \
" freed, expect memory leak", \
p_buffers->i_allocated ); \
} \
\
vlc_mutex_destroy( &p_buffers->lock ); \
free( _p_buffers ); \
} \
}
/*****************************************************************************
* input_NewPacket: return a pointer to a data packet of the appropriate size
*****************************************************************************/
#define DECLARE_BUFFERS_NEWPACKET( FLAGS, NB_LIFO ) \
static data_packet_t * input_NewPacket( void * _p_buffers, size_t i_size ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
int i_select; \
data_packet_t * p_data; \
\
/* Safety checks */
\
if( i_size > INPUT_MAX_PACKET_SIZE ) \
{ \
intf_ErrMsg( "Packet too big (%d)", i_size ); \
return NULL; \
} \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
if( p_buffers->i_allocated > INPUT_MAX_ALLOCATION ) \
{ \
vlc_mutex_unlock( &p_buffers->lock ); \
intf_ErrMsg( "INPUT_MAX_ALLOCATION reached (%d)", \
p_buffers->i_allocated ); \
return NULL; \
} \
\
for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
{ \
if( i_size <= (2 * p_buffers->data[i_select].i_average_size \
+ p_buffers->data[i_select + 1].i_average_size) / 3 ) \
{ \
break; \
} \
} \
\
if( p_buffers->data[i_select].p_stack != NULL ) \
{ \
/* Take the packet from the cache */
\
p_data = p_buffers->data[i_select].p_stack; \
p_buffers->data[i_select].p_stack = p_data->p_next; \
p_buffers->data[i_select].i_depth--; \
\
/* Reallocate the packet if it is too small or too large */
\
if( p_data->p_buffer_end - p_data->p_buffer < i_size || \
p_data->p_buffer_end - p_data->p_buffer > 3 * i_size ) \
{ \
p_buffers->i_allocated -= p_data->p_buffer_end \
- p_data->p_buffer; \
p_data = realloc( p_data, sizeof( data_packet_t ) + i_size ); \
if( p_data == NULL ) \
{ \
vlc_mutex_unlock( &p_buffers->lock ); \
intf_ErrMsg( "Out of memory" ); \
return NULL; \
} \
p_data->p_buffer = (byte_t *)p_data + sizeof( data_packet_t ); \
p_data->p_buffer_end = p_data->p_buffer + i_size; \
p_buffers->i_allocated += i_size; \
} \
} \
else \
{ \
/* Allocate a new packet */
\
p_data = malloc( sizeof( data_packet_t ) + i_size ); \
if( p_data == NULL ) \
{ \
vlc_mutex_unlock( &p_buffers->lock ); \
intf_ErrMsg( "Out of memory" ); \
return NULL; \
} \
p_data->p_buffer = (byte_t *)p_data + sizeof( data_packet_t ); \
p_data->p_buffer_end = p_data->p_buffer + i_size; \
p_buffers->i_allocated += i_size; \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
\
/* Initialize data */
\
p_data->p_next = NULL; \
p_data->b_discard_payload = 0; \
p_data->p_payload_start = p_data->p_buffer; \
p_data->p_payload_end = p_data->p_buffer + i_size; \
\
return( p_data ); \
}
/*****************************************************************************
* input_DeletePacket: put a packet back into the cache
*****************************************************************************/
#define DECLARE_BUFFERS_DELETEPACKET( FLAGS, NB_LIFO, DATA_CACHE_SIZE ) \
static __inline__ void _input_DeletePacket( void * _p_buffers, \
data_packet_t * p_data ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
int i_select, i_size; \
\
i_size = p_data->p_buffer_end - p_data->p_buffer; \
for( i_select = 0; i_select < NB_LIFO - 1; i_select++ ) \
{ \
if( i_size <= (2 * p_buffers->data[i_select].i_average_size \
+ p_buffers->data[i_select + 1].i_average_size) / 3 ) \
{ \
break; \
} \
} \
\
if( p_buffers->data[i_select].i_depth < DATA_CACHE_SIZE ) \
{ \
/* Cache not full : store the packet in it */
\
p_data->p_next = p_buffers->data[i_select].p_stack; \
p_buffers->data[i_select].p_stack = p_data; \
p_buffers->data[i_select].i_depth++; \
\
/* Update Bresenham mean (very approximative) */
\
p_buffers->data[i_select].i_average_size = ( i_size \
+ p_buffers->data[i_select].i_average_size \
* (INPUT_BRESENHAM_NB - 1) ) \
/ INPUT_BRESENHAM_NB; \
} \
else \
{ \
p_buffers->i_allocated -= p_data->p_buffer_end - p_data->p_buffer; \
free( p_data ); \
} \
} \
\
static void input_DeletePacket( void * _p_buffers, data_packet_t * p_data ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
\
vlc_mutex_lock( &p_buffers->lock ); \
_input_DeletePacket( _p_buffers, p_data ); \
vlc_mutex_unlock( &p_buffers->lock ); \
}
/*****************************************************************************
* input_NewPES: return a pointer to a new PES packet
*****************************************************************************/
#define DECLARE_BUFFERS_NEWPES( FLAGS, NB_LIFO ) \
static pes_packet_t * input_NewPES( void * _p_buffers ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
pes_packet_t * p_pes; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
if( p_buffers->pes.p_stack != NULL ) \
{ \
p_pes = p_buffers->pes.p_stack; \
p_buffers->pes.p_stack = p_pes->p_next; \
p_buffers->pes.i_depth--; \
} \
else \
{ \
p_pes = malloc( sizeof( pes_packet_t ) ); \
if( p_pes == NULL ) \
{ \
intf_ErrMsg( "Out of memory" ); \
vlc_mutex_unlock( &p_buffers->lock ); \
return( NULL ); \
} \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
\
/* Initialize data */
\
p_pes->p_next = NULL; \
p_pes->b_data_alignment = p_pes->b_discontinuity = \
p_pes->i_pts = p_pes->i_dts = 0; \
p_pes->i_pes_size = 0; \
p_pes->p_first = NULL; \
\
return( p_pes ); \
}
/*****************************************************************************
* input_DeletePES: put a pes and all data packets back into the cache
*****************************************************************************/
#define DECLARE_BUFFERS_DELETEPES( FLAGS, NB_LIFO, PES_CACHE_SIZE ) \
static void input_DeletePES( void * _p_buffers, pes_packet_t * p_pes ) \
{ \
input_buffers_t * p_buffers = (input_buffers_t *)_p_buffers; \
data_packet_t * p_data; \
\
vlc_mutex_lock( &p_buffers->lock ); \
\
p_data = p_pes->p_first; \
while( p_data != NULL ) \
{ \
data_packet_t * p_next = p_data->p_next; \
_input_DeletePacket( _p_buffers, p_data ); \
p_data = p_next; \
} \
\
if( p_buffers->pes.i_depth < PES_CACHE_SIZE ) \
{ \
/* Cache not full : store the packet in it */
\
p_pes->p_next = p_buffers->pes.p_stack; \
p_buffers->pes.p_stack = p_pes; \
p_buffers->pes.i_depth++; \
} \
else \
{ \
free( p_pes ); \
} \
\
vlc_mutex_unlock( &p_buffers->lock ); \
}
/*
/*
* Optional MPEG demultiplexing
* Optional MPEG demultiplexing
*/
*/
...
...
plugins/mpeg_system/input_ps.c
View file @
6a74f9fb
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* input_ps.c: PS demux and packet management
* input_ps.c: PS demux and packet management
*****************************************************************************
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ps.c,v 1.
2 2001/12/10 04:53:11 sam
Exp $
* $Id: input_ps.c,v 1.
3 2001/12/12 11:18:38 massiot
Exp $
*
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
* Cyril Deguet <asmax@via.ecp.fr>
...
@@ -91,10 +91,20 @@ static void PSInit ( struct input_thread_s * );
...
@@ -91,10 +91,20 @@ static void PSInit ( struct input_thread_s * );
static
void
PSEnd
(
struct
input_thread_s
*
);
static
void
PSEnd
(
struct
input_thread_s
*
);
static
int
PSSetProgram
(
struct
input_thread_s
*
,
pgrm_descriptor_t
*
);
static
int
PSSetProgram
(
struct
input_thread_s
*
,
pgrm_descriptor_t
*
);
static
void
PSSeek
(
struct
input_thread_s
*
,
off_t
);
static
void
PSSeek
(
struct
input_thread_s
*
,
off_t
);
static
struct
pes_packet_s
*
NewPES
(
void
*
);
static
struct
data_packet_s
*
NewPacket
(
void
*
,
size_t
);
/*****************************************************************************
static
void
DeletePacket
(
void
*
,
struct
data_packet_s
*
);
* Declare a buffer manager
static
void
DeletePES
(
void
*
,
struct
pes_packet_s
*
);
*****************************************************************************/
#define FLAGS BUFFERS_NOFLAGS
#define NB_LIFO 2
DECLARE_BUFFERS_EMBEDDED
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_INIT
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_END
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_NEWPACKET
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPACKET
(
FLAGS
,
NB_LIFO
,
150
);
DECLARE_BUFFERS_NEWPES
(
FLAGS
,
NB_LIFO
);
DECLARE_BUFFERS_DELETEPES
(
FLAGS
,
NB_LIFO
,
150
);
/*****************************************************************************
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
* Functions exported as capabilities. They are declared as static so that
...
@@ -113,10 +123,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
...
@@ -113,10 +123,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_program
=
PSSetProgram
;
input
.
pf_set_program
=
PSSetProgram
;
input
.
pf_read
=
PSRead
;
input
.
pf_read
=
PSRead
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
NewPacket
;
input
.
pf_new_packet
=
input_
NewPacket
;
input
.
pf_new_pes
=
NewPES
;
input
.
pf_new_pes
=
input_
NewPES
;
input
.
pf_delete_packet
=
DeletePacket
;
input
.
pf_delete_packet
=
input_
DeletePacket
;
input
.
pf_delete_pes
=
DeletePES
;
input
.
pf_delete_pes
=
input_
DeletePES
;
input
.
pf_rewind
=
NULL
;
input
.
pf_rewind
=
NULL
;
input
.
pf_seek
=
PSSeek
;
input
.
pf_seek
=
PSSeek
;
#undef input
#undef input
...
@@ -158,64 +168,11 @@ static int PSProbe( probedata_t *p_data )
...
@@ -158,64 +168,11 @@ static int PSProbe( probedata_t *p_data )
*****************************************************************************/
*****************************************************************************/
static
void
PSInit
(
input_thread_t
*
p_input
)
static
void
PSInit
(
input_thread_t
*
p_input
)
{
{
packet_cache_t
*
p_packet_cache
;
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
NULL
)
/* creates the packet cache structure */
p_packet_cache
=
malloc
(
sizeof
(
packet_cache_t
)
);
if
(
p_packet_cache
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_input
->
p_method_data
=
(
void
*
)
p_packet_cache
;
/* Initialize packet cache mutex */
vlc_mutex_init
(
&
p_packet_cache
->
lock
);
/* allocates the data cache */
p_packet_cache
->
data
.
p_stack
=
malloc
(
DATA_CACHE_SIZE
*
sizeof
(
data_packet_t
*
)
);
if
(
p_packet_cache
->
data
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
data
.
l_index
=
0
;
/* allocates the PES cache */
p_packet_cache
->
pes
.
p_stack
=
malloc
(
PES_CACHE_SIZE
*
sizeof
(
pes_packet_t
*
)
);
if
(
p_packet_cache
->
pes
.
p_stack
==
NULL
)
{
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
p_input
->
b_error
=
1
;
return
;
return
;
}
}
p_packet_cache
->
pes
.
l_index
=
0
;
/* allocates the small buffer cache */
p_packet_cache
->
smallbuffer
.
p_stack
=
malloc
(
SMALL_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
smallbuffer
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
smallbuffer
.
l_index
=
0
;
/* allocates the large buffer cache */
p_packet_cache
->
largebuffer
.
p_stack
=
malloc
(
LARGE_CACHE_SIZE
*
sizeof
(
packet_buffer_t
)
);
if
(
p_packet_cache
->
largebuffer
.
p_stack
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
p_input
->
b_error
=
1
;
return
;
}
p_packet_cache
->
largebuffer
.
l_index
=
0
;
if
(
p_input
->
p_stream
==
NULL
)
if
(
p_input
->
p_stream
==
NULL
)
{
{
...
@@ -275,7 +232,7 @@ static void PSInit( input_thread_t * p_input )
...
@@ -275,7 +232,7 @@ static void PSInit( input_thread_t * p_input )
{
{
/* FIXME: use i_p_config_t */
/* FIXME: use i_p_config_t */
input_ParsePS
(
p_input
,
pp_packets
[
i
]
);
input_ParsePS
(
p_input
,
pp_packets
[
i
]
);
DeleteP
acket
(
p_input
->
p_method_data
,
pp_packets
[
i
]
);
p_input
->
pf_delete_p
acket
(
p_input
->
p_method_data
,
pp_packets
[
i
]
);
}
}
/* File too big. */
/* File too big. */
...
@@ -388,22 +345,7 @@ static void PSInit( input_thread_t * p_input )
...
@@ -388,22 +345,7 @@ static void PSInit( input_thread_t * p_input )
*****************************************************************************/
*****************************************************************************/
static
void
PSEnd
(
input_thread_t
*
p_input
)
static
void
PSEnd
(
input_thread_t
*
p_input
)
{
{
#define p_packet_cache ((packet_cache_t *)p_input->p_method_data)
input_BuffersEnd
(
p_input
->
p_method_data
);
vlc_mutex_destroy
(
&
p_packet_cache
->
lock
);
if
(
p_packet_cache
->
data
.
p_stack
)
free
(
p_packet_cache
->
data
.
p_stack
);
if
(
p_packet_cache
->
pes
.
p_stack
)
free
(
p_packet_cache
->
pes
.
p_stack
);
if
(
p_packet_cache
->
smallbuffer
.
p_stack
)
free
(
p_packet_cache
->
smallbuffer
.
p_stack
);
if
(
p_packet_cache
->
largebuffer
.
p_stack
)
free
(
p_packet_cache
->
largebuffer
.
p_stack
);
#undef p_packet_cache
free
(
p_input
->
p_method_data
);
}
}
/*****************************************************************************
/*****************************************************************************
...
@@ -528,7 +470,8 @@ static int PSRead( input_thread_t * p_input,
...
@@ -528,7 +470,8 @@ static int PSRead( input_thread_t * p_input,
}
}
/* Fetch a packet of the appropriate size. */
/* Fetch a packet of the appropriate size. */
p_data
=
NewPacket
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
p_data
=
p_input
->
pf_new_packet
(
p_input
->
p_method_data
,
i_packet_size
+
6
);
if
(
p_data
==
NULL
)
if
(
p_data
==
NULL
)
{
{
intf_ErrMsg
(
"Out of memory"
);
intf_ErrMsg
(
"Out of memory"
);
...
@@ -598,358 +541,3 @@ static void PSSeek( input_thread_t * p_input, off_t i_position )
...
@@ -598,358 +541,3 @@ static void PSSeek( input_thread_t * p_input, off_t i_position )
p_input
->
stream
.
p_selected_area
->
i_tell
=
i_position
;
p_input
->
stream
.
p_selected_area
->
i_tell
=
i_position
;
}
}
/*
* Packet management utilities
*/
/*****************************************************************************
* NewPacket: allocates a data packet
*****************************************************************************/
static
struct
data_packet_s
*
NewPacket
(
void
*
p_packet_cache
,
size_t
l_size
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
long
l_index
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"PPacket cache not initialized"
);
return
NULL
;
}
#endif
/* Safety check */
if
(
l_size
>
INPUT_MAX_PACKET_SIZE
)
{
intf_ErrMsg
(
"Packet too big (%d)"
,
l_size
);
return
NULL
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is empty */
if
(
p_cache
->
data
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
=
malloc
(
sizeof
(
data_packet_t
)
);
if
(
p_data
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
if
(
(
p_data
=
p_cache
->
data
.
p_stack
[
--
p_cache
->
data
.
l_index
])
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
if
(
l_size
<
MAX_SMALL_SIZE
)
{
/* Small buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
smallbuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
smallbuffer
.
l_index
;
if
(
(
p_data
->
p_buffer
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
p_data
)
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
smallbuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
else
{
/* Large buffer */
/* Checks whether the buffer cache is empty */
if
(
p_cache
->
largebuffer
.
l_index
==
0
)
{
/* Allocates a new packet */
p_data
->
p_buffer
=
malloc
(
l_size
);
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"Out of memory"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer allocated"
);
#endif
p_data
->
l_size
=
l_size
;
}
else
{
/* Takes the packet out from the cache */
l_index
=
--
p_cache
->
largebuffer
.
l_index
;
p_data
->
p_buffer
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
p_data
;
if
(
p_data
->
p_buffer
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the small buffer cache"
);
free
(
p_data
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
/* Reallocates the packet if it is too small or too large */
if
(
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
<
l_size
||
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
>
2
*
l_size
)
{
p_data
->
p_buffer
=
realloc
(
p_data
->
p_buffer
,
l_size
);
p_data
->
l_size
=
l_size
;
}
else
{
p_data
->
l_size
=
p_cache
->
largebuffer
.
p_stack
[
l_index
].
l_size
;
}
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
/* Initialize data */
p_data
->
p_next
=
NULL
;
p_data
->
b_discard_payload
=
0
;
p_data
->
p_payload_start
=
p_data
->
p_buffer
;
p_data
->
p_payload_end
=
p_data
->
p_buffer
+
l_size
;
return
(
p_data
);
}
/*****************************************************************************
* NewPES: allocates a pes packet
*****************************************************************************/
static
pes_packet_t
*
NewPES
(
void
*
p_packet_cache
)
{
packet_cache_t
*
p_cache
;
pes_packet_t
*
p_pes
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
NULL
;
}
#endif
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is empty */
if
(
p_cache
->
pes
.
l_index
==
0
)
{
/* Allocates a new packet */
p_pes
=
malloc
(
sizeof
(
pes_packet_t
)
);
if
(
p_pes
==
NULL
)
{
intf_DbgMsg
(
"Out of memory"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet allocated"
);
#endif
}
else
{
/* Takes the packet out from the cache */
p_pes
=
p_cache
->
pes
.
p_stack
[
--
p_cache
->
pes
.
l_index
];
if
(
p_pes
==
NULL
)
{
intf_ErrMsg
(
"NULL packet in the data cache"
);
vlc_mutex_unlock
(
&
p_cache
->
lock
);
return
NULL
;
}
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
p_pes
->
b_data_alignment
=
p_pes
->
b_discontinuity
=
p_pes
->
i_pts
=
p_pes
->
i_dts
=
0
;
p_pes
->
i_pes_size
=
0
;
p_pes
->
p_first
=
NULL
;
return
(
p_pes
);
}
/*****************************************************************************
* DeletePacket: deletes a data packet
*****************************************************************************/
static
void
DeletePacket
(
void
*
p_packet_cache
,
data_packet_t
*
p_data
)
{
packet_cache_t
*
p_cache
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_data
);
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the data cache is full */
if
(
p_cache
->
data
.
l_index
<
DATA_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
data
.
p_stack
[
p_cache
->
data
.
l_index
++
]
=
p_data
;
/* Small buffer or large buffer? */
if
(
p_data
->
l_size
<
MAX_SMALL_SIZE
)
{
/* Checks whether the small buffer cache is full */
if
(
p_cache
->
smallbuffer
.
l_index
<
SMALL_CACHE_SIZE
)
{
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
smallbuffer
.
p_stack
[
p_cache
->
smallbuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: small buffer freed"
);
#endif
}
}
else
{
/* Checks whether the large buffer cache is full */
if
(
p_cache
->
largebuffer
.
l_index
<
LARGE_CACHE_SIZE
)
{
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
].
l_size
=
p_data
->
l_size
;
p_cache
->
largebuffer
.
p_stack
[
p_cache
->
largebuffer
.
l_index
++
].
p_data
=
p_data
->
p_buffer
;
}
else
{
ASSERT
(
p_data
->
p_buffer
);
free
(
p_data
->
p_buffer
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: large buffer freed"
);
#endif
}
}
}
else
{
/* Cache full: the packet must be freed */
free
(
p_data
->
p_buffer
);
free
(
p_data
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: data packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
/*****************************************************************************
* DeletePES: deletes a PES packet and associated data packets
*****************************************************************************/
static
void
DeletePES
(
void
*
p_packet_cache
,
pes_packet_t
*
p_pes
)
{
packet_cache_t
*
p_cache
;
data_packet_t
*
p_data
;
data_packet_t
*
p_next
;
p_cache
=
(
packet_cache_t
*
)
p_packet_cache
;
#ifdef DEBUG
if
(
p_cache
==
NULL
)
{
intf_ErrMsg
(
"Packet cache not initialized"
);
return
;
}
#endif
ASSERT
(
p_pes
);
p_data
=
p_pes
->
p_first
;
while
(
p_data
!=
NULL
)
{
p_next
=
p_data
->
p_next
;
DeletePacket
(
p_cache
,
p_data
);
p_data
=
p_next
;
}
vlc_mutex_lock
(
&
p_cache
->
lock
);
/* Checks whether the PES cache is full */
if
(
p_cache
->
pes
.
l_index
<
PES_CACHE_SIZE
)
{
/* Cache not full: store the packet in it */
p_cache
->
pes
.
p_stack
[
p_cache
->
pes
.
l_index
++
]
=
p_pes
;
}
else
{
/* Cache full: the packet must be freed */
free
(
p_pes
);
#ifdef TRACE_INPUT
intf_DbgMsg
(
"PS input: PES packet freed"
);
#endif
}
vlc_mutex_unlock
(
&
p_cache
->
lock
);
}
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