Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Steve Lhomme
VLC
Commits
3b94a56f
Commit
3b94a56f
authored
Apr 20, 2001
by
Renaud Dartus
Browse files
* Begin of the new ac3_decoder ;)
- New ac3_decoder_thread (we now use GetBits) Please warn me if you encounter some problem
parent
39db76ab
Changes
13
Hide whitespace changes
Inline
Side-by-side
src/ac3_decoder/ac3_bit_allocate.c
View file @
3b94a56f
...
...
@@ -2,7 +2,7 @@
* ac3_bit_allocate.c: ac3 allocation tables
*****************************************************************************
* Copyright (C) 2000 VideoLAN
* $Id: ac3_bit_allocate.c,v 1.1
7
2001/04/
06 09:15:47 sam
Exp $
* $Id: ac3_bit_allocate.c,v 1.1
8
2001/04/
20 12:14:34 reno
Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca>
...
...
@@ -24,9 +24,16 @@
*****************************************************************************/
#include
"defs.h"
#include
<string.h>
/* memcpy(), memset() */
#include
"config.h"
#include
"common.h"
#include
"threads.h"
#include
"mtime.h"
#include
"intf_msg.h"
/* intf_DbgMsg(), intf_ErrMsg() */
#include
"stream_control.h"
#include
"input_ext-dec.h"
#include
"int_types.h"
#include
"ac3_decoder.h"
#include
"ac3_internal.h"
...
...
src/ac3_decoder/ac3_bit_stream.h
deleted
100644 → 0
View file @
39db76ab
/*****************************************************************************
* ac3_bit_stream.h: getbits functions for the ac3 decoder
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: ac3_bit_stream.h,v 1.9 2001/03/21 13:42:34 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
* Renaud Dartus <reno@videolan.org>
*
*
* 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.
*****************************************************************************/
static
__inline__
u32
bitstream_get
(
ac3_bit_stream_t
*
p_bit_stream
,
u32
num_bits
)
{
u32
result
=
0
;
while
(
p_bit_stream
->
i_available
<
num_bits
)
{
if
(
p_bit_stream
->
byte_stream
.
p_byte
>=
p_bit_stream
->
byte_stream
.
p_end
)
{
ac3dec_thread_t
*
p_ac3dec
=
p_bit_stream
->
byte_stream
.
info
;
/* no, switch to next buffer */
if
(
!
p_ac3dec
->
p_fifo
->
b_die
)
ac3_byte_stream_next
(
&
p_bit_stream
->
byte_stream
);
}
p_bit_stream
->
buffer
|=
((
u32
)
*
(
p_bit_stream
->
byte_stream
.
p_byte
++
))
<<
(
24
-
p_bit_stream
->
i_available
);
p_bit_stream
->
i_available
+=
8
;
}
result
=
p_bit_stream
->
buffer
>>
(
32
-
num_bits
);
p_bit_stream
->
buffer
<<=
num_bits
;
p_bit_stream
->
i_available
-=
num_bits
;
p_bit_stream
->
total_bits_read
+=
num_bits
;
return
result
;
}
src/ac3_decoder/ac3_decoder.c
View file @
3b94a56f
...
...
@@ -2,7 +2,7 @@
* ac3_decoder.c: core ac3 decoder
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.c,v 1.2
8
2001/0
3
/2
1
1
3:42:34 sam
Exp $
* $Id: ac3_decoder.c,v 1.2
9
2001/0
4
/2
0
1
2:14:34 reno
Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
...
...
@@ -25,8 +25,21 @@
#include
"defs.h"
#include
"int_types.h"
#include
"config.h"
#include
"common.h"
#include
"threads.h"
#include
"mtime.h"
#include
"intf_msg.h"
/* intf_DbgMsg(), intf_ErrMsg() */
#include
"stream_control.h"
#include
"input_ext-dec.h"
#include
"audio_output.h"
#include
"ac3_decoder.h"
#include
"ac3_decoder_thread.h"
#include
"ac3_internal.h"
#include
<stdio.h>
...
...
@@ -35,8 +48,8 @@ void imdct_init (imdct_t * p_imdct);
int
ac3_init
(
ac3dec_t
*
p_ac3dec
)
{
//
p_ac3dec->bit_stream.buffer = 0;
//
p_ac3dec->bit_stream.i_available = 0;
//
p_ac3dec->bit_stream.buffer = 0;
//
p_ac3dec->bit_stream.i_available = 0;
p_ac3dec
->
mantissa
.
lfsr_state
=
1
;
/* dither_gen initialization */
imdct_init
(
&
p_ac3dec
->
imdct
);
...
...
@@ -46,21 +59,50 @@ int ac3_init (ac3dec_t * p_ac3dec)
int
ac3_decode_frame
(
ac3dec_t
*
p_ac3dec
,
s16
*
buffer
)
{
int
i
;
ac3dec_thread_t
*
p_ac3dec_t
=
(
ac3dec_thread_t
*
)
p_ac3dec
->
bit_stream
.
p_callback_arg
;
if
(
parse_bsi
(
p_ac3dec
))
{
intf_WarnMsg
(
1
,
"Error during ac3parsing"
);
parse_auxdata
(
p_ac3dec
);
return
1
;
}
for
(
i
=
0
;
i
<
6
;
i
++
)
{
if
((
p_ac3dec_t
->
p_fifo
->
b_die
)
&&
(
p_ac3dec_t
->
p_fifo
->
b_error
))
{
return
1
;
}
if
(
parse_audblk
(
p_ac3dec
,
i
))
{
intf_WarnMsg
(
1
,
"Error during ac3audioblock"
);
parse_auxdata
(
p_ac3dec
);
return
1
;
}
if
((
p_ac3dec_t
->
p_fifo
->
b_die
)
&&
(
p_ac3dec_t
->
p_fifo
->
b_error
))
{
return
1
;
}
if
(
exponent_unpack
(
p_ac3dec
))
{
intf_WarnMsg
(
1
,
"Error during ac3unpack"
);
parse_auxdata
(
p_ac3dec
);
return
1
;
}
bit_allocate
(
p_ac3dec
);
mantissa_unpack
(
p_ac3dec
);
if
((
p_ac3dec_t
->
p_fifo
->
b_die
)
&&
(
p_ac3dec_t
->
p_fifo
->
b_error
))
{
return
1
;
}
if
(
p_ac3dec
->
bsi
.
acmod
==
0x2
)
rematrix
(
p_ac3dec
);
imdct
(
p_ac3dec
,
buffer
);
// downmix (p_ac3dec, buffer);
buffer
+=
2
*
256
;
}
...
...
src/ac3_decoder/ac3_decoder.h
View file @
3b94a56f
...
...
@@ -2,7 +2,7 @@
* ac3_decoder.h : ac3 decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.h,v 1.
4
2001/0
3
/2
1
1
3:42:34 sam
Exp $
* $Id: ac3_decoder.h,v 1.
5
2001/0
4
/2
0
1
2:14:34 reno
Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org>
...
...
@@ -32,22 +32,12 @@ typedef struct ac3_sync_info_s {
int
bit_rate
;
/* nominal bit rate in kbps */
}
ac3_sync_info_t
;
typedef
struct
ac3_byte_stream_s
{
u8
*
p_byte
;
u8
*
p_end
;
void
*
info
;
}
ac3_byte_stream_t
;
/**** ac3 decoder API - functions publically provided by the ac3 decoder ****/
int
ac3_init
(
ac3dec_t
*
p_ac3dec
);
int
ac3_sync_frame
(
ac3dec_t
*
p_ac3dec
,
ac3_sync_info_t
*
p_sync_info
);
int
ac3_decode_frame
(
ac3dec_t
*
p_ac3dec
,
s16
*
buffer
);
static
ac3_byte_stream_t
*
ac3_byte_stream
(
ac3dec_t
*
p_ac3dec
);
/**** ac3 decoder API - user functions to be provided to the ac3 decoder ****/
void
ac3_byte_stream_next
(
ac3_byte_stream_t
*
p_byte_stream
);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
...
...
@@ -347,15 +337,6 @@ typedef struct stream_samples_s
float
channel
[
6
][
256
];
}
stream_samples_t
;
typedef
struct
ac3_bit_stream_s
{
u32
buffer
;
int
i_available
;
ac3_byte_stream_t
byte_stream
;
unsigned
int
total_bits_read
;
/* temporary */
}
ac3_bit_stream_t
;
typedef
struct
bit_allocate_s
{
s16
psd
[
256
];
...
...
@@ -420,8 +401,10 @@ struct ac3dec_s
*/
/* The bit stream structure handles the PES stream at the bit level */
ac3_bit_stream_t
bit_stream
;
bit_stream_t
bit_stream
;
int
i_available
;
unsigned
int
total_bits_read
;
/* temporary */
/*
* Decoder properties
*/
...
...
@@ -436,10 +419,3 @@ struct ac3dec_s
mantissa_t
mantissa
;
imdct_t
imdct
;
};
/**** ac3 decoder inline functions ****/
static
ac3_byte_stream_t
*
ac3_byte_stream
(
ac3dec_t
*
p_ac3dec
)
{
return
&
(
p_ac3dec
->
bit_stream
.
byte_stream
);
}
src/ac3_decoder/ac3_decoder_thread.c
View file @
3b94a56f
...
...
@@ -2,7 +2,7 @@
* ac3_decoder_thread.c: ac3 decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.c,v 1.2
7
2001/04/
06 09:15:47 sam
Exp $
* $Id: ac3_decoder_thread.c,v 1.2
8
2001/04/
20 12:14:34 reno
Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
...
...
@@ -38,7 +38,6 @@
#include
<unistd.h>
/* getpid() */
#include
<stdio.h>
/* "intf_msg.h" */
#include
<string.h>
/* memcpy(), memset() */
#include
<stdlib.h>
/* malloc(), free() */
#include
"config.h"
...
...
@@ -65,49 +64,53 @@ static int InitThread (ac3dec_thread_t * p_adec);
static
void
RunThread
(
ac3dec_thread_t
*
p_adec
);
static
void
ErrorThread
(
ac3dec_thread_t
*
p_adec
);
static
void
EndThread
(
ac3dec_thread_t
*
p_adec
);
static
void
BitstreamCallback
(
bit_stream_t
*
p_bit_stream
,
boolean_t
b_new_pes
);
/*****************************************************************************
* ac3dec_CreateThread: creates an ac3 decoder thread
*****************************************************************************/
vlc_thread_t
ac3dec_CreateThread
(
adec_config_t
*
p_config
)
{
ac3dec_thread_t
*
p_ac3dec
;
ac3dec_thread_t
*
p_ac3dec
_t
;
intf_DbgMsg
(
"ac3dec debug: creating ac3 decoder thread"
);
/* Allocate the memory needed to store the thread's structure */
if
((
p_ac3dec
=
(
ac3dec_thread_t
*
)
malloc
(
sizeof
(
ac3dec_thread_t
)))
==
NULL
)
if
((
p_ac3dec
_t
=
(
ac3dec_thread_t
*
)
malloc
(
sizeof
(
ac3dec_thread_t
)))
==
NULL
)
{
intf_ErrMsg
(
"ac3dec error: not enough memory "
"for ac3dec_CreateThread() to create the new thread"
);
return
0
;
}
/*
* Initialize the thread properties
*/
p_ac3dec
->
p_config
=
p_config
;
p_ac3dec
->
p_fifo
=
p_config
->
decoder_config
.
p_decoder_fifo
;
p_ac3dec
_t
->
p_config
=
p_config
;
p_ac3dec
_t
->
p_fifo
=
p_config
->
decoder_config
.
p_decoder_fifo
;
/* Initialize the ac3 decoder structures */
ac3_init
(
&
p_ac3dec
->
ac3_decoder
);
ac3_init
(
&
p_ac3dec
_t
->
ac3_decoder
);
/*
* Initialize the output properties
*/
p_ac3dec
->
p_aout
=
p_config
->
p_aout
;
p_ac3dec
->
p_aout_fifo
=
NULL
;
p_ac3dec
_t
->
p_aout
=
p_config
->
p_aout
;
p_ac3dec
_t
->
p_aout_fifo
=
NULL
;
/* Spawn the ac3 decoder thread */
if
(
vlc_thread_create
(
&
p_ac3dec
->
thread_id
,
"ac3 decoder"
,
(
vlc_thread_func_t
)
RunThread
,
(
void
*
)
p_ac3dec
))
if
(
vlc_thread_create
(
&
p_ac3dec_t
->
thread_id
,
"ac3 decoder"
,
(
vlc_thread_func_t
)
RunThread
,
(
void
*
)
p_ac3dec_t
))
{
intf_ErrMsg
(
"ac3dec error: can't spawn ac3 decoder thread"
);
free
(
p_ac3dec
);
free
(
p_ac3dec
_t
);
return
0
;
}
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread (%p) created"
,
p_ac3dec
);
return
p_ac3dec
->
thread_id
;
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread (%p) created"
,
p_ac3dec
_t
);
return
p_ac3dec
_t
->
thread_id
;
}
/* Following functions are local */
...
...
@@ -115,31 +118,19 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
/*****************************************************************************
* InitThread : initialize an ac3 decoder thread
*****************************************************************************/
static
int
InitThread
(
ac3dec_thread_t
*
p_ac3dec
)
static
int
InitThread
(
ac3dec_thread_t
*
p_ac3dec
_t
)
{
aout_fifo_t
aout_fifo
;
ac3_byte_stream_t
*
byte_stream
;
intf_DbgMsg
(
"ac3dec debug: initializing ac3 decoder thread %p"
,
p_ac3dec
);
intf_DbgMsg
(
"ac3dec debug: initializing ac3 decoder thread %p"
,
p_ac3dec
_t
);
/* Get the first data packet. */
vlc_mutex_lock
(
&
p_ac3dec
->
p_fifo
->
data_lock
);
while
(
DECODER_FIFO_ISEMPTY
(
*
p_ac3dec
->
p_fifo
)
)
{
if
(
p_ac3dec
->
p_fifo
->
b_die
)
{
vlc_mutex_unlock
(
&
p_ac3dec
->
p_fifo
->
data_lock
);
return
-
1
;
}
vlc_cond_wait
(
&
p_ac3dec
->
p_fifo
->
data_wait
,
&
p_ac3dec
->
p_fifo
->
data_lock
);
}
p_ac3dec
->
p_data
=
DECODER_FIFO_START
(
*
p_ac3dec
->
p_fifo
)
->
p_first
;
byte_stream
=
ac3_byte_stream
(
&
p_ac3dec
->
ac3_decoder
);
byte_stream
->
p_byte
=
p_ac3dec
->
p_data
->
p_payload_start
;
byte_stream
->
p_end
=
p_ac3dec
->
p_data
->
p_payload_end
;
byte_stream
->
info
=
p_ac3dec
;
vlc_mutex_unlock
(
&
p_ac3dec
->
p_fifo
->
data_lock
);
p_ac3dec_t
->
p_config
->
decoder_config
.
pf_init_bit_stream
(
&
p_ac3dec_t
->
ac3_decoder
.
bit_stream
,
p_ac3dec_t
->
p_config
->
decoder_config
.
p_decoder_fifo
);
p_ac3dec_t
->
ac3_decoder
.
bit_stream
.
pf_bitstream_callback
=
BitstreamCallback
;
p_ac3dec_t
->
ac3_decoder
.
bit_stream
.
p_callback_arg
=
(
void
*
)
p_ac3dec_t
;
aout_fifo
.
i_type
=
AOUT_ADEC_STEREO_FIFO
;
aout_fifo
.
i_channels
=
2
;
aout_fifo
.
b_stereo
=
1
;
...
...
@@ -147,247 +138,178 @@ static int InitThread (ac3dec_thread_t * p_ac3dec)
aout_fifo
.
l_frame_size
=
AC3DEC_FRAME_SIZE
;
/* Creating the audio output fifo */
if
((
p_ac3dec
->
p_aout_fifo
=
aout_CreateFifo
(
p_ac3dec
->
p_aout
,
&
aout_fifo
))
==
NULL
)
if
((
p_ac3dec
_t
->
p_aout_fifo
=
aout_CreateFifo
(
p_ac3dec
_t
->
p_aout
,
&
aout_fifo
))
==
NULL
)
{
return
-
1
;
}
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread %p initialized"
,
p_ac3dec
);
/* InitBitstream has normally begun to read a PES packet, get its
* PTS/DTS */
if
(
!
p_ac3dec_t
->
p_fifo
->
b_die
)
{
BitstreamCallback
(
&
p_ac3dec_t
->
ac3_decoder
.
bit_stream
,
1
);
}
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread %p initialized"
,
p_ac3dec_t
);
return
0
;
}
/*****************************************************************************
* RunThread : ac3 decoder thread
*****************************************************************************/
static
void
RunThread
(
ac3dec_thread_t
*
p_ac3dec
)
static
void
RunThread
(
ac3dec_thread_t
*
p_ac3dec
_t
)
{
int
sync
;
intf_DbgMsg
(
"ac3dec debug: running ac3 decoder thread (%p) (pid == %i)"
,
p_ac3dec
,
getpid
());
intf_DbgMsg
(
"ac3dec debug: running ac3 decoder thread (%p) (pid == %i)"
,
p_ac3dec
_t
,
getpid
());
/* Initializing the ac3 decoder thread */
if
(
InitThread
(
p_ac3dec
))
/* XXX?? */
if
(
InitThread
(
p_ac3dec
_t
))
/* XXX?? */
{
p_ac3dec
->
p_fifo
->
b_error
=
1
;
p_ac3dec
_t
->
p_fifo
->
b_error
=
1
;
}
sync
=
0
;
p_ac3dec
->
sync_ptr
=
0
;
p_ac3dec
_t
->
sync_ptr
=
0
;
/* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */
while
((
!
p_ac3dec
->
p_fifo
->
b_die
)
&&
(
!
p_ac3dec
->
p_fifo
->
b_error
))
while
((
!
p_ac3dec
_t
->
p_fifo
->
b_die
)
&&
(
!
p_ac3dec
_t
->
p_fifo
->
b_error
))
{
s16
*
buffer
;
ac3_sync_info_t
sync_info
;
if
(
!
sync
)
{
/* have to find a synchro point */
int
ptr
;
ac3_byte_stream_t
*
p_byte_stream
;
intf_DbgMsg
(
"ac3dec: sync"
);
p_byte_stream
=
ac3_byte_stream
(
&
p_ac3dec
->
ac3_decoder
);
/* first read till next ac3 magic header */
do
{
ac3_byte_stream_next
(
p_byte_stream
);
}
while
((
!
p_ac3dec
->
sync_ptr
)
&&
(
!
p_ac3dec
->
p_fifo
->
b_die
)
&&
(
!
p_ac3dec
->
p_fifo
->
b_error
));
/* skip the specified number of bytes */
if
(
p_ac3dec
->
p_fifo
->
b_die
||
p_ac3dec
->
p_fifo
->
b_error
)
{
goto
bad_frame
;
}
ptr
=
p_ac3dec
->
sync_ptr
;
while
(
--
ptr
&&
(
!
p_ac3dec
->
p_fifo
->
b_die
)
&&
(
!
p_ac3dec
->
p_fifo
->
b_error
))
{
if
(
p_byte_stream
->
p_byte
>=
p_byte_stream
->
p_end
)
{
ac3_byte_stream_next
(
p_byte_stream
);
}
p_byte_stream
->
p_byte
++
;
}
if
(
p_ac3dec
->
p_fifo
->
b_die
||
p_ac3dec
->
p_fifo
->
b_error
)
{
goto
bad_frame
;
}
if
(
!
sync
)
{
do
{
GetBits
(
&
p_ac3dec_t
->
ac3_decoder
.
bit_stream
,
8
);
}
while
((
!
p_ac3dec_t
->
sync_ptr
)
&&
(
!
p_ac3dec_t
->
p_fifo
->
b_die
)
&&
(
!
p_ac3dec_t
->
p_fifo
->
b_error
));
/* we are in sync now */
sync
=
1
;
p_ac3dec
->
sync_ptr
=
0
;
}
if
(
DECODER_FIFO_START
(
*
p_ac3dec
->
p_fifo
)
->
i_pts
)
{
p_ac3dec
->
p_aout_fifo
->
date
[
p_ac3dec
->
p_aout_fifo
->
l_end_frame
]
=
DECODER_FIFO_START
(
*
p_ac3dec
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_ac3dec
->
p_fifo
)
->
i_pts
=
0
;
}
else
if
(
DECODER_FIFO_START
(
*
p_ac3dec_t
->
p_fifo
)
->
i_pts
)
{
p_ac3dec
->
p_aout_fifo
->
date
[
p_ac3dec
->
p_aout_fifo
->
l_end_frame
]
=
LAST_MDATE
;
p_ac3dec_t
->
p_aout_fifo
->
date
[
p_ac3dec_t
->
p_aout_fifo
->
l_end_frame
]
=
DECODER_FIFO_START
(
*
p_ac3dec_t
->
p_fifo
)
->
i_pts
;
DECODER_FIFO_START
(
*
p_ac3dec_t
->
p_fifo
)
->
i_pts
=
0
;
}
else
{
p_ac3dec_t
->
p_aout_fifo
->
date
[
p_ac3dec_t
->
p_aout_fifo
->
l_end_frame
]
=
LAST_MDATE
;
}
if
(
ac3_sync_frame
(
&
p_ac3dec
->
ac3_decoder
,
&
sync_info
))
if
(
ac3_sync_frame
(
&
p_ac3dec
_t
->
ac3_decoder
,
&
sync_info
))
{
sync
=
0
;
goto
bad_frame
;
}
p_ac3dec
->
p_aout_fifo
->
l_rate
=
sync_info
.
sample_rate
;
p_ac3dec
_t
->
p_aout_fifo
->
l_rate
=
sync_info
.
sample_rate
;
buffer
=
((
s16
*
)
p_ac3dec
->
p_aout_fifo
->
buffer
)
+
(
p_ac3dec
->
p_aout_fifo
->
l_end_frame
*
AC3DEC_FRAME_SIZE
);
buffer
=
((
s16
*
)
p_ac3dec_t
->
p_aout_fifo
->
buffer
)
+
(
p_ac3dec_t
->
p_aout_fifo
->
l_end_frame
*
AC3DEC_FRAME_SIZE
);
if
(
ac3_decode_frame
(
&
p_ac3dec
->
ac3_decoder
,
buffer
))
if
(
ac3_decode_frame
(
&
p_ac3dec
_t
->
ac3_decoder
,
buffer
))
{
sync
=
0
;
goto
bad_frame
;
}
vlc_mutex_lock
(
&
p_ac3dec
->
p_aout_fifo
->
data_lock
);
p_ac3dec
->
p_aout_fifo
->
l_end_frame
=
(
p_ac3dec
->
p_aout_fifo
->
l_end_frame
+
1
)
&
AOUT_FIFO_SIZE
;
vlc_cond_signal
(
&
p_ac3dec
->
p_aout_fifo
->
data_wait
);
vlc_mutex_unlock
(
&
p_ac3dec
->
p_aout_fifo
->
data_lock
);
bad_frame:
continue
;
vlc_mutex_lock
(
&
p_ac3dec_t
->
p_aout_fifo
->
data_lock
);
p_ac3dec_t
->
p_aout_fifo
->
l_end_frame
=
(
p_ac3dec_t
->
p_aout_fifo
->
l_end_frame
+
1
)
&
AOUT_FIFO_SIZE
;
vlc_cond_signal
(
&
p_ac3dec_t
->
p_aout_fifo
->
data_wait
);
vlc_mutex_unlock
(
&
p_ac3dec_t
->
p_aout_fifo
->
data_lock
);
bad_frame:
RealignBits
(
&
p_ac3dec_t
->
ac3_decoder
.
bit_stream
);
}
/* If b_error is set, the ac3 decoder thread enters the error loop */
if
(
p_ac3dec
->
p_fifo
->
b_error
)
if
(
p_ac3dec
_t
->
p_fifo
->
b_error
)
{
ErrorThread
(
p_ac3dec
);
ErrorThread
(
p_ac3dec
_t
);
}
/* End of the ac3 decoder thread */
EndThread
(
p_ac3dec
);
EndThread
(
p_ac3dec
_t
);
}
/*****************************************************************************
* ErrorThread : ac3 decoder's RunThread() error loop
*****************************************************************************/
static
void
ErrorThread
(
ac3dec_thread_t
*
p_ac3dec
)
static
void
ErrorThread
(
ac3dec_thread_t
*
p_ac3dec
_t
)
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
vlc_mutex_lock
(
&
p_ac3dec
->
p_fifo
->
data_lock
);
vlc_mutex_lock
(
&
p_ac3dec
_t
->
p_fifo
->
data_lock
);
/* Wait until a `die' order is sent */
while
(
!
p_ac3dec
->
p_fifo
->
b_die
)
while
(
!
p_ac3dec
_t
->
p_fifo
->
b_die
)
{
/* Trash all received PES packets */
while
(
!
DECODER_FIFO_ISEMPTY
(
*
p_ac3dec
->
p_fifo
))
while
(
!
DECODER_FIFO_ISEMPTY
(
*
p_ac3dec
_t
->
p_fifo
))
{
p_ac3dec
->
p_fifo
->
pf_delete_pes
(
p_ac3dec
->
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_ac3dec
->
p_fifo
));
DECODER_FIFO_INCSTART
(
*
p_ac3dec
->
p_fifo
);
p_ac3dec
_t
->
p_fifo
->
pf_delete_pes
(
p_ac3dec
_t
->
p_fifo
->
p_packets_mgt
,
DECODER_FIFO_START
(
*
p_ac3dec
_t
->
p_fifo
));
DECODER_FIFO_INCSTART
(
*
p_ac3dec
_t
->
p_fifo
);
}
/* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait
(
&
p_ac3dec
->
p_fifo
->
data_wait
,
&
p_ac3dec
->
p_fifo
->
data_lock
);
vlc_cond_wait
(
&
p_ac3dec
_t
->
p_fifo
->
data_wait
,
&
p_ac3dec
_t
->
p_fifo
->
data_lock
);
}
/* We can release the lock before leaving */
vlc_mutex_unlock
(
&
p_ac3dec
->
p_fifo
->
data_lock
);
vlc_mutex_unlock
(
&
p_ac3dec
_t
->
p_fifo
->
data_lock
);
}
/*****************************************************************************
* EndThread : ac3 decoder thread destruction
*****************************************************************************/
static
void
EndThread
(
ac3dec_thread_t
*
p_ac3dec
)
static
void
EndThread
(
ac3dec_thread_t
*
p_ac3dec
_t
)
{
intf_DbgMsg
(
"ac3dec debug: destroying ac3 decoder thread %p"
,
p_ac3dec
);
intf_DbgMsg
(
"ac3dec debug: destroying ac3 decoder thread %p"
,
p_ac3dec
_t
);
/* If the audio output fifo was created, we destroy it */
if
(
p_ac3dec
->
p_aout_fifo
!=
NULL
)
if
(
p_ac3dec
_t
->
p_aout_fifo
!=
NULL
)
{
aout_DestroyFifo
(
p_ac3dec
->
p_aout_fifo
);
aout_DestroyFifo
(
p_ac3dec
_t
->
p_aout_fifo
);
/* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock
(
&
(
p_ac3dec
->
p_aout_fifo
->
data_lock
));
vlc_cond_signal
(
&
(
p_ac3dec
->
p_aout_fifo
->
data_wait
));
vlc_mutex_unlock
(
&
(
p_ac3dec
->
p_aout_fifo
->
data_lock
));
vlc_mutex_lock
(
&
(
p_ac3dec_t
->
p_aout_fifo
->
data_lock
));
vlc_cond_signal
(
&
(
p_ac3dec_t
->
p_aout_fifo
->
data_wait
));
vlc_mutex_unlock
(
&
(
p_ac3dec_t
->
p_aout_fifo
->
data_lock
));
}
/* Destroy descriptor */
free
(
p_ac3dec
->
p_config
);
free
(
p_ac3dec
);
free
(
p_ac3dec
_t
->
p_config
);
free
(
p_ac3dec
_t
);
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread %p destroyed"
,
p_ac3dec
);
intf_DbgMsg
(
"ac3dec debug: ac3 decoder thread %p destroyed"
,
p_ac3dec
_t
);
}
void
ac3_byte_stream_next
(
ac3_byte_stream_t
*
p_byte_stream
)
/*****************************************************************************
* BitstreamCallback: Import parame