summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEwald Snel <esnel@users.sourceforge.net>2002-12-15 18:02:35 +0000
committerEwald Snel <esnel@users.sourceforge.net>2002-12-15 18:02:35 +0000
commit422d666bdfc36ee4b90466fac94b1d6e2c1d3536 (patch)
tree28d055a09d7d50aba9e3c65356067f21f79dbf8e
parentc6f8b1cbf1448586796e37319d2ade785137b2c7 (diff)
downloadxine-lib-422d666bdfc36ee4b90466fac94b1d6e2c1d3536.tar.gz
xine-lib-422d666bdfc36ee4b90466fac94b1d6e2c1d3536.tar.bz2
Report broken frames
CVS patchset: 3547 CVS date: 2002/12/15 18:02:35
-rw-r--r--src/libxinevdec/cinepak.c95
1 files changed, 53 insertions, 42 deletions
diff --git a/src/libxinevdec/cinepak.c b/src/libxinevdec/cinepak.c
index 102b5a561..2d116786f 100644
--- a/src/libxinevdec/cinepak.c
+++ b/src/libxinevdec/cinepak.c
@@ -22,7 +22,7 @@
* based on overview of Cinepak algorithm and example decoder
* by Tim Ferguson: http://www.csse.monash.edu.au/~timf/
*
- * $Id: cinepak.c,v 1.23 2002/12/15 16:35:51 esnel Exp $
+ * $Id: cinepak.c,v 1.24 2002/12/15 18:02:35 esnel Exp $
*/
#include <stdlib.h>
@@ -140,8 +140,8 @@ static void cinepak_decode_codebook (cvid_codebook_t *codebook,
}
}
-static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
- int chunk_id, int size, uint8_t *data)
+static int cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
+ int chunk_id, int size, uint8_t *data)
{
uint8_t *eod = (data + size);
uint32_t flag, mask;
@@ -169,7 +169,7 @@ static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
for (x=strip->x1; x < strip->x2; x+=4) {
if ((chunk_id & 0x0100) && !(mask >>= 1)) {
if ((data + 4) > eod)
- return;
+ return -1;
flag = BE_32 (data);
data += 4;
@@ -179,7 +179,7 @@ static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
if (!(chunk_id & 0x0100) || (flag & mask)) {
if (!(chunk_id & 0x0200) && !(mask >>= 1)) {
if ((data + 4) > eod)
- return;
+ return -1;
flag = BE_32 (data);
data += 4;
@@ -188,7 +188,7 @@ static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
if ((chunk_id & 0x0200) || (~flag & mask)) {
if (data >= eod)
- return;
+ return -1;
codebook = &strip->v1_codebook[*data++];
iy[0][0] = codebook->y0; iy[0][1] = codebook->y0;
@@ -209,7 +209,7 @@ static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
} else if (flag & mask) {
if ((data + 4) > eod)
- return;
+ return -1;
codebook = &strip->v4_codebook[*data++];
iy[0][0] = codebook->y0; iy[0][1] = codebook->y1;
@@ -239,10 +239,12 @@ static void cinepak_decode_vectors (cvid_decoder_t *this, cvid_strip_t *strip,
iv[0] += 2; iv[1] += 2;
}
}
+
+ return 0;
}
-static void cinepak_decode_strip (cvid_decoder_t *this,
- cvid_strip_t *strip, uint8_t *data, int size)
+static int cinepak_decode_strip (cvid_decoder_t *this,
+ cvid_strip_t *strip, uint8_t *data, int size)
{
uint8_t *eod = (data + size);
int chunk_id, chunk_size;
@@ -250,7 +252,7 @@ static void cinepak_decode_strip (cvid_decoder_t *this,
if (strip->x1 >= this->biWidth || strip->x2 > this->biWidth ||
strip->y1 >= this->biHeight || strip->y2 > this->biHeight ||
strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
- return;
+ return -1;
while ((data + 4) <= eod) {
chunk_id = BE_16 (&data[0]);
@@ -274,21 +276,22 @@ static void cinepak_decode_strip (cvid_decoder_t *this,
case 0x3000:
case 0x3100:
case 0x3200:
- cinepak_decode_vectors (this, strip, chunk_id, chunk_size, data);
- return;
+ return cinepak_decode_vectors (this, strip, chunk_id, chunk_size, data);
}
data += chunk_size;
}
+
+ return -1;
}
-static void cinepak_decode_frame (cvid_decoder_t *this, uint8_t *data, int size) {
+static int cinepak_decode_frame (cvid_decoder_t *this, uint8_t *data, int size) {
uint8_t *eod = (data + size);
- int i, strip_size, frame_flags, num_strips;
+ int i, result, strip_size, frame_flags, num_strips;
int y0 = 0;
if (size < 10)
- return;
+ return -1;
frame_flags = data[0];
num_strips = BE_16 (&data[8]);
@@ -299,7 +302,7 @@ static void cinepak_decode_frame (cvid_decoder_t *this, uint8_t *data, int size)
for (i=0; i < num_strips; i++) {
if ((data + 12) > eod)
- break;
+ return -1;
this->strips[i].id = BE_16 (data);
this->strips[i].y1 = y0;
@@ -319,11 +322,16 @@ static void cinepak_decode_frame (cvid_decoder_t *this, uint8_t *data, int size)
sizeof(this->strips[i].v1_codebook));
}
- cinepak_decode_strip (this, &this->strips[i], data, strip_size);
+ result = cinepak_decode_strip (this, &this->strips[i], data, strip_size);
+
+ if (result != 0)
+ return result;
data += strip_size;
y0 = this->strips[i].y2;
}
+
+ return 0;
}
static void cvid_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
@@ -394,9 +402,10 @@ static void cvid_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
vo_frame_t *img;
uint8_t *dy, *du, *dv, *sy, *su, *sv;
- int y;
+ int result, y;
- cinepak_decode_frame (this, this->buf, this->size);
+ result = cinepak_decode_frame (this, this->buf, this->size);
+ result = 0;
img = this->stream->video_out->get_frame (this->stream->video_out,
this->biWidth, this->biHeight,
@@ -405,32 +414,34 @@ static void cvid_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
img->duration = this->video_step;
img->pts = buf->pts;
- img->bad_frame = 0;
-
- dy = img->base[0];
- du = img->base[1];
- dv = img->base[2];
- sy = this->img_buffer;
- su = this->img_buffer + (this->biWidth * this->biHeight);
- sv = this->img_buffer + ((this->biWidth * this->biHeight * 5) / 4);
-
- for (y=0; y < this->biHeight; y++) {
- xine_fast_memcpy (dy, sy, this->biWidth);
-
- dy += img->pitches[0];
- sy += this->biWidth;
- }
+ img->bad_frame = (result != 0);
+
+ if (result == 0) {
+ dy = img->base[0];
+ du = img->base[1];
+ dv = img->base[2];
+ sy = this->img_buffer;
+ su = this->img_buffer + (this->biWidth * this->biHeight);
+ sv = this->img_buffer + ((this->biWidth * this->biHeight * 5) / 4);
- for (y=0; y < (this->biHeight/2); y++) {
- xine_fast_memcpy (du, su, this->biWidth/2);
- xine_fast_memcpy (dv, sv, this->biWidth/2);
+ for (y=0; y < this->biHeight; y++) {
+ xine_fast_memcpy (dy, sy, this->biWidth);
+
+ dy += img->pitches[0];
+ sy += this->biWidth;
+ }
- du += img->pitches[1];
- dv += img->pitches[2];
- su += this->biWidth/2;
- sv += this->biWidth/2;
+ for (y=0; y < (this->biHeight/2); y++) {
+ xine_fast_memcpy (du, su, this->biWidth/2);
+ xine_fast_memcpy (dv, sv, this->biWidth/2);
+
+ du += img->pitches[1];
+ dv += img->pitches[2];
+ su += this->biWidth/2;
+ sv += this->biWidth/2;
+ }
}
-
+
img->draw(img, this->stream);
img->free(img);