aboutsummaryrefslogtreecommitdiff
path: root/lib/ffmpeg/libavcodec/eamad.c
diff options
context:
space:
mode:
authorelupus <elupus@xbmc.org>2012-03-25 23:27:29 +0200
committerelupus <elupus@xbmc.org>2012-03-31 16:28:00 +0200
commit2836f95ad7d9425fc27c2de62b5c51e7829032f6 (patch)
tree158a931d0795a3c9d9e21294ac9f1fa63e03f17f /lib/ffmpeg/libavcodec/eamad.c
parent8a0ce9e337267786236cba4f68d1db93bd28c3ef (diff)
Update ffmpeg to n0.10.2 (f139838d6473c7b5152178f602cb953a824c2ff9)
xbmc ffmpeg 05f8b5549c5e20cf9a417069838edd6841d7bd40
Diffstat (limited to 'lib/ffmpeg/libavcodec/eamad.c')
-rw-r--r--lib/ffmpeg/libavcodec/eamad.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/lib/ffmpeg/libavcodec/eamad.c b/lib/ffmpeg/libavcodec/eamad.c
index 1dd3b79755..40fdb37670 100644
--- a/lib/ffmpeg/libavcodec/eamad.c
+++ b/lib/ffmpeg/libavcodec/eamad.c
@@ -22,9 +22,9 @@
/**
* @file
* Electronic Arts Madcow Video Decoder
- * by Peter Ross <pross@xvid.org>
+ * @author Peter Ross <pross@xvid.org>
*
- * Technical details here:
+ * @see technical details at
* http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD
*/
@@ -34,7 +34,7 @@
#include "aandcttab.h"
#include "mpeg12.h"
#include "mpeg12data.h"
-#include "libavcore/imgutils.h"
+#include "libavutil/imgutils.h"
#define EA_PREAMBLE_SIZE 8
#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */
@@ -85,15 +85,21 @@ static inline void comp_block(MadContext *t, int mb_x, int mb_y,
{
MpegEncContext *s = &t->s;
if (j < 4) {
+ unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
+ if (offset >= (s->height - 7) * t->last_frame.linesize[0] - 7)
+ return;
comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
t->frame.linesize[0],
- t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x,
+ t->last_frame.data[0] + offset,
t->last_frame.linesize[0], add);
} else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) {
int index = j - 3;
+ unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2);
+ if (offset >= (s->height/2 - 7) * t->last_frame.linesize[index] - 7)
+ return;
comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8,
t->frame.linesize[index],
- t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2),
+ t->last_frame.data[index] + offset,
t->last_frame.linesize[index], add);
}
}
@@ -113,7 +119,7 @@ static inline void idct_put(MadContext *t, DCTELEM *block, int mb_x, int mb_y, i
}
}
-static inline void decode_block_intra(MadContext * t, DCTELEM * block)
+static inline int decode_block_intra(MadContext * t, DCTELEM * block)
{
MpegEncContext *s = &t->s;
int level, i, j, run;
@@ -164,13 +170,14 @@ static inline void decode_block_intra(MadContext * t, DCTELEM * block)
}
if (i > 63) {
av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return;
+ return -1;
}
block[j] = level;
}
CLOSE_READER(re, &s->gb);
}
+ return 0;
}
static int decode_motion(GetBitContext *gb)
@@ -184,7 +191,7 @@ static int decode_motion(GetBitContext *gb)
return value;
}
-static void decode_mb(MadContext *t, int inter)
+static int decode_mb(MadContext *t, int inter)
{
MpegEncContext *s = &t->s;
int mv_map = 0;
@@ -205,13 +212,16 @@ static void decode_mb(MadContext *t, int inter)
for (j=0; j<6; j++) {
if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map
int add = 2*decode_motion(&s->gb);
- comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
+ if (t->last_frame.data[0])
+ comp_block(t, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
} else {
s->dsp.clear_block(t->block);
- decode_block_intra(t, t->block);
+ if(decode_block_intra(t, t->block) < 0)
+ return -1;
idct_put(t, t->block, s->mb_x, s->mb_y, j);
}
}
+ return 0;
}
static void calc_intra_matrix(MadContext *t, int qscale)
@@ -261,14 +271,18 @@ static int decode_frame(AVCodecContext *avctx,
buf += 16;
if (avctx->width != s->width || avctx->height != s->height) {
+ if((s->width * s->height)/2048*7 > buf_end-buf)
+ return -1;
if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
return -1;
avcodec_set_dimensions(avctx, s->width, s->height);
if (t->frame.data[0])
avctx->release_buffer(avctx, &t->frame);
+ if (t->last_frame.data[0])
+ avctx->release_buffer(avctx, &t->last_frame);
}
- t->frame.reference = 1;
+ t->frame.reference = 3;
if (!t->frame.data[0]) {
if (avctx->get_buffer(avctx, &t->frame) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -280,11 +294,13 @@ static int decode_frame(AVCodecContext *avctx,
if (!t->bitstream_buf)
return AVERROR(ENOMEM);
bswap16_buf(t->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2);
+ memset((uint8_t*)t->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE);
init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf));
for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
- decode_mb(t, inter);
+ if(decode_mb(t, inter) < 0)
+ return -1;
*data_size = sizeof(AVFrame);
*(AVFrame*)data = t->frame;
@@ -307,14 +323,13 @@ static av_cold int decode_end(AVCodecContext *avctx)
}
AVCodec ff_eamad_decoder = {
- "eamad",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_MAD,
- sizeof(MadContext),
- decode_init,
- NULL,
- decode_end,
- decode_frame,
- CODEC_CAP_DR1,
+ .name = "eamad",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_MAD,
+ .priv_data_size = sizeof(MadContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video")
};