History

adx: move header decoding to ADX common code

Justin Ruggles committed 14 years ago

Commit d8cec2d1 parent 7ff55d93 files · +74 −36Browse files

Unified · Split

3 files
  1. libavcodec/adx.c +47 −0
  2. libavcodec/adx.h +21 −0
  3. libavcodec/adxdec.c +6 −36
libavcodec/adx.c+47−0
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1919 */
2020
21+#include "libavutil/intreadwrite.h"
2122 #include "libavutil/mathematics.h"
2223 #include "adx.h"
2324
@@ -32,3 +33,49 @@ void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff) · 8 unmodified lines
3233 coeff[0] = lrintf(c * 2.0 * (1 << bits));
3334 coeff[1] = lrintf(-(c * c) * (1 << bits));
3435 }
36+
37+int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize,
38+ int *header_size, int *coeff)
39+{
40+ int offset, cutoff;
41+
42+ if (bufsize < 24)
43+ return AVERROR_INVALIDDATA;
44+
45+ if (AV_RB16(buf) != 0x8000)
46+ return AVERROR_INVALIDDATA;
47+ offset = AV_RB16(buf + 2) + 4;
48+
49+ /* if copyright string is within the provided data, validate it */
50+ if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6))
51+ return AVERROR_INVALIDDATA;
52+
53+ /* check for encoding=3 block_size=18, sample_size=4 */
54+ if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
55+ av_log_ask_for_sample(avctx, "unsupported ADX format\n");
56+ return AVERROR_PATCHWELCOME;
57+ }
58+
59+ /* channels */
60+ avctx->channels = buf[7];
61+ if (avctx->channels > 2)
62+ return AVERROR_INVALIDDATA;
63+
64+ /* sample rate */
65+ avctx->sample_rate = AV_RB32(buf + 8);
66+ if (avctx->sample_rate < 1 ||
67+ avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))
68+ return AVERROR_INVALIDDATA;
69+
70+ /* bit rate */
71+ avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
72+
73+ /* LPC coefficients */
74+ if (coeff) {
75+ cutoff = AV_RB16(buf + 16);
76+ ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);
77+ }
78+
79+ *header_size = offset;
80+ return 0;
81+}
libavcodec/adx.h+21−0
@@ -31,6 +31,10 @@ · 30 unmodified lines
3131 #ifndef AVCODEC_ADX_H
3232 #define AVCODEC_ADX_H
3333
34+#include <stdint.h>
35+
36+#include "avcodec.h"
37+
3438 typedef struct {
3539 int s1,s2;
3640 } ADXChannelState;
@@ -47,6 +51,9 @@ typedef struct { · 10 unmodified lines
4751
4852 #define COEFF_BITS 12
4953
54+#define BLOCK_SIZE 18
55+#define BLOCK_SAMPLES 32
56+
5057 /**
5158 * Calculate LPC coefficients based on cutoff frequency and sample rate.
5259 *
@@ -57,4 +64,18 @@ typedef struct { · 4 unmodified lines
5764 */
5865 void ff_adx_calculate_coeffs(int cutoff, int sample_rate, int bits, int *coeff);
5966
67+/**
68+ * Decode ADX stream header.
69+ * Sets avctx->channels and avctx->sample_rate.
70+ *
71+ * @param avctx codec context
72+ * @param buf header data
73+ * @param bufsize data size, should be at least 24 bytes
74+ * @param[out] header_size size of ADX header
75+ * @param[out] coeff 2 LPC coefficients, can be NULL
76+ * @return data offset or negative error code if header is invalid
77+ */
78+int ff_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, int bufsize,
79+ int *header_size, int *coeff);
80+
6081 #endif /* AVCODEC_ADX_H */
libavcodec/adxdec.c+6−36
@@ -33,9 +33,6 @@ · 32 unmodified lines
3333 * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
3434 */
3535
36−#define BLOCK_SIZE 18
37−#define BLOCK_SAMPLES 32
38−
3936 static av_cold int adx_decode_init(AVCodecContext *avctx)
4037 {
4138 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
@@ -72,45 +69,18 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) · 30 unmodified lines
7269 prev->s2 = s2;
7370 }
7471
75−/**
76− * Decode stream header.
77− *
78− * @param avctx codec context
79− * @param buf packet data
80− * @param bufsize packet size
81− * @return data offset or negative error code if header is invalid
82− */
8372 static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
8473 int bufsize)
8574 {
8675 ADXContext *c = avctx->priv_data;
87− int offset, cutoff;
88−
89− if (AV_RB16(buf) != 0x8000)
90− return AVERROR_INVALIDDATA;
91− offset = AV_RB16(buf + 2) + 4;
92− if (bufsize < offset || memcmp(buf + offset - 6, "(c)CRI", 6))
93− return AVERROR_INVALIDDATA;
94−
95− /* check for encoding=3 block_size=18, sample_size=4 */
96− if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
97− av_log_ask_for_sample(avctx, "unsupported ADX format\n");
98− return AVERROR_PATCHWELCOME;
99− }
100−
101− c->channels = avctx->channels = buf[7];
102− if (avctx->channels > 2)
103− return AVERROR_INVALIDDATA;
104− avctx->sample_rate = AV_RB32(buf + 8);
105− if (avctx->sample_rate < 1 ||
106− avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))
107− return AVERROR_INVALIDDATA;
108− avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;
76+ int ret, header_size;
10977
110− cutoff = AV_RB16(buf + 16);
111− ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, c->coeff);
78+ if ((ret = ff_adx_decode_header(avctx, buf, bufsize, &header_size,
79+ c->coeff)) < 0)
80+ return ret;
11281
113− return offset;
82+ c->channels = avctx->channels;
83+ return header_size;
11484 }
11585
11686 static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t