summaryrefslogtreecommitdiff
path: root/ffmpeg/libavcodec/svq3.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavcodec/svq3.c')
-rw-r--r--ffmpeg/libavcodec/svq3.c83
1 files changed, 54 insertions, 29 deletions
diff --git a/ffmpeg/libavcodec/svq3.c b/ffmpeg/libavcodec/svq3.c
index 53c4d32..e1d2588 100644
--- a/ffmpeg/libavcodec/svq3.c
+++ b/ffmpeg/libavcodec/svq3.c
@@ -39,6 +39,8 @@
* correctly decodes this file:
* http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
*/
+
+#include "libavutil/attributes.h"
#include "internal.h"
#include "avcodec.h"
#include "mpegvideo.h"
@@ -105,6 +107,13 @@ static const uint8_t svq3_scan[16] = {
0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
};
+static const uint8_t luma_dc_zigzag_scan[16] = {
+ 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+ 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
+ 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
+ 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
+};
+
static const uint8_t svq3_pred_0[25][2] = {
{ 0, 0 },
{ 1, 0 }, { 0, 1 },
@@ -149,6 +158,8 @@ static const uint32_t svq3_dequant_coeff[32] = {
61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
};
+static int svq3_decode_end(AVCodecContext *avctx);
+
void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
{
const int qmul = svq3_dequant_coeff[qp];
@@ -308,7 +319,8 @@ static inline void svq3_mc_dir_part(SVQ3Context *s,
src = pic->f.data[0] + mx + my * h->linesize;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->linesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+ h->linesize, h->linesize,
width + 1, height + 1,
mx, my, s->h_edge_pos, s->v_edge_pos);
src = h->edge_emu_buffer;
@@ -334,7 +346,8 @@ static inline void svq3_mc_dir_part(SVQ3Context *s,
src = pic->f.data[i] + mx + my * h->uvlinesize;
if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src, h->uvlinesize,
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src,
+ h->uvlinesize, h->uvlinesize,
width + 1, height + 1,
mx, my, (s->h_edge_pos >> 1),
s->v_edge_pos >> 1);
@@ -648,9 +661,9 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
dir = i_mb_type_info[mb_type - 8].pred_mode;
dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
- if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) == -1) {
- av_log(h->avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n");
- return -1;
+ if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) {
+ av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n");
+ return h->intra16x16_pred_mode;
}
cbp = i_mb_type_info[mb_type - 8].cbp;
@@ -792,8 +805,8 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
header ^ s->watermark_key);
}
if (length > 0) {
- memcpy((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
- &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
+ memmove((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
+ &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
}
skip_bits_long(&h->gb, 0);
}
@@ -827,8 +840,8 @@ static int svq3_decode_slice_header(AVCodecContext *avctx)
skip_bits1(&h->gb);
skip_bits(&h->gb, 2);
- while (get_bits1(&h->gb))
- skip_bits(&h->gb, 8);
+ if (skip_1stop_8data_bits(&h->gb) < 0)
+ return AVERROR_INVALIDDATA;
/* reset intra predictors and invalidate motion vector references */
if (h->mb_x > 0) {
@@ -857,19 +870,18 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
unsigned char *extradata_end;
unsigned int size;
int marker_found = 0;
+ int ret;
s->cur_pic = av_mallocz(sizeof(*s->cur_pic));
s->last_pic = av_mallocz(sizeof(*s->last_pic));
s->next_pic = av_mallocz(sizeof(*s->next_pic));
if (!s->next_pic || !s->last_pic || !s->cur_pic) {
- av_freep(&s->cur_pic);
- av_freep(&s->last_pic);
- av_freep(&s->next_pic);
- return AVERROR(ENOMEM);
+ ret = AVERROR(ENOMEM);
+ goto fail;
}
- if (ff_h264_decode_init(avctx) < 0)
- return -1;
+ if ((ret = ff_h264_decode_init(avctx)) < 0)
+ goto fail;
ff_hpeldsp_init(&s->hdsp, avctx->flags);
h->flags = avctx->flags;
@@ -904,8 +916,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
int frame_size_code;
size = AV_RB32(&extradata[4]);
- if (size > extradata_end - extradata - 8)
- return AVERROR_INVALIDDATA;
+ if (size > extradata_end - extradata - 8) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
init_get_bits(&gb, extradata + 8, size * 8);
/* 'frame size code' and optional 'width, height' */
@@ -959,8 +973,10 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
/* unknown field */
skip_bits1(&gb);
- while (get_bits1(&gb))
- skip_bits(&gb, 8);
+ if (skip_1stop_8data_bits(&gb) < 0) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
s->unknown_flag = get_bits1(&gb);
avctx->has_b_frames = !h->low_delay;
@@ -977,8 +993,11 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
int offset = get_bits_count(&gb) + 7 >> 3;
uint8_t *buf;
- if (watermark_height <= 0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
- return -1;
+ if (watermark_height <= 0 ||
+ (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) {
+ ret = -1;
+ goto fail;
+ }
buf = av_malloc(buf_len);
av_log(avctx, AV_LOG_DEBUG, "watermark size: %dx%d\n",
@@ -991,7 +1010,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR,
"could not uncompress watermark logo\n");
av_free(buf);
- return -1;
+ ret = -1;
+ goto fail;
}
s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
s->watermark_key = s->watermark_key << 16 | s->watermark_key;
@@ -1001,7 +1021,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
#else
av_log(avctx, AV_LOG_ERROR,
"this svq3 file contains watermark which need zlib support compiled in\n");
- return -1;
+ ret = -1;
+ goto fail;
#endif
}
}
@@ -1016,12 +1037,15 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx)
s->h_edge_pos = h->mb_width * 16;
s->v_edge_pos = h->mb_height * 16;
- if (ff_h264_alloc_tables(h) < 0) {
+ if ((ret = ff_h264_alloc_tables(h)) < 0) {
av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
- return AVERROR(ENOMEM);
+ goto fail;
}
return 0;
+fail:
+ svq3_decode_end(avctx);
+ return ret;
}
static void free_picture(AVCodecContext *avctx, Picture *pic)
@@ -1113,8 +1137,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
h->mb_x = h->mb_y = h->mb_xy = 0;
if (s->watermark_key) {
- av_fast_malloc(&s->buf, &s->buf_size,
- buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
+ av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size);
if (!s->buf)
return AVERROR(ENOMEM);
memcpy(s->buf, avpkt->data, buf_size);
@@ -1164,6 +1187,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
if (h->pict_type != AV_PICTURE_TYPE_I) {
if (!s->last_pic->f.data[0]) {
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+ av_frame_unref(s->last_pic);
ret = get_buffer(avctx, s->last_pic);
if (ret < 0)
return ret;
@@ -1176,6 +1200,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f.data[0]) {
av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+ av_frame_unref(s->next_pic);
ret = get_buffer(avctx, s->next_pic);
if (ret < 0)
return ret;
@@ -1310,7 +1335,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data,
return buf_size;
}
-static int svq3_decode_end(AVCodecContext *avctx)
+static av_cold int svq3_decode_end(AVCodecContext *avctx)
{
SVQ3Context *s = avctx->priv_data;
H264Context *h = &s->h;
@@ -1335,6 +1360,7 @@ static int svq3_decode_end(AVCodecContext *avctx)
AVCodec ff_svq3_decoder = {
.name = "svq3",
+ .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_SVQ3,
.priv_data_size = sizeof(SVQ3Context),
@@ -1344,7 +1370,6 @@ AVCodec ff_svq3_decoder = {
.capabilities = CODEC_CAP_DRAW_HORIZ_BAND |
CODEC_CAP_DR1 |
CODEC_CAP_DELAY,
- .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P,
AV_PIX_FMT_NONE},
};