Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
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-2-2
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
Hide 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 @@
/* Maximum length of a hostname or source name */
#define INPUT_MAX_SOURCE_LENGTH 100
/* Maximum memory the input is allowed to use (20 MB) */
#define INPUT_MAX_ALLOCATION 20971520
/* Default network protocol */
#define INPUT_NETWORK_PROTOCOL_VAR "vlc_network_protocol"
#define INPUT_NETWORK_PROTOCOL_DEFAULT "ts"
...
...
include/input_ext-dec.h
View file @
6a74f9fb
...
...
@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders
*****************************************************************************
* 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>
* Michel Kaempf <maxx@via.ecp.fr>
...
...
@@ -44,6 +44,7 @@ typedef struct data_packet_s
{
/* Nothing before this line, the code relies on that */
byte_t
*
p_buffer
;
/* raw data packet */
byte_t
*
p_buffer_end
;
long
l_size
;
/* buffer size */
/* Decoders information */
...
...
@@ -83,6 +84,9 @@ typedef struct pes_packet_s
p_next fields of the data_packet_t struct) */
data_packet_t
*
p_first
;
/* The first packet contained by this
* PES (used by decoders). */
/* Chained list used by the input buffers manager */
struct
pes_packet_s
*
p_next
;
}
pes_packet_t
;
/*****************************************************************************
...
...
include/input_ext-plugins.h
View file @
6a74f9fb
...
...
@@ -3,7 +3,7 @@
* but exported to plug-ins
*****************************************************************************
* 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>
*
...
...
@@ -197,6 +197,359 @@ void input_NetlistDeletePES( void *,
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
*/
...
...
plugins/mpeg_system/input_ps.c
View file @
6a74f9fb
...
...
@@ -2,7 +2,7 @@
* input_ps.c: PS demux and packet management
*****************************************************************************
* 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>
* Cyril Deguet <asmax@via.ecp.fr>
...
...
@@ -91,10 +91,20 @@ static void PSInit ( struct input_thread_s * );
static
void
PSEnd
(
struct
input_thread_s
*
);
static
int
PSSetProgram
(
struct
input_thread_s
*
,
pgrm_descriptor_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
*
);
static
void
DeletePES
(
void
*
,
struct
pes_packet_s
*
);
/*****************************************************************************
* Declare a buffer manager
*****************************************************************************/
#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
...
...
@@ -113,10 +123,10 @@ void _M( input_getfunctions )( function_list_t * p_function_list )
input
.
pf_set_program
=
PSSetProgram
;
input
.
pf_read
=
PSRead
;
input
.
pf_demux
=
input_DemuxPS
;
input
.
pf_new_packet
=
NewPacket
;
input
.
pf_new_pes
=
NewPES
;
input
.
pf_delete_packet
=
DeletePacket
;
input
.
pf_delete_pes
=
DeletePES
;
input
.
pf_new_packet
=
input_
NewPacket
;
input
.
pf_new_pes
=
input_
NewPES
;
input
.
pf_delete_packet
=
input_
DeletePacket
;
input
.
pf_delete_pes
=
input_
DeletePES
;
input
.
pf_rewind
=
NULL
;
input
.
pf_seek
=
PSSeek
;
#undef input
...
...
@@ -158,65 +168,12 @@ static int PSProbe( probedata_t *p_data )
*****************************************************************************/
static
void
PSInit
(
input_thread_t
*
p_input
)
{
packet_cache_t
*
p_packet_cache
;
/* creates the packet cache structure */
p_packet_cache
=
malloc
(
sizeof
(
packet_cache_t
)
);
if
(
p_packet_cache
==
NULL
)
if
(
(
p_input
->
p_method_data
=
input_BuffersInit
())
==
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
;
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
)
{
/* Re-open the socket as a buffered FILE stream */
...
...
@@ -275,7 +232,7 @@ static void PSInit( input_thread_t * p_input )
{
/* FIXME: use i_p_config_t */
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. */
...
...
@@ -388,22 +345,7 @@ static void PSInit( 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)
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
);
input_BuffersEnd
(
p_input
->
p_method_data
);
}
/*****************************************************************************
...
...
@@ -528,7 +470,8 @@ static int PSRead( input_thread_t * p_input,
}
/* 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
)
{
intf_ErrMsg
(
"Out of memory"
);
...
...
@@ -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
;
}
/*
* 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