Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
7b84f1e6
Commit
7b84f1e6
authored
Feb 17, 2009
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
faad: use the decoder_buffer library
Replace this plugin's own buffer library with the new decoder_buffer library.
parent
7cea5357
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
155 additions
and
152 deletions
+155
-152
faad_plugin.c
src/decoder/faad_plugin.c
+155
-152
No files found.
src/decoder/faad_plugin.c
View file @
7b84f1e6
...
...
@@ -17,6 +17,7 @@
*/
#include "../decoder_api.h"
#include "decoder_buffer.h"
#include "config.h"
#define AAC_MAX_CHANNELS 6
...
...
@@ -29,60 +30,6 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "faad"
/* all code here is either based on or copied from FAAD2's frontend code */
struct
faad_buffer
{
struct
decoder
*
decoder
;
struct
input_stream
*
is
;
size_t
length
;
size_t
consumed
;
unsigned
char
data
[
FAAD_MIN_STREAMSIZE
*
AAC_MAX_CHANNELS
];
};
static
void
faad_buffer_shift
(
struct
faad_buffer
*
b
,
size_t
length
)
{
assert
(
length
>=
b
->
consumed
);
assert
(
length
<=
b
->
consumed
+
b
->
length
);
memmove
(
b
->
data
,
b
->
data
+
length
,
b
->
consumed
+
b
->
length
-
length
);
length
-=
b
->
consumed
;
b
->
consumed
=
0
;
b
->
length
-=
length
;
}
static
void
faad_buffer_fill
(
struct
faad_buffer
*
b
)
{
size_t
rest
,
bread
;
if
(
b
->
consumed
>
0
)
faad_buffer_shift
(
b
,
b
->
consumed
);
rest
=
sizeof
(
b
->
data
)
-
b
->
length
;
if
(
rest
==
0
)
/* buffer already full */
return
;
bread
=
decoder_read
(
b
->
decoder
,
b
->
is
,
b
->
data
+
b
->
length
,
rest
);
b
->
length
+=
bread
;
if
((
b
->
length
>
3
&&
memcmp
(
b
->
data
,
"TAG"
,
3
)
==
0
)
||
(
b
->
length
>
11
&&
memcmp
(
b
->
data
,
"LYRICSBEGIN"
,
11
)
==
0
)
||
(
b
->
length
>
8
&&
memcmp
(
b
->
data
,
"APETAGEX"
,
8
)
==
0
))
b
->
length
=
0
;
}
static
void
faad_buffer_consume
(
struct
faad_buffer
*
b
,
size_t
bytes
)
{
b
->
consumed
=
bytes
;
b
->
length
-=
bytes
;
}
static
const
unsigned
adts_sample_rates
[]
=
{
96000
,
88200
,
64000
,
48000
,
44100
,
32000
,
24000
,
22050
,
16000
,
12000
,
11025
,
8000
,
7350
,
0
,
0
,
0
...
...
@@ -93,17 +40,15 @@ static const unsigned adts_sample_rates[] =
* length. Returns 0 if it is not a frame.
*/
static
size_t
adts_check_frame
(
struct
faad_buffer
*
b
)
adts_check_frame
(
const
unsigned
char
*
data
)
{
assert
(
b
->
length
>=
8
);
/* check syncword */
if
(
!
((
b
->
data
[
0
]
==
0xFF
)
&&
((
b
->
data
[
1
]
&
0xF6
)
==
0xF0
)))
if
(
!
((
data
[
0
]
==
0xFF
)
&&
((
data
[
1
]
&
0xF6
)
==
0xF0
)))
return
0
;
return
(((
unsigned
int
)
b
->
data
[
3
]
&
0x3
)
<<
11
)
|
(((
unsigned
int
)
b
->
data
[
4
])
<<
3
)
|
(
b
->
data
[
5
]
>>
5
);
return
(((
unsigned
int
)
data
[
3
]
&
0x3
)
<<
11
)
|
(((
unsigned
int
)
data
[
4
])
<<
3
)
|
(
data
[
5
]
>>
5
);
}
/**
...
...
@@ -111,40 +56,71 @@ adts_check_frame(struct faad_buffer *b)
* found or if not enough data is available.
*/
static
size_t
adts_find_frame
(
struct
faad_buffer
*
b
)
adts_find_frame
(
struct
decoder_buffer
*
buffer
)
{
const
unsigned
char
*
p
;
size_t
frame_length
;
const
unsigned
char
*
data
,
*
p
;
size_t
length
,
frame_length
;
bool
ret
;
faad_buffer_fill
(
b
);
while
(
true
)
{
data
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
data
==
NULL
||
length
<
8
)
{
/* not enough data yet */
ret
=
decoder_buffer_fill
(
buffer
);
if
(
!
ret
)
/* failed */
return
0
;
while
((
p
=
memchr
(
b
->
data
,
0xff
,
b
->
length
))
!=
NULL
)
{
/* discard data before 0xff */
if
(
p
>
b
->
data
)
faad_buffer_shift
(
b
,
p
-
b
->
data
);
continue
;
}
if
(
b
->
length
<
8
)
/* not enough data yet */
return
0
;
/* find the 0xff marker */
p
=
memchr
(
data
,
0xff
,
length
);
if
(
p
==
NULL
)
{
/* no marker - discard the buffer */
decoder_buffer_consume
(
buffer
,
length
);
continue
;
}
if
(
p
>
data
)
{
/* discard data before 0xff */
decoder_buffer_consume
(
buffer
,
p
-
data
);
continue
;
}
/* is it a frame? */
frame_length
=
adts_check_frame
(
b
);
if
(
frame_length
>
0
)
/* yes, it is */
return
frame_length
;
/* it's just some random 0xff byte; discard and and
continue searching */
faad_buffer_shift
(
b
,
1
);
}
frame_length
=
adts_check_frame
(
data
);
if
(
frame_length
==
0
)
{
/* it's just some random 0xff byte; discard it
and continue searching */
decoder_buffer_consume
(
buffer
,
1
);
continue
;
}
if
(
length
<
frame_length
)
{
/* available buffer size is smaller than the
frame will be - attempt to read more
data */
ret
=
decoder_buffer_fill
(
buffer
);
if
(
!
ret
)
{
/* not enough data; discard this frame
to prevent a possible buffer
overflow */
data
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
data
!=
NULL
)
decoder_buffer_consume
(
buffer
,
length
);
}
continue
;
}
/* nothing at all; discard the whole buffer
*/
faad_buffer_shift
(
b
,
b
->
length
)
;
return
0
;
/* found a full frame!
*/
return
frame_length
;
}
}
static
float
adts_song_duration
(
struct
faad_buffer
*
b
)
adts_song_duration
(
struct
decoder_buffer
*
buffer
)
{
unsigned
int
frames
,
frame_length
;
unsigned
sample_rate
=
0
;
...
...
@@ -152,18 +128,23 @@ adts_song_duration(struct faad_buffer *b)
/* Read all frames to ensure correct time and bitrate */
for
(
frames
=
0
;;
frames
++
)
{
frame_length
=
adts_find_frame
(
b
);
if
(
frame_length
>
0
)
{
if
(
frames
==
0
)
{
sample_rate
=
adts_sample_rates
[(
b
->
data
[
2
]
&
0x3c
)
>>
2
];
}
frame_length
=
adts_find_frame
(
buffer
);
if
(
frame_length
==
0
)
break
;
if
(
frame_length
>
b
->
length
)
break
;
faad_buffer_consume
(
b
,
frame_length
);
}
else
break
;
if
(
frames
==
0
)
{
const
unsigned
char
*
data
;
size_t
buffer_length
;
data
=
decoder_buffer_read
(
buffer
,
&
buffer_length
);
assert
(
data
!=
NULL
);
assert
(
frame_length
<=
buffer_length
);
sample_rate
=
adts_sample_rates
[(
data
[
2
]
&
0x3c
)
>>
2
];
}
decoder_buffer_consume
(
buffer
,
frame_length
);
}
frames_per_second
=
(
float
)
sample_rate
/
1024
.
0
;
...
...
@@ -173,61 +154,60 @@ adts_song_duration(struct faad_buffer *b)
return
(
float
)
frames
/
frames_per_second
;
}
static
void
faad_buffer_init
(
struct
faad_buffer
*
buffer
,
struct
decoder
*
decoder
,
struct
input_stream
*
is
)
{
memset
(
buffer
,
0
,
sizeof
(
*
buffer
));
buffer
->
decoder
=
decoder
;
buffer
->
is
=
is
;
}
static
float
faad_song_duration
(
struct
faad_buffer
*
b
)
faad_song_duration
(
struct
decoder_buffer
*
buffer
,
struct
input_stream
*
is
)
{
size_t
fileread
;
size_t
tagsize
;
const
unsigned
char
*
data
;
size_t
length
;
fileread
=
b
->
is
->
size
>=
0
?
b
->
is
->
size
:
0
;
fileread
=
is
->
size
>=
0
?
is
->
size
:
0
;
faad_buffer_fill
(
b
);
decoder_buffer_fill
(
buffer
);
data
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
data
==
NULL
)
return
-
1
;
tagsize
=
0
;
if
(
b
->
length
>=
10
&&
!
memcmp
(
b
->
data
,
"ID3"
,
3
))
{
tagsize
=
(
b
->
data
[
6
]
<<
21
)
|
(
b
->
data
[
7
]
<<
14
)
|
(
b
->
data
[
8
]
<<
7
)
|
(
b
->
data
[
9
]
<<
0
);
if
(
length
>=
10
&&
!
memcmp
(
data
,
"ID3"
,
3
))
{
tagsize
=
(
data
[
6
]
<<
21
)
|
(
data
[
7
]
<<
14
)
|
(
data
[
8
]
<<
7
)
|
(
data
[
9
]
<<
0
);
tagsize
+=
10
;
faad_buffer_consume
(
b
,
tagsize
);
faad_buffer_fill
(
b
);
decoder_buffer_consume
(
buffer
,
tagsize
);
decoder_buffer_fill
(
buffer
);
data
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
data
==
NULL
)
return
-
1
;
}
if
(
b
->
is
->
seekable
&&
b
->
length
>=
2
&&
(
b
->
data
[
0
]
==
0xFF
)
&&
((
b
->
data
[
1
]
&
0xF6
)
==
0xF0
))
{
float
length
=
adts_song_duration
(
b
);
input_stream_seek
(
b
->
is
,
tagsize
,
SEEK_SET
);
if
(
is
->
seekable
&&
length
>=
2
&&
data
[
0
]
==
0xFF
&&
((
data
[
1
]
&
0xF6
)
==
0xF0
))
{
float
song_length
=
adts_song_duration
(
buffer
);
b
->
length
=
0
;
b
->
consumed
=
0
;
input_stream_seek
(
is
,
tagsize
,
SEEK_SET
);
faad_buffer_fill
(
b
);
data
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
data
!=
NULL
)
decoder_buffer_consume
(
buffer
,
length
);
decoder_buffer_fill
(
buffer
);
return
length
;
}
else
if
(
b
->
length
>=
5
&&
memcmp
(
b
->
data
,
"ADIF"
,
4
)
==
0
)
{
return
song_
length
;
}
else
if
(
length
>=
5
&&
memcmp
(
data
,
"ADIF"
,
4
)
==
0
)
{
unsigned
bit_rate
;
size_t
skip_size
=
(
b
->
data
[
4
]
&
0x80
)
?
9
:
0
;
size_t
skip_size
=
(
data
[
4
]
&
0x80
)
?
9
:
0
;
if
(
8
+
skip_size
>
b
->
length
)
if
(
8
+
skip_size
>
length
)
/* not enough data yet; skip parsing this
header */
return
-
1
;
bit_rate
=
((
unsigned
)(
b
->
data
[
4
+
skip_size
]
&
0x0F
)
<<
19
)
|
(
(
unsigned
)
b
->
data
[
5
+
skip_size
]
<<
11
)
|
(
(
unsigned
)
b
->
data
[
6
+
skip_size
]
<<
3
)
|
(
(
unsigned
)
b
->
data
[
7
+
skip_size
]
&
0xE0
);
bit_rate
=
((
data
[
4
+
skip_size
]
&
0x0F
)
<<
19
)
|
(
data
[
5
+
skip_size
]
<<
11
)
|
(
data
[
6
+
skip_size
]
<<
3
)
|
(
data
[
7
+
skip_size
]
&
0xE0
);
if
(
fileread
!=
0
&&
bit_rate
!=
0
)
return
fileread
*
8
.
0
/
bit_rate
;
...
...
@@ -242,9 +222,15 @@ faad_song_duration(struct faad_buffer *b)
* inconsistencies in libfaad.
*/
static
bool
faad_decoder_init
(
faacDecHandle
decoder
,
struct
faad
_buffer
*
buffer
,
faad_decoder_init
(
faacDecHandle
decoder
,
struct
decoder
_buffer
*
buffer
,
uint32_t
*
sample_rate
,
uint8_t
*
channels
)
{
union
{
/* deconst hack for libfaad */
const
void
*
in
;
void
*
out
;
}
u
;
size_t
length
;
int32_t
nbytes
;
#ifdef HAVE_FAAD_LONG
/* neaacdec.h declares all arguments as "unsigned long", but
...
...
@@ -255,15 +241,19 @@ faad_decoder_init(faacDecHandle decoder, struct faad_buffer *buffer,
uint32_t
*
sample_rate_r
=
sample_rate
;
#endif
nbytes
=
faacDecInit
(
decoder
,
buffer
->
data
,
u
.
in
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
u
.
in
==
NULL
)
return
false
;
nbytes
=
faacDecInit
(
decoder
,
u
.
out
,
#ifdef HAVE_FAAD_BUFLEN_FUNCS
buffer
->
length
,
length
,
#endif
sample_rate_r
,
channels
);
if
(
nbytes
<
0
)
return
false
;
faad
_buffer_consume
(
buffer
,
nbytes
);
decoder
_buffer_consume
(
buffer
,
nbytes
);
return
true
;
}
...
...
@@ -272,15 +262,25 @@ faad_decoder_init(faacDecHandle decoder, struct faad_buffer *buffer,
* inconsistencies in libfaad.
*/
static
const
void
*
faad_decoder_decode
(
faacDecHandle
decoder
,
struct
faad
_buffer
*
buffer
,
faad_decoder_decode
(
faacDecHandle
decoder
,
struct
decoder
_buffer
*
buffer
,
NeAACDecFrameInfo
*
frame_info
)
{
union
{
/* deconst hack for libfaad */
const
void
*
in
;
void
*
out
;
}
u
;
size_t
length
;
void
*
result
;
u
.
in
=
decoder_buffer_read
(
buffer
,
&
length
);
if
(
u
.
in
==
NULL
)
return
false
;
result
=
faacDecDecode
(
decoder
,
frame_info
,
buffer
->
data
u
.
out
#ifdef HAVE_FAAD_BUFLEN_FUNCS
,
buffer
->
length
,
length
#endif
);
...
...
@@ -290,7 +290,7 @@ faad_decoder_decode(faacDecHandle decoder, struct faad_buffer *buffer,
static
float
faad_get_file_time_float
(
const
char
*
file
)
{
struct
faad_buffer
buffer
;
struct
decoder_buffer
*
buffer
;
float
length
;
faacDecHandle
decoder
;
faacDecConfigurationPtr
config
;
...
...
@@ -301,8 +301,9 @@ faad_get_file_time_float(const char *file)
if
(
!
input_stream_open
(
&
is
,
file
))
return
-
1
;
faad_buffer_init
(
&
buffer
,
NULL
,
&
is
);
length
=
faad_song_duration
(
&
buffer
);
buffer
=
decoder_buffer_new
(
NULL
,
&
is
,
FAAD_MIN_STREAMSIZE
*
AAC_MAX_CHANNELS
);
length
=
faad_song_duration
(
buffer
,
&
is
);
if
(
length
<
0
)
{
bool
ret
;
...
...
@@ -313,9 +314,9 @@ faad_get_file_time_float(const char *file)
config
->
outputFormat
=
FAAD_FMT_16BIT
;
faacDecSetConfiguration
(
decoder
,
config
);
faad_buffer_fill
(
&
buffer
);
decoder_buffer_fill
(
buffer
);
ret
=
faad_decoder_init
(
decoder
,
&
buffer
,
ret
=
faad_decoder_init
(
decoder
,
buffer
,
&
sample_rate
,
&
channels
);
if
(
ret
&&
sample_rate
>
0
&&
channels
>
0
)
length
=
0
;
...
...
@@ -323,6 +324,7 @@ faad_get_file_time_float(const char *file)
faacDecClose
(
decoder
);
}
decoder_buffer_free
(
buffer
);
input_stream_close
(
&
is
);
return
length
;
...
...
@@ -355,12 +357,13 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
const
void
*
decoded
;
size_t
decoded_length
;
uint16_t
bit_rate
=
0
;
struct
faad_buffer
buffer
;
struct
decoder_buffer
*
buffer
;
bool
initialized
=
false
;
enum
decoder_command
cmd
;
faad_buffer_init
(
&
buffer
,
mpd_decoder
,
is
);
total_time
=
faad_song_duration
(
&
buffer
);
buffer
=
decoder_buffer_new
(
mpd_decoder
,
is
,
FAAD_MIN_STREAMSIZE
*
AAC_MAX_CHANNELS
);
total_time
=
faad_song_duration
(
buffer
,
is
);
decoder
=
faacDecOpen
();
...
...
@@ -374,14 +377,14 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
#endif
faacDecSetConfiguration
(
decoder
,
config
);
while
(
buffer
.
length
<
sizeof
(
buffer
.
data
)
&&
!
input_stream_eof
(
buffer
.
is
)
&&
while
(
!
decoder_buffer_is_full
(
buffer
)
&&
!
input_stream_eof
(
is
)
&&
decoder_get_command
(
mpd_decoder
)
==
DECODE_COMMAND_NONE
)
{
adts_find_frame
(
&
buffer
);
faad_buffer_fill
(
&
buffer
);
adts_find_frame
(
buffer
);
decoder_buffer_fill
(
buffer
);
}
ret
=
faad_decoder_init
(
decoder
,
&
buffer
,
ret
=
faad_decoder_init
(
decoder
,
buffer
,
&
sample_rate
,
&
channels
);
if
(
!
ret
)
{
g_warning
(
"Error not a AAC stream.
\n
"
);
...
...
@@ -392,11 +395,11 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
file_time
=
0
.
0
;
do
{
size_t
frame_size
=
adts_find_frame
(
&
buffer
);
size_t
frame_size
=
adts_find_frame
(
buffer
);
if
(
frame_size
==
0
)
break
;
decoded
=
faad_decoder_decode
(
decoder
,
&
buffer
,
&
frame_info
);
decoded
=
faad_decoder_decode
(
decoder
,
buffer
,
&
frame_info
);
if
(
frame_info
.
error
>
0
)
{
g_warning
(
"error decoding AAC stream: %s
\n
"
,
...
...
@@ -424,7 +427,7 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
initialized
=
true
;
}
faad_buffer_consume
(
&
buffer
,
frame_info
.
bytesconsumed
);
decoder_buffer_consume
(
buffer
,
frame_info
.
bytesconsumed
);
sample_count
=
(
unsigned
long
)
frame_info
.
samples
;
if
(
sample_count
>
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