#include "avcodec.h"
#include "dsputil.h"
-#define PALETTE_COUNT 256
-
-#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
-#define BE_32(x) ((((uint8_t*)(x))[0] << 24) | \
- (((uint8_t*)(x))[1] << 16) | \
- (((uint8_t*)(x))[2] << 8) | \
- ((uint8_t*)(x))[3])
typedef struct {
uint8_t y0, y1, y2, y3;
AVCodecContext *avctx;
DSPContext dsp;
AVFrame frame;
- AVFrame prev_frame;
unsigned char *data;
int size;
- unsigned char palette[PALETTE_COUNT * 4];
+ int width, height;
+
int palette_video;
cvid_strip_t strips[MAX_STRIPS];
uint8_t *eod = (data + size);
uint32_t flag, mask;
cvid_codebook_t *codebook;
- unsigned int i, j, x, y;
+ unsigned int x, y;
uint32_t iy[4];
uint32_t iu[2];
uint32_t iv[2];
s->frame.data[2][iv[0]] = codebook->v;
}
- s->frame.data[0][iy[0] + 2] = codebook->y0;
- s->frame.data[0][iy[0] + 3] = codebook->y0;
- s->frame.data[0][iy[1] + 2] = codebook->y0;
- s->frame.data[0][iy[1] + 3] = codebook->y0;
+ s->frame.data[0][iy[0] + 2] = codebook->y1;
+ s->frame.data[0][iy[0] + 3] = codebook->y1;
+ s->frame.data[0][iy[1] + 2] = codebook->y1;
+ s->frame.data[0][iy[1] + 3] = codebook->y1;
if (!s->palette_video) {
s->frame.data[1][iu[0] + 1] = codebook->u;
s->frame.data[2][iv[0] + 1] = codebook->v;
}
- s->frame.data[0][iy[2] + 0] = codebook->y0;
- s->frame.data[0][iy[2] + 1] = codebook->y0;
- s->frame.data[0][iy[3] + 0] = codebook->y0;
- s->frame.data[0][iy[3] + 1] = codebook->y0;
+ s->frame.data[0][iy[2] + 0] = codebook->y2;
+ s->frame.data[0][iy[2] + 1] = codebook->y2;
+ s->frame.data[0][iy[3] + 0] = codebook->y2;
+ s->frame.data[0][iy[3] + 1] = codebook->y2;
if (!s->palette_video) {
s->frame.data[1][iu[1]] = codebook->u;
s->frame.data[2][iv[1]] = codebook->v;
}
- s->frame.data[0][iy[2] + 2] = codebook->y0;
- s->frame.data[0][iy[2] + 3] = codebook->y0;
- s->frame.data[0][iy[3] + 2] = codebook->y0;
- s->frame.data[0][iy[3] + 3] = codebook->y0;
+ s->frame.data[0][iy[2] + 2] = codebook->y3;
+ s->frame.data[0][iy[2] + 3] = codebook->y3;
+ s->frame.data[0][iy[3] + 2] = codebook->y3;
+ s->frame.data[0][iy[3] + 3] = codebook->y3;
if (!s->palette_video) {
s->frame.data[1][iu[1] + 1] = codebook->u;
s->frame.data[2][iv[1] + 1] = codebook->v;
}
}
- } else {
- /* copy from the previous frame */
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- s->frame.data[0][iy[i] + j] =
- s->prev_frame.data[0][iy[i] + j];
- }
- }
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 2; j++) {
- s->frame.data[1][iu[i] + j] =
- s->prev_frame.data[1][iu[i] + j];
- s->frame.data[2][iv[i] + j] =
- s->prev_frame.data[2][iv[i] + j];
- }
- }
}
iy[0] += 4; iy[1] += 4;
int chunk_id, chunk_size;
/* coordinate sanity checks */
- if (strip->x1 >= s->avctx->width || strip->x2 > s->avctx->width ||
- strip->y1 >= s->avctx->height || strip->y2 > s->avctx->height ||
- strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
+ if (strip->x1 >= s->width || strip->x2 > s->width ||
+ strip->y1 >= s->height || strip->y2 > s->height ||
+ strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
return -1;
while ((data + 4) <= eod) {
static int cinepak_decode_init(AVCodecContext *avctx)
{
CinepakContext *s = (CinepakContext *)avctx->priv_data;
-/*
- int i;
- unsigned char r, g, b;
- unsigned char *raw_palette;
- unsigned int *palette32;
-*/
s->avctx = avctx;
+ s->width = (avctx->width + 3) & ~3;
+ s->height = (avctx->height + 3) & ~3;
+
+ // check for paletted data
+ if ((avctx->palctrl == NULL) || (avctx->bits_per_sample == 40)) {
+ s->palette_video = 0;
+ avctx->pix_fmt = PIX_FMT_YUV420P;
+ } else {
+ s->palette_video = 1;
+ avctx->pix_fmt = PIX_FMT_PAL8;
+ }
-// check for paletted data
-s->palette_video = 0;
-
-
- avctx->pix_fmt = PIX_FMT_YUV420P;
avctx->has_b_frames = 0;
dsputil_init(&s->dsp, avctx);
- s->frame.data[0] = s->prev_frame.data[0] = NULL;
+ s->frame.data[0] = NULL;
return 0;
}
s->data = buf;
s->size = buf_size;
- if (avctx->get_buffer(avctx, &s->frame)) {
- printf (" Cinepak: get_buffer() failed\n");
+ s->frame.reference = 1;
+ s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
+ FF_BUFFER_HINTS_REUSABLE;
+ if (avctx->reget_buffer(avctx, &s->frame)) {
+ av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
cinepak_decode(s);
- if (s->prev_frame.data[0])
- avctx->release_buffer(avctx, &s->prev_frame);
-
- /* shuffle frames */
- s->prev_frame = s->frame;
+ if (s->palette_video) {
+ memcpy (s->frame.data[1], avctx->palctrl->palette, AVPALETTE_SIZE);
+ if (avctx->palctrl->palette_changed) {
+ s->frame.palette_has_changed = 1;
+ avctx->palctrl->palette_changed = 0;
+ } else
+ s->frame.palette_has_changed = 0;
+ }
*data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame;
{
CinepakContext *s = (CinepakContext *)avctx->priv_data;
- if (s->prev_frame.data[0])
- avctx->release_buffer(avctx, &s->prev_frame);
+ if (s->frame.data[0])
+ avctx->release_buffer(avctx, &s->frame);
return 0;
}