diff options
author | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2003-10-06 17:03:25 +0000 |
---|---|---|
committer | James Courtier-Dutton <jcdutton@users.sourceforge.net> | 2003-10-06 17:03:25 +0000 |
commit | 6fdf11ff4f277cb34e936fd20cbc1c95f85dfcd3 (patch) | |
tree | 466e17f31018de8a738f5ae79c5c59ee743a081f | |
parent | a0407c7861a4906f41152cf25ac3851a5a8eb6f8 (diff) | |
download | xine-lib-6fdf11ff4f277cb34e936fd20cbc1c95f85dfcd3.tar.gz xine-lib-6fdf11ff4f277cb34e936fd20cbc1c95f85dfcd3.tar.bz2 |
Implement CRC checking in liba52.
Add invalid frame_length protection.
CVS patchset: 5457
CVS date: 2003/10/06 17:03:25
-rw-r--r-- | src/liba52/Makefile.am | 1 | ||||
-rw-r--r-- | src/liba52/a52.h | 1 | ||||
-rw-r--r-- | src/liba52/crc.c | 73 | ||||
-rw-r--r-- | src/liba52/xine_decoder.c | 38 |
4 files changed, 108 insertions, 5 deletions
diff --git a/src/liba52/Makefile.am b/src/liba52/Makefile.am index ec6dfd642..cee608e1d 100644 --- a/src/liba52/Makefile.am +++ b/src/liba52/Makefile.am @@ -9,6 +9,7 @@ lib_LTLIBRARIES = xineplug_decode_a52.la xineplug_decode_a52_la_SOURCES = \ bitstream.c \ bit_allocate.c \ + crc.c \ downmix.c \ imdct.c \ parse.c \ diff --git a/src/liba52/a52.h b/src/liba52/a52.h index 9db52ccf8..12883011b 100644 --- a/src/liba52/a52.h +++ b/src/liba52/a52.h @@ -58,5 +58,6 @@ void a52_dynrng (a52_state_t * state, sample_t (* call) (sample_t, void *), void * data); int a52_block (a52_state_t * state); void a52_free (a52_state_t * state); +uint16_t crc16_block(uint8_t *data,uint32_t num_bytes); #endif /* A52_H */ diff --git a/src/liba52/crc.c b/src/liba52/crc.c new file mode 100644 index 000000000..d19a4a2e1 --- /dev/null +++ b/src/liba52/crc.c @@ -0,0 +1,73 @@ +/* + * crc.c + * + * Copyright (C) Aaron Holtzman - May 1999 + * + * This file is part of ac3dec, a free Dolby AC-3 stream decoder. + * + * ac3dec is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * ac3dec is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Make; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <inttypes.h> + +static const uint16_t crc_lut[256] = +{ + 0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011, + 0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022, + 0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072, + 0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041, + 0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2, + 0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1, + 0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1, + 0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082, + 0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192, + 0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1, + 0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1, + 0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2, + 0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151, + 0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162, + 0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132, + 0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101, + 0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312, + 0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321, + 0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371, + 0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342, + 0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1, + 0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2, + 0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2, + 0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381, + 0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291, + 0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2, + 0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2, + 0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1, + 0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252, + 0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261, + 0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231, + 0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202 +}; + +uint16_t crc16_block(uint8_t *data,uint32_t num_bytes) +{ + uint32_t i; + uint16_t state=0; + + for(i=0;i<num_bytes;i++) + state = crc_lut[data[i] ^ (state>>8)] ^ (state<<8); + + return state; +} diff --git a/src/liba52/xine_decoder.c b/src/liba52/xine_decoder.c index 651f91520..e19aa6ac3 100644 --- a/src/liba52/xine_decoder.c +++ b/src/liba52/xine_decoder.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_decoder.c,v 1.57 2003/09/15 04:02:45 jcdutton Exp $ + * $Id: xine_decoder.c,v 1.58 2003/10/06 17:03:25 jcdutton Exp $ * * stuff needed to turn liba52 into a xine decoder plugin */ @@ -199,7 +199,7 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int previe #endif if (!this->bypass_mode) { - int a52_output_flags, i; + int a52_output_flags, i,n; sample_t level = this->class->a52_level; audio_buffer_t *buf; int16_t *int_samples; @@ -271,7 +271,14 @@ static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int previe for (i = 0; i < 6; i++) { if (a52_block (this->a52_state)) { - printf ("liba52: a52_block error\n"); + printf ("liba52: a52_block error on audio channel %d\n", i); +#if 0 + for(n=0;n<2000;n++) { + printf("%02x ",this->frame_buffer[n]); + if ((n % 32) == 0) printf("\n"); + } + printf("\n"); +#endif buf->num_frames = 0; break; } @@ -385,9 +392,12 @@ static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; uint8_t *current = buf->content; + uint8_t *sync_start=current + 1; uint8_t *end = buf->content + buf->size; uint8_t byte; int32_t n; + uint16_t crc16; + uint16_t crc16_result; #ifdef LOG printf ("liba52: decode data %d bytes of type %08x, pts=%lld\n", @@ -457,6 +467,7 @@ static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { break; case 1: /* Looking for enough bytes for sync_info. */ + sync_start = current - 1; *this->frame_ptr++ = *current++; if ((this->frame_ptr - this->frame_buffer) > 16) { int a52_flags_old = this->a52_flags; @@ -467,6 +478,13 @@ static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { &this->a52_flags, &this->a52_sample_rate, &this->a52_bit_rate); + + if (this->frame_length < 80) { /* Invalid a52 frame_length */ + this->syncword = 0; + current = sync_start; + this->sync_state = 0; + break; + } #ifdef LOG printf("Frame length = %d\n",this->frame_length); #endif @@ -507,12 +525,22 @@ static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { case 2: /* Filling frame_buffer with sync_info bytes */ *this->frame_ptr++ = *current++; - this->frame_todo--; - if (this->frame_todo < 1) { + this->frame_todo--; + if (this->frame_todo < 1) { this->sync_state = 3; } else break; case 3: /* Ready for decode */ + crc16 = (uint16_t) ((this->frame_buffer[2] << 8) | this->frame_buffer[3]) ; + crc16_result = crc16_block(&this->frame_buffer[2], this->frame_length - 2) ; /* frame_length */ + if (crc16_result != 0) { /* CRC16 failed */ + printf("liba52:a52 frame failed crc16 checksum.\n"); + current = sync_start; + this->pts = 0; + this->syncword = 0; + this->sync_state = 0; + break; + } a52dec_decode_frame (this, this->pts_list[0], buf->decoder_flags & BUF_FLAG_PREVIEW); for(n=0;n<4;n++) { this->pts_list[n] = this->pts_list[n+1]; |