Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
/*
* 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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment