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
4d50b304
Commit
4d50b304
authored
Nov 24, 2003
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* input_ext-dec.c: useless file.
parent
f2dbf8ee
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
0 additions
and
509 deletions
+0
-509
src/input/input_ext-dec.c
src/input/input_ext-dec.c
+0
-509
No files found.
src/input/input_ext-dec.c
deleted
100644 → 0
View file @
f2dbf8ee
/*****************************************************************************
* input_ext-dec.c: services to the decoders
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: input_ext-dec.c,v 1.46 2003/08/17 20:39:08 fenrir Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <string.h>
/* memcpy(), memset() */
#include <vlc/vlc.h>
#include "stream_control.h"
#include "input_ext-dec.h"
#include "input_ext-intf.h"
#include "input_ext-plugins.h"
/****************************************************************************
* input_ExtractPES
*****************************************************************************
* Extract a PES from the fifo. If pp_pes is NULL then the PES is just
* deleted, otherwise *pp_pes will point to this PES.
****************************************************************************/
void
input_ExtractPES
(
decoder_fifo_t
*
p_fifo
,
pes_packet_t
**
pp_pes
)
{
pes_packet_t
*
p_pes
;
vlc_mutex_lock
(
&
p_fifo
->
data_lock
);
if
(
p_fifo
->
p_first
==
NULL
)
{
if
(
p_fifo
->
b_die
)
{
vlc_mutex_unlock
(
&
p_fifo
->
data_lock
);
if
(
pp_pes
)
*
pp_pes
=
NULL
;
return
;
}
/* Signal the input thread we're waiting. This is only
* needed in case of slave clock (ES plug-in) but it won't
* harm. */
vlc_cond_signal
(
&
p_fifo
->
data_wait
);
/* Wait for the input to tell us when we received a packet. */
vlc_cond_wait
(
&
p_fifo
->
data_wait
,
&
p_fifo
->
data_lock
);
}
p_pes
=
p_fifo
->
p_first
;
p_fifo
->
p_first
=
p_pes
->
p_next
;
p_pes
->
p_next
=
NULL
;
p_fifo
->
i_depth
--
;
if
(
!
p_fifo
->
p_first
)
{
/* No PES in the FIFO. p_last is no longer valid. */
p_fifo
->
pp_last
=
&
p_fifo
->
p_first
;
}
vlc_mutex_unlock
(
&
p_fifo
->
data_lock
);
if
(
pp_pes
)
*
pp_pes
=
p_pes
;
else
input_DeletePES
(
p_fifo
->
p_packets_mgt
,
p_pes
);
}
/*****************************************************************************
* InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
* on success.
*****************************************************************************/
int
InitBitstream
(
bit_stream_t
*
p_bit_stream
,
decoder_fifo_t
*
p_fifo
,
void
(
*
pf_bitstream_callback
)(
bit_stream_t
*
,
vlc_bool_t
),
void
*
p_callback_arg
)
{
/* Get the first pes packet */
input_ExtractPES
(
p_fifo
,
&
p_bit_stream
->
p_pes
);
if
(
!
p_bit_stream
->
p_pes
)
return
VLC_EGENERIC
;
p_bit_stream
->
p_decoder_fifo
=
p_fifo
;
p_bit_stream
->
pf_bitstream_callback
=
pf_bitstream_callback
;
p_bit_stream
->
p_callback_arg
=
p_callback_arg
;
p_bit_stream
->
p_data
=
p_bit_stream
->
p_pes
->
p_first
;
p_bit_stream
->
p_byte
=
p_bit_stream
->
p_data
->
p_payload_start
;
p_bit_stream
->
p_end
=
p_bit_stream
->
p_data
->
p_payload_end
;
p_bit_stream
->
fifo
.
buffer
=
0
;
p_bit_stream
->
fifo
.
i_available
=
0
;
p_bit_stream
->
i_pts
=
p_bit_stream
->
p_pes
->
i_pts
;
p_bit_stream
->
i_dts
=
p_bit_stream
->
p_pes
->
i_dts
;
p_bit_stream
->
p_pts_validity
=
p_bit_stream
->
p_byte
;
/* Call back the decoder. */
if
(
p_bit_stream
->
pf_bitstream_callback
!=
NULL
)
{
p_bit_stream
->
pf_bitstream_callback
(
p_bit_stream
,
1
);
}
if
(
p_bit_stream
->
p_byte
<=
p_bit_stream
->
p_end
-
sizeof
(
WORD_TYPE
)
)
{
/* Get aligned on a word boundary.
* NB : we _will_ get aligned, because we have at most
* sizeof(WORD_TYPE) - 1 bytes to store, and at least
* sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
AlignWord
(
p_bit_stream
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* CloseBitstream: free the bitstream structure.
*****************************************************************************/
void
CloseBitstream
(
bit_stream_t
*
p_bit_stream
)
{
if
(
p_bit_stream
->
p_pes
)
input_DeletePES
(
p_bit_stream
->
p_decoder_fifo
->
p_packets_mgt
,
p_bit_stream
->
p_pes
);
}
/*****************************************************************************
* DecoderError : an error occured, use this function to empty the fifo
*****************************************************************************/
void
DecoderError
(
decoder_fifo_t
*
p_fifo
)
{
/* No need to take the lock, because input_ExtractPES already takes it
* and also check for p_fifo->b_die */
/* Wait until a `die' order is sent */
while
(
!
p_fifo
->
b_die
)
{
/* Trash all received PES packets */
input_ExtractPES
(
p_fifo
,
NULL
);
}
}
/*****************************************************************************
* NextDataPacket: go to the data packet after *pp_data, return 1 if we
* changed PES. This function can fail in case of end of stream, you can
* check p_bit_stream->p_data or p_bit_stream->p_pes to know wether we did get
* the next data packet.
*****************************************************************************/
static
inline
vlc_bool_t
_NextDataPacket
(
decoder_fifo_t
*
p_fifo
,
bit_stream_t
*
p_bit_stream
)
{
vlc_bool_t
b_new_pes
;
/* We are looking for the next data packet that contains real data,
* and not just a PES header */
do
{
/* Sanity check. Yes, this can happen if the caller doesn't check
* for p_fifo->b_die beforehand. */
if
(
p_bit_stream
->
p_pes
==
NULL
)
return
0
;
/* We were reading the last data packet of this PES packet... It's
* time to jump to the next PES packet */
if
(
p_bit_stream
->
p_data
->
p_next
==
NULL
)
{
/* The next packet could be found in the next PES packet */
input_DeletePES
(
p_fifo
->
p_packets_mgt
,
p_bit_stream
->
p_pes
);
input_ExtractPES
(
p_fifo
,
&
p_bit_stream
->
p_pes
);
if
(
!
p_bit_stream
->
p_pes
)
{
/* Couldn't get the next PES, might be an eos */
p_bit_stream
->
p_data
=
NULL
;
return
0
;
}
p_bit_stream
->
p_data
=
p_bit_stream
->
p_pes
->
p_first
;
b_new_pes
=
1
;
}
else
{
/* Perhaps the next data packet of the current PES packet contains
* real data (ie its payload's size is greater than 0). */
p_bit_stream
->
p_data
=
p_bit_stream
->
p_data
->
p_next
;
b_new_pes
=
0
;
}
}
while
(
p_bit_stream
->
p_data
->
p_payload_start
==
p_bit_stream
->
p_data
->
p_payload_end
);
return
(
b_new_pes
);
}
vlc_bool_t
NextDataPacket
(
decoder_fifo_t
*
p_fifo
,
bit_stream_t
*
p_bit_stream
)
{
return
(
_NextDataPacket
(
p_fifo
,
p_bit_stream
)
);
}
/*****************************************************************************
* BitstreamNextDataPacket: go to the next data packet, and update bitstream
* context. This function can fail in case of eos!
*****************************************************************************/
static
inline
void
_BitstreamNextDataPacket
(
bit_stream_t
*
p_bit_stream
)
{
decoder_fifo_t
*
p_fifo
=
p_bit_stream
->
p_decoder_fifo
;
vlc_bool_t
b_new_pes
;
b_new_pes
=
_NextDataPacket
(
p_fifo
,
p_bit_stream
);
if
(
!
p_bit_stream
->
p_pes
)
return
;
/* We've found a data packet which contains interesting data... */
p_bit_stream
->
p_byte
=
p_bit_stream
->
p_data
->
p_payload_start
;
p_bit_stream
->
p_end
=
p_bit_stream
->
p_data
->
p_payload_end
;
/* Call back the decoder. */
if
(
p_bit_stream
->
pf_bitstream_callback
!=
NULL
)
{
p_bit_stream
->
pf_bitstream_callback
(
p_bit_stream
,
b_new_pes
);
}
/* Discontinuity management. */
if
(
p_bit_stream
->
p_data
->
b_discard_payload
)
{
p_bit_stream
->
i_pts
=
p_bit_stream
->
i_dts
=
0
;
}
/* Retrieve the PTS. */
if
(
b_new_pes
&&
p_bit_stream
->
p_pes
->
i_pts
)
{
p_bit_stream
->
i_pts
=
p_bit_stream
->
p_pes
->
i_pts
;
p_bit_stream
->
i_dts
=
p_bit_stream
->
p_pes
->
i_dts
;
p_bit_stream
->
p_pts_validity
=
p_bit_stream
->
p_byte
;
}
}
void
BitstreamNextDataPacket
(
bit_stream_t
*
p_bit_stream
)
{
_BitstreamNextDataPacket
(
p_bit_stream
);
}
/*****************************************************************************
* UnalignedShowBits : places i_bits bits into the bit buffer, even when
* not aligned on a word boundary
*****************************************************************************/
uint32_t
UnalignedShowBits
(
bit_stream_t
*
p_bit_stream
,
unsigned
int
i_bits
)
{
/* We just fill in the bit buffer. */
while
(
(
unsigned
int
)
p_bit_stream
->
fifo
.
i_available
<
i_bits
)
{
if
(
p_bit_stream
->
p_byte
<
p_bit_stream
->
p_end
)
{
p_bit_stream
->
fifo
.
buffer
|=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
8
*
sizeof
(
WORD_TYPE
)
-
8
-
p_bit_stream
->
fifo
.
i_available
);
p_bit_stream
->
fifo
.
i_available
+=
8
;
}
else
{
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
0
;
if
(
(
ptrdiff_t
)
p_bit_stream
->
p_byte
&
(
sizeof
(
WORD_TYPE
)
-
1
)
)
{
/* We are not aligned anymore. */
if
(
((
ptrdiff_t
)
p_bit_stream
->
p_byte
&
(
sizeof
(
WORD_TYPE
)
-
1
))
*
8
<
(
unsigned
int
)
p_bit_stream
->
fifo
.
i_available
)
{
/* We are not aligned, and won't be. Copy the first word
* of the packet in a temporary buffer, and we'll see
* later. */
int
i
;
/* sizeof(WORD_TYPE) - number of bytes to trash
* from the last payload */
int
j
;
p_bit_stream
->
i_showbits_buffer
=
0
;
for
(
j
=
i
=
0
;
i
<
(
int
)
sizeof
(
WORD_TYPE
)
;
i
++
)
{
if
(
p_bit_stream
->
p_byte
>=
p_bit_stream
->
p_end
)
{
j
=
i
;
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
0
;
}
((
byte_t
*
)
&
p_bit_stream
->
i_showbits_buffer
)[
i
]
=
*
p_bit_stream
->
p_byte
;
p_bit_stream
->
p_byte
++
;
}
/* This is kind of kludgy. */
p_bit_stream
->
p_data
->
p_payload_start
+=
sizeof
(
WORD_TYPE
)
-
j
;
p_bit_stream
->
p_byte
=
(
byte_t
*
)
&
p_bit_stream
->
i_showbits_buffer
;
p_bit_stream
->
p_end
=
(
byte_t
*
)
&
p_bit_stream
->
i_showbits_buffer
+
sizeof
(
WORD_TYPE
);
p_bit_stream
->
showbits_data
.
p_next
=
p_bit_stream
->
p_data
;
p_bit_stream
->
p_data
=
&
p_bit_stream
->
showbits_data
;
}
else
{
/* We are not aligned, but we can be. */
AlignWord
(
p_bit_stream
);
}
}
/* We have 32 bits ready for reading, it will be enough. */
break
;
}
}
/* It shouldn't loop :-)) */
return
(
ShowBits
(
p_bit_stream
,
i_bits
)
);
}
/*****************************************************************************
* UnalignedGetBits : returns i_bits bits from the bit stream and removes
* them from the buffer, even when the bit stream is not aligned on a word
* boundary
*****************************************************************************/
uint32_t
UnalignedGetBits
(
bit_stream_t
*
p_bit_stream
,
unsigned
int
i_bits
)
{
uint32_t
i_result
;
i_result
=
p_bit_stream
->
fifo
.
buffer
>>
(
8
*
sizeof
(
WORD_TYPE
)
-
i_bits
);
i_bits
=
-
p_bit_stream
->
fifo
.
i_available
;
/* Gather missing bytes. */
while
(
i_bits
>=
8
)
{
if
(
p_bit_stream
->
p_byte
<
p_bit_stream
->
p_end
)
{
i_result
|=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
i_bits
-
8
);
i_bits
-=
8
;
}
else
{
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
0
;
i_result
|=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
i_bits
-
8
);
i_bits
-=
8
;
}
}
/* Gather missing bits. */
if
(
i_bits
>
0
)
{
unsigned
int
i_tmp
=
8
-
i_bits
;
if
(
p_bit_stream
->
p_byte
<
p_bit_stream
->
p_end
)
{
i_result
|=
*
p_bit_stream
->
p_byte
>>
i_tmp
;
p_bit_stream
->
fifo
.
buffer
=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
sizeof
(
WORD_TYPE
)
*
8
-
i_tmp
);
p_bit_stream
->
fifo
.
i_available
=
i_tmp
;
}
else
{
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
0
;
i_result
|=
*
p_bit_stream
->
p_byte
>>
i_tmp
;
p_bit_stream
->
fifo
.
buffer
=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
sizeof
(
WORD_TYPE
)
*
8
-
i_tmp
);
p_bit_stream
->
fifo
.
i_available
=
i_tmp
;
}
}
else
{
p_bit_stream
->
fifo
.
i_available
=
0
;
p_bit_stream
->
fifo
.
buffer
=
0
;
}
if
(
p_bit_stream
->
p_byte
<=
p_bit_stream
->
p_end
-
sizeof
(
WORD_TYPE
)
)
{
/* Get aligned on a word boundary. Otherwise it is safer
* to do it the next time.
* NB : we _will_ get aligned, because we have at most
* sizeof(WORD_TYPE) - 1 bytes to store, and at least
* sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
AlignWord
(
p_bit_stream
);
}
return
(
i_result
);
}
/*****************************************************************************
* UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
* buffer, even when the bit stream is not aligned on a word boundary
*****************************************************************************/
void
UnalignedRemoveBits
(
bit_stream_t
*
p_bit_stream
)
{
/* First remove all unnecessary bytes. */
while
(
p_bit_stream
->
fifo
.
i_available
<=
-
8
)
{
if
(
p_bit_stream
->
p_byte
<
p_bit_stream
->
p_end
)
{
p_bit_stream
->
p_byte
++
;
p_bit_stream
->
fifo
.
i_available
+=
8
;
}
else
{
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
;
p_bit_stream
->
p_byte
++
;
p_bit_stream
->
fifo
.
i_available
+=
8
;
}
}
/* Remove unnecessary bits. */
if
(
p_bit_stream
->
fifo
.
i_available
<
0
)
{
if
(
p_bit_stream
->
p_byte
<
p_bit_stream
->
p_end
)
{
p_bit_stream
->
fifo
.
buffer
=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
sizeof
(
WORD_TYPE
)
*
8
-
8
-
p_bit_stream
->
fifo
.
i_available
);
p_bit_stream
->
fifo
.
i_available
+=
8
;
}
else
{
_BitstreamNextDataPacket
(
p_bit_stream
);
if
(
p_bit_stream
->
p_decoder_fifo
->
b_die
)
return
;
p_bit_stream
->
fifo
.
buffer
=
*
(
p_bit_stream
->
p_byte
++
)
<<
(
sizeof
(
WORD_TYPE
)
*
8
-
8
-
p_bit_stream
->
fifo
.
i_available
);
p_bit_stream
->
fifo
.
i_available
+=
8
;
}
}
else
{
p_bit_stream
->
fifo
.
buffer
=
0
;
}
if
(
p_bit_stream
->
p_byte
<=
p_bit_stream
->
p_end
-
sizeof
(
WORD_TYPE
)
)
{
/* Get aligned on a word boundary. Otherwise it is safer
* to do it the next time.
* NB : we _will_ get aligned, because we have at most
* sizeof(WORD_TYPE) - 1 bytes to store, and at least
* sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
AlignWord
(
p_bit_stream
);
}
}
/*****************************************************************************
* CurrentPTS: returns the current PTS and DTS
*****************************************************************************/
void
CurrentPTS
(
bit_stream_t
*
p_bit_stream
,
mtime_t
*
pi_pts
,
mtime_t
*
pi_dts
)
{
/* Check if the current PTS is already valid (ie. if the first byte
* of the packet has already been used in the decoder). */
ptrdiff_t
p_diff
=
p_bit_stream
->
p_pts_validity
-
p_bit_stream
->
p_byte
;
if
(
p_diff
<
0
||
p_diff
>
4
/* We are far away so it is valid */
||
(
p_diff
*
8
)
>=
p_bit_stream
->
fifo
.
i_available
/* We have buffered less bytes than actually read */
)
{
*
pi_pts
=
p_bit_stream
->
i_pts
;
if
(
pi_dts
!=
NULL
)
*
pi_dts
=
p_bit_stream
->
i_dts
;
p_bit_stream
->
i_pts
=
0
;
p_bit_stream
->
i_dts
=
0
;
}
else
{
*
pi_pts
=
0
;
if
(
pi_dts
!=
NULL
)
*
pi_dts
=
0
;
}
}
/*****************************************************************************
* NextPTS: returns the PTS and DTS for the next starting byte
*****************************************************************************/
void
NextPTS
(
bit_stream_t
*
p_bit_stream
,
mtime_t
*
pi_pts
,
mtime_t
*
pi_dts
)
{
/* Check if the current PTS is already valid (ie. if the first byte
* of the packet has already been used in the decoder). */
ptrdiff_t
p_diff
=
p_bit_stream
->
p_pts_validity
-
p_bit_stream
->
p_byte
-
1
;
if
(
p_diff
<
0
||
p_diff
>
4
/* We are far away so it is valid */
||
(
p_diff
*
8
)
>=
p_bit_stream
->
fifo
.
i_available
/* We have buffered less bytes than actually read */
)
{
*
pi_pts
=
p_bit_stream
->
i_pts
;
if
(
pi_dts
!=
NULL
)
*
pi_dts
=
p_bit_stream
->
i_dts
;
p_bit_stream
->
i_pts
=
0
;
p_bit_stream
->
i_dts
=
0
;
}
else
{
*
pi_pts
=
0
;
if
(
pi_dts
!=
NULL
)
*
pi_dts
=
0
;
}
}
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