Commit cbb39648 authored by Thilo Borgmann's avatar Thilo Borgmann

Add CRC check to the ALS decoder.

Originally committed as revision 23889 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent a4edc5a9
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "mpeg4audio.h" #include "mpeg4audio.h"
#include "bytestream.h" #include "bytestream.h"
#include "bgmc.h" #include "bgmc.h"
#include "dsputil.h"
#include "libavutil/crc.h"
#include <stdint.h> #include <stdint.h>
...@@ -154,6 +156,7 @@ typedef struct { ...@@ -154,6 +156,7 @@ typedef struct {
uint32_t samples; ///< number of samples, 0xFFFFFFFF if unknown uint32_t samples; ///< number of samples, 0xFFFFFFFF if unknown
int resolution; ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit int resolution; ///< 000 = 8-bit; 001 = 16-bit; 010 = 24-bit; 011 = 32-bit
int floating; ///< 1 = IEEE 32-bit floating-point, 0 = integer int floating; ///< 1 = IEEE 32-bit floating-point, 0 = integer
int msb_first; ///< 1 = original CRC calculated on big-endian system, 0 = little-endian
int frame_length; ///< frame length for each frame (last frame may differ) int frame_length; ///< frame length for each frame (last frame may differ)
int ra_distance; ///< distance between RA frames (in frames, 0...255) int ra_distance; ///< distance between RA frames (in frames, 0...255)
enum RA_Flag ra_flag; ///< indicates where the size of ra units is stored enum RA_Flag ra_flag; ///< indicates where the size of ra units is stored
...@@ -171,6 +174,7 @@ typedef struct { ...@@ -171,6 +174,7 @@ typedef struct {
int rlslms; ///< use "Recursive Least Square-Least Mean Square" predictor: 1 = on, 0 = off int rlslms; ///< use "Recursive Least Square-Least Mean Square" predictor: 1 = on, 0 = off
int chan_config_info; ///< mapping of channels to loudspeaker locations. Unused until setting channel configuration is implemented. int chan_config_info; ///< mapping of channels to loudspeaker locations. Unused until setting channel configuration is implemented.
int *chan_pos; ///< original channel positions int *chan_pos; ///< original channel positions
int crc_enabled; ///< enable Cyclic Redundancy Checksum
} ALSSpecificConfig; } ALSSpecificConfig;
...@@ -188,6 +192,10 @@ typedef struct { ...@@ -188,6 +192,10 @@ typedef struct {
AVCodecContext *avctx; AVCodecContext *avctx;
ALSSpecificConfig sconf; ALSSpecificConfig sconf;
GetBitContext gb; GetBitContext gb;
DSPContext dsp;
const AVCRC *crc_table;
uint32_t crc_org; ///< CRC value of the original input data
uint32_t crc; ///< CRC value calculated from decoded data
unsigned int cur_frame_length; ///< length of the current frame to decode unsigned int cur_frame_length; ///< length of the current frame to decode
unsigned int frame_id; ///< the frame ID / number of the current frame unsigned int frame_id; ///< the frame ID / number of the current frame
unsigned int js_switch; ///< if true, joint-stereo decoding is enforced unsigned int js_switch; ///< if true, joint-stereo decoding is enforced
...@@ -211,6 +219,7 @@ typedef struct { ...@@ -211,6 +219,7 @@ typedef struct {
int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block int32_t *prev_raw_samples; ///< contains unshifted raw samples from the previous block
int32_t **raw_samples; ///< decoded raw samples for each channel int32_t **raw_samples; ///< decoded raw samples for each channel
int32_t *raw_buffer; ///< contains all decoded raw samples including carryover samples int32_t *raw_buffer; ///< contains all decoded raw samples including carryover samples
uint8_t *crc_buffer; ///< buffer of byte order corrected samples used for CRC check
} ALSDecContext; } ALSDecContext;
...@@ -268,7 +277,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) ...@@ -268,7 +277,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
{ {
GetBitContext gb; GetBitContext gb;
uint64_t ht_size; uint64_t ht_size;
int i, config_offset, crc_enabled; int i, config_offset;
MPEG4AudioConfig m4ac; MPEG4AudioConfig m4ac;
ALSSpecificConfig *sconf = &ctx->sconf; ALSSpecificConfig *sconf = &ctx->sconf;
AVCodecContext *avctx = ctx->avctx; AVCodecContext *avctx = ctx->avctx;
...@@ -297,7 +306,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) ...@@ -297,7 +306,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
skip_bits(&gb, 3); // skip file_type skip_bits(&gb, 3); // skip file_type
sconf->resolution = get_bits(&gb, 3); sconf->resolution = get_bits(&gb, 3);
sconf->floating = get_bits1(&gb); sconf->floating = get_bits1(&gb);
skip_bits1(&gb); // skip msb_first sconf->msb_first = get_bits1(&gb);
sconf->frame_length = get_bits(&gb, 16) + 1; sconf->frame_length = get_bits(&gb, 16) + 1;
sconf->ra_distance = get_bits(&gb, 8); sconf->ra_distance = get_bits(&gb, 8);
sconf->ra_flag = get_bits(&gb, 2); sconf->ra_flag = get_bits(&gb, 2);
...@@ -312,7 +321,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) ...@@ -312,7 +321,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
sconf->mc_coding = get_bits1(&gb); sconf->mc_coding = get_bits1(&gb);
sconf->chan_config = get_bits1(&gb); sconf->chan_config = get_bits1(&gb);
sconf->chan_sort = get_bits1(&gb); sconf->chan_sort = get_bits1(&gb);
crc_enabled = get_bits1(&gb); sconf->crc_enabled = get_bits1(&gb);
sconf->rlslms = get_bits1(&gb); sconf->rlslms = get_bits1(&gb);
skip_bits(&gb, 5); // skip 5 reserved bits skip_bits(&gb, 5); // skip 5 reserved bits
skip_bits1(&gb); // skip aux_data_enabled skip_bits1(&gb); // skip aux_data_enabled
...@@ -375,12 +384,17 @@ static av_cold int read_specific_config(ALSDecContext *ctx) ...@@ -375,12 +384,17 @@ static av_cold int read_specific_config(ALSDecContext *ctx)
skip_bits_long(&gb, ht_size); skip_bits_long(&gb, ht_size);
// skip the crc data // initialize CRC calculation
if (crc_enabled) { if (sconf->crc_enabled) {
if (get_bits_left(&gb) < 32) if (get_bits_left(&gb) < 32)
return -1; return -1;
skip_bits_long(&gb, 32); if (avctx->error_recognition >= FF_ER_CAREFUL) {
ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
ctx->crc = 0xFFFFFFFF;
ctx->crc_org = ~get_bits_long(&gb, 32);
} else
skip_bits_long(&gb, 32);
} }
...@@ -1437,6 +1451,59 @@ static int decode_frame(AVCodecContext *avctx, ...@@ -1437,6 +1451,59 @@ static int decode_frame(AVCodecContext *avctx,
INTERLEAVE_OUTPUT(32) INTERLEAVE_OUTPUT(32)
} }
// update CRC
if (sconf->crc_enabled && avctx->error_recognition >= FF_ER_CAREFUL) {
int swap = HAVE_BIGENDIAN != sconf->msb_first;
if (ctx->avctx->bits_per_raw_sample == 24) {
int32_t *src = data;
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
sample++) {
int32_t v;
if (swap)
v = bswap_32(src[sample]);
else
v = src[sample];
if (!HAVE_BIGENDIAN)
v >>= 8;
ctx->crc = av_crc(ctx->crc_table, ctx->crc, (uint8_t*)(&v), 3);
}
} else {
uint8_t *crc_source;
if (swap) {
if (ctx->avctx->bits_per_raw_sample <= 16) {
int16_t *src = (int16_t*) data;
int16_t *dest = (int16_t*) ctx->crc_buffer;
for (sample = 0;
sample < ctx->cur_frame_length * avctx->channels;
sample++)
*dest++ = bswap_16(src[sample]);
} else {
ctx->dsp.bswap_buf((uint32_t*)ctx->crc_buffer, data,
ctx->cur_frame_length * avctx->channels);
}
crc_source = ctx->crc_buffer;
} else {
crc_source = data;
}
ctx->crc = av_crc(ctx->crc_table, ctx->crc, crc_source, size);
}
// check CRC sums if this is the last frame
if (ctx->cur_frame_length != sconf->frame_length &&
ctx->crc_org != ctx->crc) {
av_log(avctx, AV_LOG_ERROR, "CRC error.\n");
}
}
bytes_read = invalid_frame ? buffer_size : bytes_read = invalid_frame ? buffer_size :
(get_bits_count(&ctx->gb) + 7) >> 3; (get_bits_count(&ctx->gb) + 7) >> 3;
...@@ -1606,6 +1673,22 @@ static av_cold int decode_init(AVCodecContext *avctx) ...@@ -1606,6 +1673,22 @@ static av_cold int decode_init(AVCodecContext *avctx)
for (c = 1; c < avctx->channels; c++) for (c = 1; c < avctx->channels; c++)
ctx->raw_samples[c] = ctx->raw_samples[c - 1] + channel_size; ctx->raw_samples[c] = ctx->raw_samples[c - 1] + channel_size;
// allocate crc buffer
if (HAVE_BIGENDIAN != sconf->msb_first && sconf->crc_enabled &&
avctx->error_recognition >= FF_ER_CAREFUL) {
ctx->crc_buffer = av_malloc(sizeof(*ctx->crc_buffer) *
ctx->cur_frame_length *
avctx->channels *
(av_get_bits_per_sample_format(avctx->sample_fmt) >> 3));
if (!ctx->crc_buffer) {
av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
decode_end(avctx);
return AVERROR(ENOMEM);
}
}
dsputil_init(&ctx->dsp, avctx);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment