Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
b456ece5
Commit
b456ece5
authored
Nov 01, 2015
by
Paul B Mahol
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
XMA1 and XMA2 stereo decoders
Signed-off-by:
Paul B Mahol
<
onemda@gmail.com
>
parent
c8780822
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
164 additions
and
21 deletions
+164
-21
Changelog
Changelog
+1
-0
general.texi
doc/general.texi
+2
-0
Makefile
libavcodec/Makefile
+2
-0
allcodecs.c
libavcodec/allcodecs.c
+2
-0
avcodec.h
libavcodec/avcodec.h
+2
-0
codec_desc.c
libavcodec/codec_desc.c
+14
-0
version.h
libavcodec/version.h
+1
-1
wmaprodec.c
libavcodec/wmaprodec.c
+116
-15
riff.c
libavformat/riff.c
+2
-0
riffdec.c
libavformat/riffdec.c
+22
-5
No files found.
Changelog
View file @
b456ece5
...
...
@@ -30,6 +30,7 @@ version <next>:
- innoHeim/Rsupport Screen Capture Codec decoder
- ADPCM AICA decoder
- Interplay ACM demuxer and audio decoder
- XMA1 & XMA2 decoder
version 2.8:
...
...
doc/general.texi
View file @
b456ece5
...
...
@@ -1076,6 +1076,8 @@ following image formats are supported:
@item Windows Media Audio Lossless @tab @tab X
@item Windows Media Audio Pro @tab @tab X
@item Windows Media Audio Voice @tab @tab X
@item Xbox Media Audio 1 @tab @tab X
@item Xbox Media Audio 2 @tab @tab X
@end multitable
@code
{
X
}
means that encoding (resp. decoding) is supported.
...
...
libavcodec/Makefile
View file @
b456ece5
...
...
@@ -586,6 +586,8 @@ OBJS-$(CONFIG_XBM_ENCODER) += xbmenc.o
OBJS-$(CONFIG_XFACE_DECODER)
+=
xfacedec.o
xface.o
OBJS-$(CONFIG_XFACE_ENCODER)
+=
xfaceenc.o
xface.o
OBJS-$(CONFIG_XL_DECODER)
+=
xl.o
OBJS-$(CONFIG_XMA1_DECODER)
+=
wmaprodec.o
wma.o
wma_common.o
OBJS-$(CONFIG_XMA2_DECODER)
+=
wmaprodec.o
wma.o
wma_common.o
OBJS-$(CONFIG_XSUB_DECODER)
+=
xsubdec.o
OBJS-$(CONFIG_XSUB_ENCODER)
+=
xsubenc.o
OBJS-$(CONFIG_XWD_DECODER)
+=
xwddec.o
...
...
libavcodec/allcodecs.c
View file @
b456ece5
...
...
@@ -445,6 +445,8 @@ void avcodec_register_all(void)
REGISTER_ENCDEC
(
WMAV2
,
wmav2
);
REGISTER_DECODER
(
WMAVOICE
,
wmavoice
);
REGISTER_DECODER
(
WS_SND1
,
ws_snd1
);
REGISTER_DECODER
(
XMA1
,
xma1
);
REGISTER_DECODER
(
XMA2
,
xma2
);
/* PCM codecs */
REGISTER_ENCDEC
(
PCM_ALAW
,
pcm_alaw
);
...
...
libavcodec/avcodec.h
View file @
b456ece5
...
...
@@ -497,6 +497,8 @@ enum AVCodecID {
AV_CODEC_ID_DSD_MSBF_PLANAR
,
AV_CODEC_ID_4GV
,
AV_CODEC_ID_INTERPLAY_ACM
,
AV_CODEC_ID_XMA1
,
AV_CODEC_ID_XMA2
,
/* subtitle codecs */
AV_CODEC_ID_FIRST_SUBTITLE
=
0x17000
,
///< A dummy ID pointing at the start of subtitle codecs.
...
...
libavcodec/codec_desc.c
View file @
b456ece5
...
...
@@ -2629,6 +2629,20 @@ static const AVCodecDescriptor codec_descriptors[] = {
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Interplay ACM"
),
.
props
=
AV_CODEC_PROP_LOSSY
,
},
{
.
id
=
AV_CODEC_ID_XMA1
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
name
=
"xma1"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Xbox Media Audio 1"
),
.
props
=
AV_CODEC_PROP_LOSSY
,
},
{
.
id
=
AV_CODEC_ID_XMA2
,
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
name
=
"xma2"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Xbox Media Audio 2"
),
.
props
=
AV_CODEC_PROP_LOSSY
,
},
/* subtitle codecs */
{
...
...
libavcodec/version.h
View file @
b456ece5
...
...
@@ -29,7 +29,7 @@
#include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 1
4
#define LIBAVCODEC_VERSION_MINOR 1
5
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
...
...
libavcodec/wmaprodec.c
View file @
b456ece5
...
...
@@ -206,9 +206,11 @@ typedef struct WMAProDecodeCtx {
int
subframe_offset
;
///< subframe offset in the bit reservoir
uint8_t
packet_loss
;
///< set in case of bitstream error
uint8_t
packet_done
;
///< set when a packet is fully decoded
uint8_t
skip_packets
;
/* frame decode state */
uint32_t
frame_num
;
///< current frame number (not used for decoding)
int
num_frames
;
GetBitContext
gb
;
///< bitstream reader context
int
buf_bit_size
;
///< buffer size in bits
uint8_t
drc_gain
;
///< gain for the DRC tool
...
...
@@ -268,6 +270,21 @@ static av_cold int decode_end(AVCodecContext *avctx)
return
0
;
}
static
av_cold
int
get_rate
(
AVCodecContext
*
avctx
)
{
if
(
avctx
->
codec_id
!=
AV_CODEC_ID_WMAPRO
)
{
// XXX: is this really only for XMA?
if
(
avctx
->
sample_rate
>
44100
)
return
48000
;
else
if
(
avctx
->
sample_rate
>
32000
)
return
44100
;
else
if
(
avctx
->
sample_rate
>
24000
)
return
32000
;
return
24000
;
}
return
avctx
->
sample_rate
;
}
/**
*@brief Initialize the decoder.
*@param avctx codec context
...
...
@@ -282,6 +299,9 @@ static av_cold int decode_init(AVCodecContext *avctx)
int
log2_max_num_subframes
;
int
num_possible_block_sizes
;
if
(
avctx
->
codec_id
==
AV_CODEC_ID_XMA1
||
avctx
->
codec_id
==
AV_CODEC_ID_XMA2
)
avctx
->
block_align
=
2048
;
if
(
!
avctx
->
block_align
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"block_align is not set
\n
"
);
return
AVERROR
(
EINVAL
);
...
...
@@ -296,7 +316,25 @@ static av_cold int decode_init(AVCodecContext *avctx)
avctx
->
sample_fmt
=
AV_SAMPLE_FMT_FLTP
;
if
(
avctx
->
extradata_size
>=
18
)
{
if
(
avctx
->
codec_id
==
AV_CODEC_ID_XMA2
&&
avctx
->
extradata_size
>=
34
)
{
s
->
decode_flags
=
0x10d6
;
channel_mask
=
AV_RL32
(
edata_ptr
+
2
);
s
->
bits_per_sample
=
16
;
/** dump the extradata */
for
(
i
=
0
;
i
<
avctx
->
extradata_size
;
i
++
)
ff_dlog
(
avctx
,
"[%x] "
,
avctx
->
extradata
[
i
]);
ff_dlog
(
avctx
,
"
\n
"
);
}
else
if
(
avctx
->
codec_id
==
AV_CODEC_ID_XMA1
&&
avctx
->
extradata_size
>=
28
)
{
s
->
decode_flags
=
0x10d6
;
s
->
bits_per_sample
=
16
;
channel_mask
=
0
;
/** dump the extradata */
for
(
i
=
0
;
i
<
avctx
->
extradata_size
;
i
++
)
ff_dlog
(
avctx
,
"[%x] "
,
avctx
->
extradata
[
i
]);
ff_dlog
(
avctx
,
"
\n
"
);
}
else
if
(
avctx
->
extradata_size
>=
18
)
{
s
->
decode_flags
=
AV_RL16
(
edata_ptr
+
14
);
channel_mask
=
AV_RL32
(
edata_ptr
+
2
);
s
->
bits_per_sample
=
AV_RL16
(
edata_ptr
);
...
...
@@ -310,6 +348,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
return
AVERROR_PATCHWELCOME
;
}
if
(
avctx
->
codec_id
!=
AV_CODEC_ID_WMAPRO
&&
avctx
->
channels
>
2
)
{
avpriv_report_missing_feature
(
avctx
,
">2 channels support"
);
return
AVERROR_PATCHWELCOME
;
}
/** generic init */
s
->
log2_frame_size
=
av_log2
(
avctx
->
block_align
)
+
4
;
if
(
s
->
log2_frame_size
>
25
)
{
...
...
@@ -318,17 +361,25 @@ static av_cold int decode_init(AVCodecContext *avctx)
}
/** frame info */
s
->
skip_frame
=
1
;
/* skip first frame */
if
(
avctx
->
codec_id
!=
AV_CODEC_ID_WMAPRO
)
s
->
skip_frame
=
0
;
else
s
->
skip_frame
=
1
;
/* skip first frame */
s
->
packet_loss
=
1
;
s
->
len_prefix
=
(
s
->
decode_flags
&
0x40
);
/** get frame len */
bits
=
ff_wma_get_frame_len_bits
(
avctx
->
sample_rate
,
3
,
s
->
decode_flags
);
if
(
bits
>
WMAPRO_BLOCK_MAX_BITS
)
{
avpriv_request_sample
(
avctx
,
"14-bit block sizes"
);
return
AVERROR_PATCHWELCOME
;
if
(
avctx
->
codec_id
==
AV_CODEC_ID_WMAPRO
)
{
bits
=
ff_wma_get_frame_len_bits
(
avctx
->
sample_rate
,
3
,
s
->
decode_flags
);
if
(
bits
>
WMAPRO_BLOCK_MAX_BITS
)
{
avpriv_request_sample
(
avctx
,
"14-bit block sizes"
);
return
AVERROR_PATCHWELCOME
;
}
s
->
samples_per_frame
=
1
<<
bits
;
}
else
{
s
->
samples_per_frame
=
512
;
}
s
->
samples_per_frame
=
1
<<
bits
;
/** subframe info */
log2_max_num_subframes
=
((
s
->
decode_flags
&
0x38
)
>>
3
);
...
...
@@ -417,12 +468,12 @@ static av_cold int decode_init(AVCodecContext *avctx)
int
subframe_len
=
s
->
samples_per_frame
>>
i
;
int
x
;
int
band
=
1
;
int
rate
=
get_rate
(
avctx
);
s
->
sfb_offsets
[
i
][
0
]
=
0
;
for
(
x
=
0
;
x
<
MAX_BANDS
-
1
&&
s
->
sfb_offsets
[
i
][
band
-
1
]
<
subframe_len
;
x
++
)
{
int
offset
=
(
subframe_len
*
2
*
critical_freq
[
x
])
/
s
->
avctx
->
sample_rate
+
2
;
int
offset
=
(
subframe_len
*
2
*
critical_freq
[
x
])
/
rate
+
2
;
offset
&=
~
3
;
if
(
offset
>
s
->
sfb_offsets
[
i
][
band
-
1
])
s
->
sfb_offsets
[
i
][
band
++
]
=
offset
;
...
...
@@ -1535,32 +1586,52 @@ static int decode_packet(AVCodecContext *avctx, void *data,
*
got_frame_ptr
=
0
;
if
(
s
->
skip_packets
>
0
)
{
s
->
skip_packets
--
;
return
FFMIN
(
avpkt
->
size
,
avctx
->
block_align
);
}
if
(
s
->
packet_done
||
s
->
packet_loss
)
{
s
->
packet_done
=
0
;
/** sanity check for the buffer length */
if
(
buf_size
<
avctx
->
block_align
)
{
if
(
avctx
->
codec_id
==
AV_CODEC_ID_WMAPRO
&&
buf_size
<
avctx
->
block_align
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Input packet too small (%d < %d)
\n
"
,
buf_size
,
avctx
->
block_align
);
return
AVERROR_INVALIDDATA
;
}
s
->
next_packet_start
=
buf_size
-
avctx
->
block_align
;
buf_size
=
avctx
->
block_align
;
if
(
avctx
->
codec_id
==
AV_CODEC_ID_WMAPRO
)
{
s
->
next_packet_start
=
buf_size
-
avctx
->
block_align
;
buf_size
=
avctx
->
block_align
;
}
else
{
s
->
next_packet_start
=
buf_size
-
FFMIN
(
buf_size
,
avctx
->
block_align
);
buf_size
=
FFMIN
(
buf_size
,
avctx
->
block_align
);
}
s
->
buf_bit_size
=
buf_size
<<
3
;
/** parse packet header */
init_get_bits
(
gb
,
buf
,
s
->
buf_bit_size
);
packet_sequence_number
=
get_bits
(
gb
,
4
);
skip_bits
(
gb
,
2
);
if
(
avctx
->
codec_id
==
AV_CODEC_ID_WMAPRO
)
{
packet_sequence_number
=
get_bits
(
gb
,
4
);
skip_bits
(
gb
,
2
);
}
else
{
s
->
num_frames
=
get_bits
(
gb
,
6
);
packet_sequence_number
=
0
;
}
/** get number of bits that need to be added to the previous frame */
num_bits_prev_frame
=
get_bits
(
gb
,
s
->
log2_frame_size
);
if
(
avctx
->
codec_id
!=
AV_CODEC_ID_WMAPRO
)
{
skip_bits
(
gb
,
3
);
s
->
skip_packets
=
get_bits
(
gb
,
8
);
}
ff_dlog
(
avctx
,
"packet[%d]: nbpf %x
\n
"
,
avctx
->
frame_number
,
num_bits_prev_frame
);
/** check for packet loss */
if
(
!
s
->
packet_loss
&&
if
(
avctx
->
codec_id
==
AV_CODEC_ID_WMAPRO
&&
!
s
->
packet_loss
&&
((
s
->
packet_sequence_number
+
1
)
&
0xF
)
!=
packet_sequence_number
)
{
s
->
packet_loss
=
1
;
av_log
(
avctx
,
AV_LOG_ERROR
,
...
...
@@ -1671,3 +1742,33 @@ AVCodec ff_wmapro_decoder = {
.
sample_fmts
=
(
const
enum
AVSampleFormat
[])
{
AV_SAMPLE_FMT_FLTP
,
AV_SAMPLE_FMT_NONE
},
};
AVCodec
ff_xma1_decoder
=
{
.
name
=
"xma1"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Xbox Media Audio 1"
),
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
id
=
AV_CODEC_ID_XMA1
,
.
priv_data_size
=
sizeof
(
WMAProDecodeCtx
),
.
init
=
decode_init
,
.
close
=
decode_end
,
.
decode
=
decode_packet
,
.
capabilities
=
AV_CODEC_CAP_SUBFRAMES
|
AV_CODEC_CAP_DR1
,
.
flush
=
flush
,
.
sample_fmts
=
(
const
enum
AVSampleFormat
[])
{
AV_SAMPLE_FMT_FLTP
,
AV_SAMPLE_FMT_NONE
},
};
AVCodec
ff_xma2_decoder
=
{
.
name
=
"xma2"
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Xbox Media Audio 2"
),
.
type
=
AVMEDIA_TYPE_AUDIO
,
.
id
=
AV_CODEC_ID_XMA2
,
.
priv_data_size
=
sizeof
(
WMAProDecodeCtx
),
.
init
=
decode_init
,
.
close
=
decode_end
,
.
decode
=
decode_packet
,
.
capabilities
=
AV_CODEC_CAP_SUBFRAMES
|
AV_CODEC_CAP_DR1
,
.
flush
=
flush
,
.
sample_fmts
=
(
const
enum
AVSampleFormat
[])
{
AV_SAMPLE_FMT_FLTP
,
AV_SAMPLE_FMT_NONE
},
};
libavformat/riff.c
View file @
b456ece5
...
...
@@ -424,6 +424,8 @@ const AVCodecTag ff_codec_wav_tags[] = {
{
AV_CODEC_ID_WMAV2
,
0x0161
},
{
AV_CODEC_ID_WMAPRO
,
0x0162
},
{
AV_CODEC_ID_WMALOSSLESS
,
0x0163
},
{
AV_CODEC_ID_XMA1
,
0x0165
},
{
AV_CODEC_ID_XMA2
,
0x0166
},
{
AV_CODEC_ID_ADPCM_CT
,
0x0200
},
{
AV_CODEC_ID_ATRAC3
,
0x0270
},
{
AV_CODEC_ID_ADPCM_G722
,
0x028F
},
...
...
libavformat/riffdec.c
View file @
b456ece5
...
...
@@ -99,10 +99,12 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb,
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
if
(
!
big_endian
)
{
id
=
avio_rl16
(
pb
);
codec
->
channels
=
avio_rl16
(
pb
);
codec
->
sample_rate
=
avio_rl32
(
pb
);
bitrate
=
avio_rl32
(
pb
)
*
8LL
;
codec
->
block_align
=
avio_rl16
(
pb
);
if
(
id
!=
0x0165
)
{
codec
->
channels
=
avio_rl16
(
pb
);
codec
->
sample_rate
=
avio_rl32
(
pb
);
bitrate
=
avio_rl32
(
pb
)
*
8LL
;
codec
->
block_align
=
avio_rl16
(
pb
);
}
}
else
{
id
=
avio_rb16
(
pb
);
codec
->
channels
=
avio_rb16
(
pb
);
...
...
@@ -126,7 +128,7 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb,
codec
->
codec_id
=
ff_wav_codec_get_id
(
id
,
codec
->
bits_per_coded_sample
);
}
if
(
size
>=
18
)
{
/* We're obviously dealing with WAVEFORMATEX */
if
(
size
>=
18
&&
id
!=
0x0165
)
{
/* We're obviously dealing with WAVEFORMATEX */
int
cbSize
=
avio_rl16
(
pb
);
/* cbSize */
if
(
big_endian
)
{
avpriv_report_missing_feature
(
codec
,
"WAVEFORMATEX support for RIFX files
\n
"
);
...
...
@@ -149,6 +151,21 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb,
/* It is possible for the chunk to contain garbage at the end */
if
(
size
>
0
)
avio_skip
(
pb
,
size
);
}
else
if
(
id
==
0x0165
&&
size
>=
32
)
{
int
nb_streams
,
i
;
size
-=
4
;
av_freep
(
&
codec
->
extradata
);
if
(
ff_get_extradata
(
codec
,
pb
,
size
)
<
0
)
return
AVERROR
(
ENOMEM
);
nb_streams
=
AV_RL16
(
codec
->
extradata
+
4
);
codec
->
sample_rate
=
AV_RL32
(
codec
->
extradata
+
12
);
codec
->
channels
=
0
;
bitrate
=
0
;
if
(
size
<
8
+
nb_streams
*
20
)
return
AVERROR_INVALIDDATA
;
for
(
i
=
0
;
i
<
nb_streams
;
i
++
)
codec
->
channels
+=
codec
->
extradata
[
8
+
i
*
20
+
17
];
}
if
(
bitrate
>
INT_MAX
)
{
...
...
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