Commit e40f5d3c authored by Roberto Togni's avatar Roberto Togni

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