Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/qpeg.c')
-rw-r--r--libavcodec/qpeg.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 1ee764bb99..4d8781e762 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -2,20 +2,20 @@
* QPEG codec
* Copyright (c) 2004 Konstantin Shishkov
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -29,8 +29,7 @@
typedef struct QpegContext{
AVCodecContext *avctx;
- AVFrame pic;
- uint8_t *refdata;
+ AVFrame pic, ref;
uint32_t pal[256];
GetByteContext buffer;
} QpegContext;
@@ -120,9 +119,12 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
int filled = 0;
int orig_height;
+ if(!refdata)
+ refdata= dst;
+
/* copy prev frame */
for(i = 0; i < height; i++)
- memcpy(refdata + (i * width), dst + (i * stride), width);
+ memcpy(dst + (i * stride), refdata + (i * stride), width);
orig_height = height;
height--;
@@ -133,7 +135,7 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
if(delta) {
/* motion compensation */
- while((code & 0xF0) == 0xF0) {
+ while(bytestream2_get_bytes_left(&qctx->buffer) > 0 && (code & 0xF0) == 0xF0) {
if(delta == 1) {
int me_idx;
int me_w, me_h, me_x, me_y;
@@ -166,10 +168,10 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
me_x, me_y, me_w, me_h, filled, height);
else {
/* do motion compensation */
- me_plane = refdata + (filled + me_x) + (height - me_y) * width;
+ me_plane = refdata + (filled + me_x) + (height - me_y) * stride;
for(j = 0; j < me_h; j++) {
for(i = 0; i < me_w; i++)
- dst[filled + i - (j * stride)] = me_plane[i - (j * width)];
+ dst[filled + i - (j * stride)] = me_plane[i - (j * stride)];
}
}
}
@@ -190,17 +192,24 @@ static void qpeg_decode_inter(QpegContext *qctx, uint8_t *dst,
filled = 0;
dst -= stride;
height--;
+ if(height < 0)
+ break;
}
}
} else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */
code &= 0x1F;
+ if(code + 1 > bytestream2_get_bytes_left(&qctx->buffer))
+ break;
+
for(i = 0; i <= code; i++) {
dst[filled++] = bytestream2_get_byte(&qctx->buffer);
if(filled >= width) {
filled = 0;
dst -= stride;
height--;
+ if(height < 0)
+ break;
}
}
} else if(code >= 0x80) { /* skip code: 0x80..0xBF */
@@ -245,7 +254,8 @@ static int decode_frame(AVCodecContext *avctx,
{
uint8_t ctable[128];
QpegContext * const a = avctx->priv_data;
- AVFrame * const p = &a->pic;
+ AVFrame * p = &a->pic;
+ AVFrame * ref= &a->ref;
uint8_t* outdata;
int delta;
const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
@@ -256,9 +266,14 @@ static int decode_frame(AVCodecContext *avctx,
}
bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
- p->reference = 3;
- if (avctx->reget_buffer(avctx, p) < 0) {
- av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+
+ if(ref->data[0])
+ avctx->release_buffer(avctx, ref);
+ FFSWAP(AVFrame, *ref, *p);
+
+ p->reference= 3;
+ if(avctx->get_buffer(avctx, p) < 0){
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
}
outdata = a->pic.data[0];
@@ -270,7 +285,7 @@ static int decode_frame(AVCodecContext *avctx,
if(delta == 0x10) {
qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height);
} else {
- qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->refdata);
+ qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->ref.data[0]);
}
/* make the palette available on the way out */
@@ -289,9 +304,10 @@ static int decode_frame(AVCodecContext *avctx,
static av_cold int decode_init(AVCodecContext *avctx){
QpegContext * const a = avctx->priv_data;
+ avcodec_get_frame_defaults(&a->pic);
+ avcodec_get_frame_defaults(&a->ref);
a->avctx = avctx;
avctx->pix_fmt= AV_PIX_FMT_PAL8;
- a->refdata = av_malloc(avctx->width * avctx->height);
return 0;
}
@@ -299,11 +315,13 @@ static av_cold int decode_init(AVCodecContext *avctx){
static av_cold int decode_end(AVCodecContext *avctx){
QpegContext * const a = avctx->priv_data;
AVFrame * const p = &a->pic;
+ AVFrame * const ref= &a->ref;
if(p->data[0])
avctx->release_buffer(avctx, p);
+ if(ref->data[0])
+ avctx->release_buffer(avctx, ref);
- av_free(a->refdata);
return 0;
}