X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Frpza.c;h=958f103865465b2cafb7f4b7de81d6c85c744181;hb=d70fa4c4238ffa69592fffa7c817532534f303c4;hp=1cef2c3a276c7b095704c9d9b32ce8237904e0e1;hpb=e02c251e5ab001eeb010c862670de9b188008b5d;p=ffmpeg diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 1cef2c3a276..958f1038654 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -2,25 +2,26 @@ * Quicktime Video (RPZA) Video Decoder * Copyright (C) 2003 the ffmpeg project * - * This library is free software; you can redistribute it and/or + * This file is part of Libav. + * + * Libav 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 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * Libav 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 this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file rpza.c - * QT RPZA Video Decoder by Roberto Togni + * @file + * QT RPZA Video Decoder by Roberto Togni * For more information about the RPZA format, visit: * http://www.pcisys.net/~melanson/codecs/ * @@ -36,30 +37,20 @@ #include #include #include -#include -#include "common.h" +#include "libavutil/intreadwrite.h" #include "avcodec.h" -#include "dsputil.h" typedef struct RpzaContext { AVCodecContext *avctx; - DSPContext dsp; AVFrame frame; - AVFrame prev_frame; - unsigned char *buf; + const unsigned char *buf; int size; } RpzaContext; -#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]) - #define ADVANCE_BLOCK() \ { \ pixel_ptr += 4; \ @@ -90,7 +81,6 @@ static void rpza_decode_stream(RpzaContext *s) unsigned char index, idx; unsigned short ta, tb; unsigned short *pixels = (unsigned short *)s->frame.data[0]; - unsigned short *prev_pixels = (unsigned short *)s->prev_frame.data[0]; int row_ptr = 0; int pixel_ptr = 0; @@ -100,11 +90,11 @@ static void rpza_decode_stream(RpzaContext *s) /* First byte is always 0xe1. Warn if it's different */ if (s->buf[stream_ptr] != 0xe1) - av_log(s->avctx, AV_LOG_ERROR, "First chunk byte is 0x%02x instead of 0x1e\n", + av_log(s->avctx, AV_LOG_ERROR, "First chunk byte is 0x%02x instead of 0xe1\n", s->buf[stream_ptr]); /* Get chunk size, ingnoring first byte */ - chunk_size = BE_32(&s->buf[stream_ptr]) & 0x00FFFFFF; + chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; stream_ptr += 4; /* If length mismatch use size from MOV file and try to decode anyway */ @@ -114,7 +104,7 @@ static void rpza_decode_stream(RpzaContext *s) chunk_size = s->size; /* Number of 4x4 blocks in frame. */ - total_blocks = (s->avctx->width * s->avctx->height) / (4 * 4); + total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); /* Process chunk data */ while (stream_ptr < chunk_size) { @@ -127,8 +117,8 @@ static void rpza_decode_stream(RpzaContext *s) colorA = (opcode << 8) | (s->buf[stream_ptr++]); opcode = 0; if ((s->buf[stream_ptr] & 0x80) != 0) { - /* Must behave as opcode 110xxxxx, using colorA computed - * above. Use fake opcode 0x20 to enter switch block at + /* Must behave as opcode 110xxxxx, using colorA computed + * above. Use fake opcode 0x20 to enter switch block at * the right place */ opcode = 0x20; n_blocks = 1; @@ -140,23 +130,13 @@ static void rpza_decode_stream(RpzaContext *s) /* Skip blocks */ case 0x80: while (n_blocks--) { - if (!s->avctx->cr_available) { - block_ptr = row_ptr + pixel_ptr; - for (pixel_y = 0; pixel_y < 4; pixel_y++) { - for (pixel_x = 0; pixel_x < 4; pixel_x++){ - pixels[block_ptr] = prev_pixels[block_ptr]; - block_ptr++; - } - block_ptr += row_inc; - } - } ADVANCE_BLOCK(); } break; /* Fill blocks with one color */ case 0xa0: - colorA = BE_16 (&s->buf[stream_ptr]); + colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; @@ -173,10 +153,10 @@ static void rpza_decode_stream(RpzaContext *s) /* Fill blocks with 4 colors */ case 0xc0: - colorA = BE_16 (&s->buf[stream_ptr]); + colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; case 0x20: - colorB = BE_16 (&s->buf[stream_ptr]); + colorB = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; /* sort out the colors */ @@ -225,7 +205,7 @@ static void rpza_decode_stream(RpzaContext *s) for (pixel_x = 0; pixel_x < 4; pixel_x++){ /* We already have color of upper left pixel */ if ((pixel_y != 0) || (pixel_x !=0)) { - colorA = BE_16 (&s->buf[stream_ptr]); + colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; } pixels[block_ptr] = colorA; @@ -246,58 +226,38 @@ static void rpza_decode_stream(RpzaContext *s) } } -static int rpza_decode_init(AVCodecContext *avctx) +static av_cold int rpza_decode_init(AVCodecContext *avctx) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; + RpzaContext *s = avctx->priv_data; s->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; - 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; } static int rpza_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + AVPacket *avpkt) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; - - /* no supplementary picture */ - if (buf_size == 0) - return 0; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + RpzaContext *s = avctx->priv_data; s->buf = buf; s->size = buf_size; s->frame.reference = 1; - s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE; - if (avctx->cr_available) - s->frame.buffer_hints |= FF_BUFFER_HINTS_REUSABLE; - else - s->frame.buffer_hints |= FF_BUFFER_HINTS_READABLE; - if (avctx->get_buffer(avctx, &s->frame)) { - av_log(avctx, AV_LOG_ERROR, " RPZA Video: 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)) { + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } - if (s->prev_frame.data[0] &&(s->frame.linesize[0] != s->prev_frame.linesize[0])) - av_log(avctx, AV_LOG_ERROR, "Buffer linesize changed: current %u, previous %u.\n" - "Expect wrong image and/or crash!\n", - s->frame.linesize[0], s->prev_frame.linesize[0]); - rpza_decode_stream(s); - if (s->prev_frame.data[0]) - avctx->release_buffer(avctx, &s->prev_frame); - - /* shuffle frames */ - if (!avctx->cr_available) - s->prev_frame = s->frame; - *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; @@ -305,24 +265,25 @@ static int rpza_decode_frame(AVCodecContext *avctx, return buf_size; } -static int rpza_decode_end(AVCodecContext *avctx) +static av_cold int rpza_decode_end(AVCodecContext *avctx) { - RpzaContext *s = (RpzaContext *)avctx->priv_data; + RpzaContext *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; } -AVCodec rpza_decoder = { +AVCodec ff_rpza_decoder = { "rpza", - CODEC_TYPE_VIDEO, + AVMEDIA_TYPE_VIDEO, CODEC_ID_RPZA, sizeof(RpzaContext), rpza_decode_init, NULL, rpza_decode_end, rpza_decode_frame, - CODEC_CAP_DR1 | CODEC_CAP_CR, + CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("QuickTime video (RPZA)"), };