summaryrefslogtreecommitdiff
path: root/ffmpeg/libavcodec/vp8.c
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
committerTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
commitf7813a5324be39d13ab536c245d15dfc602a7849 (patch)
treefad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavcodec/vp8.c
parentb7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff)
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavcodec/vp8.c')
-rw-r--r--ffmpeg/libavcodec/vp8.c99
1 files changed, 57 insertions, 42 deletions
diff --git a/ffmpeg/libavcodec/vp8.c b/ffmpeg/libavcodec/vp8.c
index ac929d0..0e4a36d 100644
--- a/ffmpeg/libavcodec/vp8.c
+++ b/ffmpeg/libavcodec/vp8.c
@@ -40,8 +40,11 @@ static void free_buffers(VP8Context *s)
int i;
if (s->thread_data)
for (i = 0; i < MAX_THREADS; i++) {
+#if HAVE_THREADS
+ pthread_cond_destroy(&s->thread_data[i].cond);
+ pthread_mutex_destroy(&s->thread_data[i].lock);
+#endif
av_freep(&s->thread_data[i].filter_strength);
- av_freep(&s->thread_data[i].edge_emu_buffer);
}
av_freep(&s->thread_data);
av_freep(&s->macroblocks_base);
@@ -110,16 +113,15 @@ static void vp8_decode_flush(AVCodecContext *avctx)
static int update_dimensions(VP8Context *s, int width, int height)
{
AVCodecContext *avctx = s->avctx;
- int i;
+ int i, ret;
if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
height != s->avctx->height) {
- if (av_image_check_size(width, height, 0, s->avctx))
- return AVERROR_INVALIDDATA;
-
vp8_decode_flush_impl(s->avctx, 1);
- avcodec_set_dimensions(s->avctx, width, height);
+ ret = ff_set_dimensions(s->avctx, width, height);
+ if (ret < 0)
+ return ret;
}
s->mb_width = (s->avctx->coded_width +15) / 16;
@@ -1176,13 +1178,13 @@ static av_always_inline
void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
ThreadFrame *ref, const VP56mv *mv,
int x_off, int y_off, int block_w, int block_h,
- int width, int height, int linesize,
+ int width, int height, ptrdiff_t linesize,
vp8_mc_func mc_func[3][3])
{
uint8_t *src = ref->f->data[0];
if (AV_RN32A(mv)) {
-
+ int src_linesize = linesize;
int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx];
int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my];
@@ -1194,12 +1196,16 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
src += y_off * linesize + x_off;
if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
- block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src - my_idx * linesize - mx_idx,
+ 32, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
- src = td->edge_emu_buffer + mx_idx + linesize * my_idx;
+ src = td->edge_emu_buffer + mx_idx + 32 * my_idx;
+ src_linesize = 32;
}
- mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
+ mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my);
} else {
ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);
@@ -1226,7 +1232,7 @@ void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
static av_always_inline
void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst2,
ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off,
- int block_w, int block_h, int width, int height, int linesize,
+ int block_w, int block_h, int width, int height, ptrdiff_t linesize,
vp8_mc_func mc_func[3][3])
{
uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
@@ -1244,17 +1250,23 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst
ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
- block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src1 - my_idx * linesize - mx_idx,
+ 32, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
- src1 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
- mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
-
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
- block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
+ src1 = td->edge_emu_buffer + mx_idx + 32 * my_idx;
+ mc_func[my_idx][mx_idx](dst1, linesize, src1, 32, block_h, mx, my);
+
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src2 - my_idx * linesize - mx_idx,
+ 32, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
x_off - mx_idx, y_off - my_idx, width, height);
- src2 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
- mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
+ src2 = td->edge_emu_buffer + mx_idx + 32 * my_idx;
+ mc_func[my_idx][mx_idx](dst2, linesize, src2, 32, block_h, mx, my);
} else {
mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
@@ -1676,6 +1688,11 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
if (s->mb_layout == 1)
mb = s->macroblocks_base + ((s->mb_width+1)*(mb_y + 1) + 1);
else {
+ // Make sure the previous frame has read its segmentation map,
+ // if we re-use the same map.
+ if (prev_frame && s->segmentation.enabled &&
+ !s->segmentation.update_map)
+ ff_thread_await_progress(&prev_frame->tf, mb_y, 0);
mb = s->macroblocks + (s->mb_height - mb_y - 1)*2;
memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED*0x01010101);
@@ -1845,8 +1862,8 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
return 0;
}
-static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
+int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
{
VP8Context *s = avctx->priv_data;
int ret, i, referenced, num_jobs;
@@ -1935,10 +1952,6 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
s->linesize = curframe->tf.f->linesize[0];
s->uvlinesize = curframe->tf.f->linesize[1];
- if (!s->thread_data[0].edge_emu_buffer)
- for (i = 0; i < MAX_THREADS; i++)
- s->thread_data[i].edge_emu_buffer = av_malloc(21*s->linesize);
-
memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz));
/* Zero macroblock structures for top/top-left prediction from outside the frame. */
if (!s->mb_layout)
@@ -1955,13 +1968,14 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
memset(s->ref_count, 0, sizeof(s->ref_count));
- // Make sure the previous frame has read its segmentation map,
- // if we re-use the same map.
- if (prev_frame && s->segmentation.enabled && !s->segmentation.update_map)
- ff_thread_await_progress(&prev_frame->tf, 1, 0);
-
- if (s->mb_layout == 1)
+ if (s->mb_layout == 1) {
+ // Make sure the previous frame has read its segmentation map,
+ // if we re-use the same map.
+ if (prev_frame && s->segmentation.enabled &&
+ !s->segmentation.update_map)
+ ff_thread_await_progress(&prev_frame->tf, 1, 0);
vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
+ }
if (avctx->active_thread_type == FF_THREAD_FRAME)
num_jobs = 1;
@@ -1999,7 +2013,7 @@ err:
return ret;
}
-static av_cold int vp8_decode_free(AVCodecContext *avctx)
+av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
{
VP8Context *s = avctx->priv_data;
int i;
@@ -2022,7 +2036,7 @@ static av_cold int vp8_init_frames(VP8Context *s)
return 0;
}
-static av_cold int vp8_decode_init(AVCodecContext *avctx)
+av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
{
VP8Context *s = avctx->priv_data;
int ret;
@@ -2036,7 +2050,7 @@ static av_cold int vp8_decode_init(AVCodecContext *avctx)
ff_vp8dsp_init(&s->vp8dsp);
if ((ret = vp8_init_frames(s)) < 0) {
- vp8_decode_free(avctx);
+ ff_vp8_decode_free(avctx);
return ret;
}
@@ -2051,7 +2065,7 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
s->avctx = avctx;
if ((ret = vp8_init_frames(s)) < 0) {
- vp8_decode_free(avctx);
+ ff_vp8_decode_free(avctx);
return ret;
}
@@ -2096,15 +2110,16 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo
AVCodec ff_vp8_decoder = {
.name = "vp8",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_VP8,
.priv_data_size = sizeof(VP8Context),
- .init = vp8_decode_init,
- .close = vp8_decode_free,
- .decode = vp8_decode_frame,
+ .init = ff_vp8_decode_init,
+ .close = ff_vp8_decode_free,
+ .decode = ff_vp8_decode_frame,
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
.flush = vp8_decode_flush,
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
.init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
};
+