Commit 3abe5fbd authored by Aurelien Jacobs's avatar Aurelien Jacobs

improve CRC API

 - don't export any global var
 - provide either generated or hardcoded tables

Originally committed as revision 11409 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 83a0d387
......@@ -132,6 +132,7 @@ show_help(){
echo " --disable-ffserver disable ffserver build"
echo " --disable-ffplay disable ffplay build"
echo " --enable-small optimize for size instead of speed"
echo " --enable-hardcoded-tables use hardcoded tables instead of runtime generation"
echo " --enable-memalign-hack emulate memalign, interferes with memory debuggers"
echo " --disable-encoder=NAME disables encoder NAME"
echo " --enable-encoder=NAME enables encoder NAME"
......@@ -629,6 +630,7 @@ CONFIG_LIST="
gpl
gprof
gray
hardcoded_tables
ipv6
liba52
liba52bin
......
......@@ -1110,7 +1110,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
/* check for crc mismatch */
if(avctx->error_resilience > 0) {
if(av_crc(av_crc8005, 0, &buf[2], s->frame_size-2)) {
if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) {
av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
return -1;
}
......
......@@ -1141,13 +1141,16 @@ static int output_frame_end(AC3EncodeContext *s)
/* Now we must compute both crcs : this is not so easy for crc1
because it is at the beginning of the data... */
frame_size_58 = (frame_size >> 1) + (frame_size >> 3);
crc1 = bswap_16(av_crc(av_crc8005, 0, frame + 4, 2 * frame_size_58 - 4));
crc1 = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0,
frame + 4, 2 * frame_size_58 - 4));
/* XXX: could precompute crc_inv */
crc_inv = pow_poly((CRC16_POLY >> 1), (16 * frame_size_58) - 16, CRC16_POLY);
crc1 = mul_poly(crc_inv, crc1, CRC16_POLY);
AV_WB16(frame+2,crc1);
crc2 = bswap_16(av_crc(av_crc8005, 0, frame + 2 * frame_size_58, (frame_size - frame_size_58) * 2 - 2));
crc2 = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0,
frame + 2 * frame_size_58,
(frame_size - frame_size_58) * 2 - 2));
AV_WB16(frame+2*frame_size-2,crc2);
// printf("n=%d frame_size=%d\n", n, frame_size);
......
......@@ -558,7 +558,8 @@ static int decode_frame(FLACContext *s, int alloc_data_size)
}
skip_bits(&s->gb, 8);
crc8= av_crc(av_crc07, 0, s->gb.buffer, get_bits_count(&s->gb)/8);
crc8 = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0,
s->gb.buffer, get_bits_count(&s->gb)/8);
if(crc8){
av_log(s->avctx, AV_LOG_ERROR, "header crc mismatch crc=%2X\n", crc8);
return -1;
......
......@@ -1283,7 +1283,8 @@ static void output_frame_header(FlacEncodeContext *s)
put_bits(&s->pb, 16, s->sr_code[1]);
}
flush_put_bits(&s->pb);
crc = av_crc(av_crc07, 0, s->pb.buf, put_bits_count(&s->pb)>>3);
crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0,
s->pb.buf, put_bits_count(&s->pb)>>3);
put_bits(&s->pb, 8, crc);
}
......@@ -1425,7 +1426,8 @@ static void output_frame_footer(FlacEncodeContext *s)
{
int crc;
flush_put_bits(&s->pb);
crc = bswap_16(av_crc(av_crc8005, 0, s->pb.buf, put_bits_count(&s->pb)>>3));
crc = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0,
s->pb.buf, put_bits_count(&s->pb)>>3));
put_bits(&s->pb, 16, crc);
flush_put_bits(&s->pb);
}
......
......@@ -1247,17 +1247,6 @@ unsigned avcodec_build( void )
return LIBAVCODEC_BUILD;
}
static void init_crcs(void){
#if LIBAVUTIL_VERSION_INT < (50<<16)
av_crc04C11DB7= av_mallocz_static(sizeof(AVCRC) * 257);
av_crc8005 = av_mallocz_static(sizeof(AVCRC) * 257);
av_crc07 = av_mallocz_static(sizeof(AVCRC) * 257);
#endif
av_crc_init(av_crc04C11DB7, 0, 32, AV_CRC_32_IEEE, sizeof(AVCRC)*257);
av_crc_init(av_crc8005 , 0, 16, AV_CRC_16 , sizeof(AVCRC)*257);
av_crc_init(av_crc07 , 0, 8, AV_CRC_8_ATM , sizeof(AVCRC)*257);
}
void avcodec_init(void)
{
static int inited = 0;
......@@ -1267,7 +1256,6 @@ void avcodec_init(void)
inited = 1;
dsputil_static_init();
init_crcs();
}
void avcodec_flush_buffers(AVCodecContext *avctx)
......
......@@ -318,7 +318,7 @@ static void fill_buffer(ByteIOContext *s)
}
unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, unsigned int len){
return av_crc(av_crc04C11DB7, checksum, buf, len);
return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
}
unsigned long get_checksum(ByteIOContext *s){
......
......@@ -262,7 +262,8 @@ static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
tss->end_of_section_reached = 1;
if (!tss->check_crc ||
av_crc(av_crc04C11DB7, -1, tss->section_buf, tss->section_h_size) == 0)
av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
tss->section_buf, tss->section_h_size) == 0)
tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
}
}
......
......@@ -43,7 +43,7 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len)
unsigned char *q;
int first, b, len1, left;
crc = bswap_32(av_crc(av_crc04C11DB7, -1, buf, len - 4));
crc = bswap_32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, buf, len - 4));
buf[len - 4] = (crc >> 24) & 0xff;
buf[len - 3] = (crc >> 16) & 0xff;
buf[len - 2] = (crc >> 8) & 0xff;
......
......@@ -21,16 +21,21 @@
#include "common.h"
#include "crc.h"
#if LIBAVUTIL_VERSION_INT < (50<<16)
AVCRC *av_crcEDB88320;
AVCRC *av_crc04C11DB7;
AVCRC *av_crc8005 ;
AVCRC *av_crc07 ;
#ifdef CONFIG_HARDCODED_TABLES
#include "crc_data.h"
#else
AVCRC av_crcEDB88320[257];
AVCRC av_crc04C11DB7[257];
AVCRC av_crc8005 [257];
AVCRC av_crc07 [257];
static struct {
uint8_t le;
uint8_t bits;
uint32_t poly;
} av_crc_table_params[AV_CRC_MAX] = {
[AV_CRC_8_ATM] = { 0, 8, 0x07 },
[AV_CRC_16_ANSI] = { 0, 16, 0x8005 },
[AV_CRC_16_CCITT] = { 0, 16, 0x1021 },
[AV_CRC_32_IEEE] = { 0, 32, 0x04C11DB7 },
[AV_CRC_32_IEEE_LE] = { 1, 32, 0xEDB88320 },
};
static AVCRC av_crc_table[AV_CRC_MAX][257];
#endif
/**
......@@ -79,6 +84,24 @@ int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size){
return 0;
}
/**
* Get an initialized standard CRC table.
* @param crc_id ID of a standard CRC
* @return a pointer to the CRC table or NULL on failure
*/
const AVCRC *av_crc_get_table(AVCRCId crc_id){
#ifndef CONFIG_HARDCODED_TABLES
if (!av_crc_table[crc_id][sizeof(av_crc_table[crc_id])-1])
if (av_crc_init(av_crc_table[crc_id],
av_crc_table_params[crc_id].le,
av_crc_table_params[crc_id].bits,
av_crc_table_params[crc_id].poly,
sizeof(av_crc_table[crc_id])) < 0)
return NULL;
#endif
return av_crc_table[crc_id];
}
/**
* Calculate the CRC of a block
* @param crc CRC of previous blocks if any or initial value for CRC.
......@@ -110,18 +133,18 @@ uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t le
main(void){
uint8_t buf[1999];
int i;
int p[4][4]={{1, 32, AV_CRC_32_IEEE_LE, 0x3D5CDD04},
{0, 32, AV_CRC_32_IEEE , 0xC0F5BAE0},
{0, 16, AV_CRC_16 , 0x1FBB },
{0, 8, AV_CRC_8_ATM , 0xE3 },};
AVCRC ctx[1 ? 1024:257];
int p[4][3]={{AV_CRC_32_IEEE_LE, 0xEDB88320, 0x3D5CDD04},
{AV_CRC_32_IEEE , 0x04C11DB7, 0xC0F5BAE0},
{AV_CRC_16_ANSI , 0x8005, 0x1FBB },
{AV_CRC_8_ATM , 0x07, 0xE3 },};
const AVCRC *ctx;
for(i=0; i<sizeof(buf); i++)
buf[i]= i+i*i;
for(i=0; i<4; i++){
av_crc_init(ctx, p[i][0], p[i][1], p[i][2], sizeof(ctx));
printf("crc %08X =%X\n", p[i][2], av_crc(ctx, 0, buf, sizeof(buf)));
ctx = av_crc_get_table(p[i][0]);
printf("crc %08X =%X\n", p[i][1], av_crc(ctx, 0, buf, sizeof(buf)));
}
}
#endif
......@@ -26,26 +26,17 @@
typedef uint32_t AVCRC;
#define AV_CRC_8_ATM 0x07
#define AV_CRC_16 0x8005
#define AV_CRC_16_CCITT 0x1021
#define AV_CRC_32_IEEE 0x04C11DB7L
//! reversed bitorder version of AV_CRC_32_IEEE
#define AV_CRC_32_IEEE_LE 0xEDB88320L
#if LIBAVUTIL_VERSION_INT < (50<<16)
extern AVCRC *av_crcEDB88320;
extern AVCRC *av_crc04C11DB7;
extern AVCRC *av_crc8005 ;
extern AVCRC *av_crc07 ;
#else
extern AVCRC av_crcEDB88320[];
extern AVCRC av_crc04C11DB7[];
extern AVCRC av_crc8005 [];
extern AVCRC av_crc07 [];
#endif
typedef enum {
AV_CRC_8_ATM,
AV_CRC_16_ANSI,
AV_CRC_16_CCITT,
AV_CRC_32_IEEE,
AV_CRC_32_IEEE_LE, /*< reversed bitorder version of AV_CRC_32_IEEE */
AV_CRC_MAX, /*< not part of public API! don't use outside lavu */
}AVCRCId;
int av_crc_init(AVCRC *ctx, int le, int bits, uint32_t poly, int ctx_size);
const AVCRC *av_crc_get_table(AVCRCId crc_id);
uint32_t av_crc(const AVCRC *ctx, uint32_t start_crc, const uint8_t *buffer, size_t length);
#endif /* FFMPEG_CRC_H */
......
This diff is collapsed.
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