Commit e40f5d3c authored by Roberto Togni's avatar Roberto Togni
Browse files

Use reget buffer instead of copying from prev frame

Added buffer hints, replaced printf with av_log

Originally committed as revision 2723 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e0c53ac8
/*
* FLI/FLC Animation Video Decoder
* Copyright (C) 2003 the ffmpeg project
* Copyright (C) 2003, 2004 the ffmpeg project
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -60,7 +60,6 @@
typedef struct FlicDecodeContext {
AVCodecContext *avctx;
AVFrame frame;
AVFrame prev_frame;
unsigned int palette[256];
int new_palette;
......@@ -82,11 +81,11 @@ static int flic_decode_init(AVCodecContext *avctx)
} else if (s->avctx->extradata_size == 128) {
s->fli_type = LE_16(&fli_header[4]);
} else {
printf (" FLI video: expected extradata of 12 or 128 bytes\n");
av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
return -1;
}
s->frame.data[0] = s->prev_frame.data[0] = NULL;
s->frame.data[0] = NULL;
s->new_palette = 0;
return 0;
......@@ -126,18 +125,16 @@ static int flic_decode_frame(AVCodecContext *avctx,
signed char byte_run;
int pixel_skip;
int pixel_countdown;
int height_countdown;
unsigned char *pixels;
unsigned char *prev_pixels;
s->frame.reference = 1;
if (avctx->get_buffer(avctx, &s->frame) < 0) {
fprintf(stderr, " FLI: get_buffer() failed\n");
s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
if (avctx->reget_buffer(avctx, &s->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
return -1;
}
pixels = s->frame.data[0];
prev_pixels = s->prev_frame.data[0];
frame_size = LE_32(&buf[stream_ptr]);
stream_ptr += 6; /* skip the magic number */
......@@ -146,11 +143,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
frame_size -= 16;
/* if there is no data, copy previous frame */
if (frame_size == 0) {
memcpy(pixels, prev_pixels, s->frame.linesize[0] * s->avctx->height);
}
/* iterate through the chunks */
while ((frame_size > 0) && (num_chunks > 0)) {
chunk_size = LE_32(&buf[stream_ptr]);
......@@ -210,7 +202,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
case FLI_DELTA:
y_ptr = 0;
height_countdown = s->avctx->height;
compressed_lines = LE_16(&buf[stream_ptr]);
stream_ptr += 2;
while (compressed_lines > 0) {
......@@ -218,25 +209,14 @@ static int flic_decode_frame(AVCodecContext *avctx,
stream_ptr += 2;
if (line_packets < 0) {
line_packets = -line_packets;
/* height_countdown was already decremented once on
* this iteration */
height_countdown -= line_packets;
/* copy the skipped lines from the previous frame */
while (line_packets--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr],
s->avctx->width);
y_ptr += s->frame.linesize[0];
}
y_ptr += line_packets * s->frame.linesize[0];
} else {
height_countdown--;
compressed_lines--;
pixel_ptr = y_ptr;
pixel_countdown = s->avctx->width;
for (i = 0; i < line_packets; i++) {
/* account for the skip bytes */
pixel_skip = buf[stream_ptr++];
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_skip);
pixel_ptr += pixel_skip;
pixel_countdown -= pixel_skip;
byte_run = buf[stream_ptr++];
......@@ -256,36 +236,17 @@ static int flic_decode_frame(AVCodecContext *avctx,
}
}
/* copy the remaining pixels in the line from the
* previous frame */
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_countdown);
y_ptr += s->frame.linesize[0];
}
}
/* copy the remainder of the lines from the previous frame */
while (height_countdown--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
}
break;
case FLI_LC:
/* line compressed */
height_countdown = s->avctx->height;
starting_line = LE_16(&buf[stream_ptr]);
stream_ptr += 2;
/* copy from the previous frame all of the lines prior to the
* starting line */
y_ptr = 0;
height_countdown -= starting_line;
while (starting_line--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
}
y_ptr += starting_line * s->frame.linesize[0];
compressed_lines = LE_16(&buf[stream_ptr]);
stream_ptr += 2;
......@@ -297,8 +258,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
for (i = 0; i < line_packets; i++) {
/* account for the skip bytes */
pixel_skip = buf[stream_ptr++];
memcpy(&pixels[pixel_ptr],
&prev_pixels[pixel_ptr], pixel_skip);
pixel_ptr += pixel_skip;
pixel_countdown -= pixel_skip;
byte_run = buf[stream_ptr++];
......@@ -317,19 +276,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
}
}
/* copy the remainder of the line from the previous frame */
memcpy(&pixels[pixel_ptr], &prev_pixels[pixel_ptr],
pixel_countdown);
y_ptr += s->frame.linesize[0];
compressed_lines--;
height_countdown--;
}
/* copy the remainder of the lines from the previous frame */
while (height_countdown--) {
memcpy(&pixels[y_ptr], &prev_pixels[y_ptr], s->avctx->width);
y_ptr += s->frame.linesize[0];
}
break;
......@@ -357,8 +305,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
pixels[pixel_ptr++] = palette_idx1;
pixel_countdown--;
if (pixel_countdown < 0)
printf ("fli warning: pixel_countdown < 0 (%d)\n",
pixel_countdown);
av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
pixel_countdown);
}
} else { /* copy bytes if byte_run < 0 */
byte_run = -byte_run;
......@@ -367,8 +315,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
pixels[pixel_ptr++] = palette_idx1;
pixel_countdown--;
if (pixel_countdown < 0)
printf ("fli warning: pixel_countdown < 0 (%d)\n",
pixel_countdown);
av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
pixel_countdown);
}
}
}
......@@ -378,13 +326,10 @@ static int flic_decode_frame(AVCodecContext *avctx,
break;
case FLI_COPY:
/* copy the chunk (uncompressed frame) to the ghost image and
* schedule the whole frame to be updated */
/* copy the chunk (uncompressed frame) */
if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
printf(
"FLI: in chunk FLI_COPY : source data (%d bytes) bigger than" \
" image, skipping chunk\n",
chunk_size - 6);
av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
"bigger than image, skipping chunk\n", chunk_size - 6);
stream_ptr += chunk_size - 6;
} else {
for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
......@@ -402,7 +347,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
break;
default:
printf ("FLI: Unrecognized chunk type: %d\n", chunk_type);
av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
break;
}
......@@ -413,9 +358,8 @@ static int flic_decode_frame(AVCodecContext *avctx,
/* by the end of the chunk, the stream ptr should equal the frame
* size (minus 1, possibly); if it doesn't, issue a warning */
if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
printf (" warning: processed FLI chunk where chunk size = %d\n" \
" and final chunk ptr = %d\n",
buf_size, stream_ptr);
av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
"and final chunk ptr = %d\n", buf_size, stream_ptr);
/* make the palette available on the way out */
// if (s->new_palette) {
......@@ -425,12 +369,6 @@ static int flic_decode_frame(AVCodecContext *avctx,
s->new_palette = 0;
}
if (s->prev_frame.data[0])
avctx->release_buffer(avctx, &s->prev_frame);
/* shuffle frames */
s->prev_frame = s->frame;
*data_size=sizeof(AVFrame);
*(AVFrame*)data = s->frame;
......@@ -441,8 +379,8 @@ static int flic_decode_end(AVCodecContext *avctx)
{
FlicDecodeContext *s = 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;
}
......
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