summaryrefslogtreecommitdiffstats
path: root/media/ffvpx/libavcodec/vp8.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/ffvpx/libavcodec/vp8.c')
-rw-r--r--media/ffvpx/libavcodec/vp8.c158
1 files changed, 90 insertions, 68 deletions
diff --git a/media/ffvpx/libavcodec/vp8.c b/media/ffvpx/libavcodec/vp8.c
index c1c3eb707..7841a9d96 100644
--- a/media/ffvpx/libavcodec/vp8.c
+++ b/media/ffvpx/libavcodec/vp8.c
@@ -261,6 +261,7 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
{
const uint8_t *sizes = buf;
int i;
+ int ret;
s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
@@ -274,13 +275,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
if (buf_size - size < 0)
return -1;
- ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
+ ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
+ if (ret < 0)
+ return ret;
buf += size;
buf_size -= size;
}
- ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
-
- return 0;
+ return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
}
static void vp7_get_quants(VP8Context *s)
@@ -434,8 +435,8 @@ static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height)
}
}
-static void fade(uint8_t *dst, int dst_linesize,
- const uint8_t *src, int src_linesize,
+static void fade(uint8_t *dst, ptrdiff_t dst_linesize,
+ const uint8_t *src, ptrdiff_t src_linesize,
int width, int height,
int alpha, int beta)
{
@@ -518,7 +519,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
- ff_vp56_init_range_decoder(c, buf, part1_size);
+ ret = ff_vp56_init_range_decoder(c, buf, part1_size);
+ if (ret < 0)
+ return ret;
buf += part1_size;
buf_size -= part1_size;
@@ -570,7 +573,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
s->lf_delta.enabled = 0;
s->num_coeff_partitions = 1;
- ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
+ ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
+ if (ret < 0)
+ return ret;
if (!s->macroblocks_base || /* first frame */
width != s->avctx->width || height != s->avctx->height ||
@@ -699,7 +704,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
memset(&s->lf_delta, 0, sizeof(s->lf_delta));
}
- ff_vp56_init_range_decoder(c, buf, header_size);
+ ret = ff_vp56_init_range_decoder(c, buf, header_size);
+ if (ret < 0)
+ return ret;
buf += header_size;
buf_size -= header_size;
@@ -765,7 +772,7 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si
}
static av_always_inline
-void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)
+void clamp_mv(VP8mvbounds *s, VP56mv *dst, const VP56mv *src)
{
dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX),
av_clip(s->mv_max.x, INT16_MIN, INT16_MAX));
@@ -1024,7 +1031,7 @@ void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb,
}
static av_always_inline
-void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,
+void vp8_decode_mvs(VP8Context *s, VP8mvbounds *mv_bounds, VP8Macroblock *mb,
int mb_x, int mb_y, int layout)
{
VP8Macroblock *mb_edge[3] = { 0 /* top */,
@@ -1095,7 +1102,7 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,
if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {
/* Choose the best mv out of 0,0 and the nearest mv */
- clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
+ clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
(mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
(mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
@@ -1109,11 +1116,11 @@ void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,
mb->bmv[0] = mb->mv;
}
} else {
- clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);
+ clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAR]);
mb->bmv[0] = mb->mv;
}
} else {
- clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);
+ clamp_mv(mv_bounds, &mb->mv, &near_mv[CNT_NEAREST]);
mb->bmv[0] = mb->mv;
}
} else {
@@ -1159,14 +1166,15 @@ void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
}
static av_always_inline
-void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
+void decode_mb_mode(VP8Context *s, VP8mvbounds *mv_bounds,
+ VP8Macroblock *mb, int mb_x, int mb_y,
uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
{
VP56RangeCoder *c = &s->c;
- static const char *vp7_feature_name[] = { "q-index",
- "lf-delta",
- "partial-golden-update",
- "blit-pitch" };
+ static const char * const vp7_feature_name[] = { "q-index",
+ "lf-delta",
+ "partial-golden-update",
+ "blit-pitch" };
if (is_vp7) {
int i;
*segment = 0;
@@ -1223,7 +1231,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
if (is_vp7)
vp7_decode_mvs(s, mb, mb_x, mb_y, layout);
else
- vp8_decode_mvs(s, mb, mb_x, mb_y, layout);
+ vp8_decode_mvs(s, mv_bounds, mb, mb_x, mb_y, layout);
} else {
// intra MB, 16.1
mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
@@ -1461,7 +1469,7 @@ void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c,
static av_always_inline
void backup_mb_border(uint8_t *top_border, uint8_t *src_y,
uint8_t *src_cb, uint8_t *src_cr,
- int linesize, int uvlinesize, int simple)
+ ptrdiff_t linesize, ptrdiff_t uvlinesize, int simple)
{
AV_COPY128(top_border, src_y + 15 * linesize);
if (!simple) {
@@ -1472,7 +1480,7 @@ void backup_mb_border(uint8_t *top_border, uint8_t *src_y,
static av_always_inline
void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb,
- uint8_t *src_cr, int linesize, int uvlinesize, int mb_x,
+ uint8_t *src_cr, ptrdiff_t linesize, ptrdiff_t uvlinesize, int mb_x,
int mb_y, int mb_width, int simple, int xchg)
{
uint8_t *top_border_m1 = top_border - 32; // for TL prediction
@@ -1625,7 +1633,8 @@ void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
for (y = 0; y < 4; y++) {
uint8_t *topright = ptr + 4 - s->linesize;
for (x = 0; x < 4; x++) {
- int copy = 0, linesize = s->linesize;
+ int copy = 0;
+ ptrdiff_t linesize = s->linesize;
uint8_t *dst = ptr + 4 * x;
LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8]);
@@ -1731,7 +1740,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
uint8_t *src = ref->f->data[0];
if (AV_RN32A(mv)) {
- int src_linesize = linesize;
+ ptrdiff_t src_linesize = linesize;
int mx = (mv->x * 2) & 7, mx_idx = subpel_idx[0][mx];
int my = (mv->y * 2) & 7, my_idx = subpel_idx[0][my];
@@ -2077,8 +2086,8 @@ void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f,
int filter_level = f->filter_level;
int inner_limit = f->inner_limit;
int inner_filter = f->inner_filter;
- int linesize = s->linesize;
- int uvlinesize = s->uvlinesize;
+ ptrdiff_t linesize = s->linesize;
+ ptrdiff_t uvlinesize = s->uvlinesize;
static const uint8_t hev_thresh_lut[2][64] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -2164,7 +2173,7 @@ void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f,
int filter_level = f->filter_level;
int inner_limit = f->inner_limit;
int inner_filter = f->inner_filter;
- int linesize = s->linesize;
+ ptrdiff_t linesize = s->linesize;
if (!filter_level)
return;
@@ -2197,8 +2206,8 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
VP8Context *s = avctx->priv_data;
int mb_x, mb_y;
- s->mv_min.y = -MARGIN;
- s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
+ s->mv_bounds.mv_min.y = -MARGIN;
+ s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
VP8Macroblock *mb = s->macroblocks_base +
((s->mb_width + 1) * (mb_y + 1) + 1);
@@ -2206,20 +2215,20 @@ void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
- s->mv_min.x = -MARGIN;
- s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
+ s->mv_bounds.mv_min.x = -MARGIN;
+ s->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
if (mb_y == 0)
AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,
DC_PRED * 0x01010101);
- decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+ decode_mb_mode(s, &s->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
prev_frame && prev_frame->seg_map ?
prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7);
- s->mv_min.x -= 64;
- s->mv_max.x -= 64;
+ s->mv_bounds.mv_min.x -= 64;
+ s->mv_bounds.mv_max.x -= 64;
}
- s->mv_min.y -= 64;
- s->mv_max.y -= 64;
+ s->mv_bounds.mv_min.y -= 64;
+ s->mv_bounds.mv_max.y -= 64;
}
}
@@ -2239,15 +2248,15 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
#define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
do { \
int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
- if (otd->thread_mb_pos < tmp) { \
+ if (atomic_load(&otd->thread_mb_pos) < tmp) { \
pthread_mutex_lock(&otd->lock); \
- td->wait_mb_pos = tmp; \
+ atomic_store(&td->wait_mb_pos, tmp); \
do { \
- if (otd->thread_mb_pos >= tmp) \
+ if (atomic_load(&otd->thread_mb_pos) >= tmp) \
break; \
pthread_cond_wait(&otd->cond, &otd->lock); \
} while (1); \
- td->wait_mb_pos = INT_MAX; \
+ atomic_store(&td->wait_mb_pos, INT_MAX); \
pthread_mutex_unlock(&otd->lock); \
} \
} while (0)
@@ -2258,12 +2267,10 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
(num_jobs > 1); \
int is_null = !next_td || !prev_td; \
- int pos_check = (is_null) ? 1 \
- : (next_td != td && \
- pos >= next_td->wait_mb_pos) || \
- (prev_td != td && \
- pos >= prev_td->wait_mb_pos); \
- td->thread_mb_pos = pos; \
+ int pos_check = (is_null) ? 1 : \
+ (next_td != td && pos >= atomic_load(&next_td->wait_mb_pos)) || \
+ (prev_td != td && pos >= atomic_load(&prev_td->wait_mb_pos)); \
+ atomic_store(&td->thread_mb_pos, pos); \
if (sliced_threading && pos_check) { \
pthread_mutex_lock(&td->lock); \
pthread_cond_broadcast(&td->cond); \
@@ -2275,12 +2282,12 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
#define update_pos(td, mb_y, mb_x) while(0)
#endif
-static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr, int is_vp7)
{
VP8Context *s = avctx->priv_data;
VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];
- int mb_y = td->thread_mb_pos >> 16;
+ int mb_y = atomic_load(&td->thread_mb_pos) >> 16;
int mb_x, mb_xy = mb_y * s->mb_width;
int num_jobs = s->num_jobs;
VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
@@ -2291,6 +2298,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize,
curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize
};
+
+ if (c->end <= c->buffer && c->bits >= 0)
+ return AVERROR_INVALIDDATA;
+
if (mb_y == 0)
prev_td = td;
else
@@ -2315,10 +2326,12 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
if (!is_vp7 || mb_y == 0)
memset(td->left_nnz, 0, sizeof(td->left_nnz));
- s->mv_min.x = -MARGIN;
- s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
+ td->mv_bounds.mv_min.x = -MARGIN;
+ td->mv_bounds.mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
+ if (c->end <= c->buffer && c->bits >= 0)
+ return AVERROR_INVALIDDATA;
// Wait for previous thread to read mb_x+2, and reach mb_y-1.
if (prev_td != td) {
if (threadnr != 0) {
@@ -2338,7 +2351,7 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
dst[2] - dst[1], 2);
if (!s->mb_layout)
- decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+ decode_mb_mode(s, &td->mv_bounds, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
prev_frame && prev_frame->seg_map ?
prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);
@@ -2385,8 +2398,8 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
dst[0] += 16;
dst[1] += 8;
dst[2] += 8;
- s->mv_min.x -= 64;
- s->mv_max.x -= 64;
+ td->mv_bounds.mv_min.x -= 64;
+ td->mv_bounds.mv_max.x -= 64;
if (mb_x == s->mb_width + 1) {
update_pos(td, mb_y, s->mb_width + 3);
@@ -2394,18 +2407,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
update_pos(td, mb_y, mb_x);
}
}
+ return 0;
}
-static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr)
{
- decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
+ return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
}
-static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr)
{
- decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
+ return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
}
static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
@@ -2413,7 +2427,7 @@ static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
{
VP8Context *s = avctx->priv_data;
VP8ThreadData *td = &s->thread_data[threadnr];
- int mb_x, mb_y = td->thread_mb_pos >> 16, num_jobs = s->num_jobs;
+ int mb_x, mb_y = atomic_load(&td->thread_mb_pos) >> 16, num_jobs = s->num_jobs;
AVFrame *curframe = s->curframe->tf.f;
VP8Macroblock *mb;
VP8ThreadData *prev_td, *next_td;
@@ -2488,19 +2502,24 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
VP8ThreadData *next_td = NULL, *prev_td = NULL;
VP8Frame *curframe = s->curframe;
int mb_y, num_jobs = s->num_jobs;
+ int ret;
td->thread_nr = threadnr;
+ td->mv_bounds.mv_min.y = -MARGIN - 64 * threadnr;
+ td->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN - 64 * threadnr;
for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
- if (mb_y >= s->mb_height)
- break;
- td->thread_mb_pos = mb_y << 16;
- s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
+ atomic_store(&td->thread_mb_pos, mb_y << 16);
+ ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
+ if (ret < 0) {
+ update_pos(td, s->mb_height, INT_MAX & 0xFFFF);
+ return ret;
+ }
if (s->deblock_filter)
s->filter_mb_row(avctx, tdata, jobnr, threadnr);
update_pos(td, mb_y, INT_MAX & 0xFFFF);
- s->mv_min.y -= 64;
- s->mv_max.y -= 64;
+ td->mv_bounds.mv_min.y -= 64 * num_jobs;
+ td->mv_bounds.mv_max.y -= 64 * num_jobs;
if (avctx->active_thread_type == FF_THREAD_FRAME)
ff_thread_report_progress(&curframe->tf, mb_y, 0);
@@ -2531,6 +2550,8 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
enum AVDiscard skip_thresh;
VP8Frame *av_uninit(curframe), *prev_frame;
+ av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVA420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P);
+
if (is_vp7)
ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size);
else
@@ -2646,11 +2667,12 @@ int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
s->num_jobs = num_jobs;
s->curframe = curframe;
s->prev_frame = prev_frame;
- s->mv_min.y = -MARGIN;
- s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
+ s->mv_bounds.mv_min.y = -MARGIN;
+ s->mv_bounds.mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
for (i = 0; i < MAX_THREADS; i++) {
- s->thread_data[i].thread_mb_pos = 0;
- s->thread_data[i].wait_mb_pos = INT_MAX;
+ VP8ThreadData *td = &s->thread_data[i];
+ atomic_init(&td->thread_mb_pos, 0);
+ atomic_init(&td->wait_mb_pos, INT_MAX);
}
if (is_vp7)
avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL,