diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 03:20:18 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-03-12 03:23:28 +0100 |
commit | 80e9e63c946660304fc65fa8141ccfdbe4d196d1 (patch) | |
tree | 55eb37a0bd8d102b07516b88015094d8f3bc6216 /libavcodec/vp8.c | |
parent | 2e7bc9c2a1f138d305f111bb07d8b70e494584a8 (diff) | |
parent | 759001c534287a96dc96d1e274665feb7059145d (diff) | |
download | ffmpeg-80e9e63c946660304fc65fa8141ccfdbe4d196d1.tar.gz |
Merge commit '759001c534287a96dc96d1e274665feb7059145d'
* commit '759001c534287a96dc96d1e274665feb7059145d':
lavc decoders: work with refcounted frames.
Anton Khirnov (1):
lavc decoders: work with refcounted frames.
Clément Bœsch (47):
lavc/ansi: reset file
lavc/ansi: re-do refcounted frame changes from Anton
fraps: reset file
lavc/fraps: switch to refcounted frames
gifdec: reset file
lavc/gifdec: switch to refcounted frames
dsicinav: resolve conflicts
smc: resolve conflicts
zmbv: resolve conflicts
rpza: resolve conflicts
vble: resolve conflicts
xxan: resolve conflicts
targa: resolve conflicts
vmnc: resolve conflicts
utvideodec: resolve conflicts
tscc: resolve conflicts
ulti: resolve conflicts
ffv1dec: resolve conflicts
dnxhddec: resolve conflicts
v210dec: resolve conflicts
vp3: resolve conflicts
vcr1: resolve conflicts
v210x: resolve conflicts
wavpack: resolve conflicts
pngdec: fix compilation
roqvideodec: resolve conflicts
pictordec: resolve conflicts
mdec: resolve conflicts
tiertexseqv: resolve conflicts
smacker: resolve conflicts
vb: resolve conflicts
vqavideo: resolve conflicts
xl: resolve conflicts
tmv: resolve conflicts
vmdav: resolve conflicts
truemotion1: resolve conflicts
truemotion2: resolve conflicts
lcldec: fix compilation
libcelt_dec: fix compilation
qdrw: fix compilation
r210dec: fix compilation
rl2: fix compilation
wnv1: fix compilation
yop: fix compilation
tiff: resolve conflicts
interplayvideo: fix compilation
qpeg: resolve conflicts (FIXME/TESTME).
Hendrik Leppkes (33):
012v: convert to refcounted frames
8bps: fix compilation
8svx: resolve conflicts
4xm: resolve conflicts
aasc: resolve conflicts
bfi: fix compilation
aura: fix compilation
alsdec: resolve conflicts
avrndec: convert to refcounted frames
avuidec: convert to refcounted frames
bintext: convert to refcounted frames
cavsdec: resolve conflicts
brender_pix: convert to refcounted frames
cinepak: resolve conflicts
cinepak: avoid using AVFrame struct directly in private context
cljr: fix compilation
cpia: convert to refcounted frames
cscd: resolve conflicts
iff: resolve conflicts and do proper conversion to refcounted frames
4xm: fix reference frame handling
cyuv: fix compilation
dxa: fix compilation
eacmv: fix compilation
eamad: fix compilation
eatgv: fix compilation
escape124: remove unused variable.
escape130: convert to refcounted frames
evrcdec: convert to refcounted frames
exr: convert to refcounted frames
mvcdec: convert to refcounted frames
paf: properly free the frame data on decode close
sgirle: convert to refcounted frames
lavfi/moviesrc: use refcounted frames
Michael Niedermayer (56):
Merge commit '759001c534287a96dc96d1e274665feb7059145d'
resolve conflicts in headers
motion_est: resolve conflict
mpeg4videodec: fix conflicts
dpcm conflict fix
dpx: fix conflicts
indeo3: resolve confilcts
kmvc: resolve conflicts
kmvc: resolve conflicts
h264: resolve conflicts
utils: resolve conflicts
rawdec: resolve conflcits
mpegvideo: resolve conflicts
svq1enc: resolve conflicts
mpegvideo: dont clear data, fix assertion failure on fate vsynth1 with threads
pthreads: resolve conflicts
frame_thread_encoder: simple compilefix not yet tested
snow: update to buffer refs
crytsalhd: fix compile
dirac: switch to new API
sonic: update to new API
svq1: resolve conflict, update to new API
ffwavesynth: update to new buffer API
g729: update to new API
indeo5: fix compile
j2kdec: update to new buffer API
linopencore-amr: fix compile
libvorbisdec: update to new API
loco: fix compile
paf: update to new API
proresdec: update to new API
vp56: update to new api / resolve conflicts
xface: convert to refcounted frames
xan: fix compile&fate
v408: update to ref counted buffers
v308: update to ref counted buffers
yuv4dec: update to ref counted buffers
y41p: update to ref counted frames
xbm: update to refcounted frames
targa_y216: update to refcounted buffers
qpeg: fix fate/crash
cdxl: fix fate
tscc: fix reget buffer useage
targa_y216dec: fix style
msmpeg4: fix fate
h264: ref_picture() copy fields that have been lost too
update_frame_pool: use channel field
h264: Put code that prevents deadlocks back
mpegvideo: dont allow last == current
wmalossless: fix buffer ref messup
ff_alloc_picture: free tables in case of dimension mismatches
h264: fix null pointer dereference and assertion failure
frame_thread_encoder: update to bufrefs
ec: fix used arrays
snowdec: fix off by 1 error in dimensions check
h264: disallow single unpaired fields as references of frames
Paul B Mahol (2):
lavc/vima: convert to refcounted frames
sanm: convert to refcounted frames
Conflicts:
libavcodec/4xm.c
libavcodec/8bps.c
libavcodec/8svx.c
libavcodec/aasc.c
libavcodec/alsdec.c
libavcodec/anm.c
libavcodec/ansi.c
libavcodec/avs.c
libavcodec/bethsoftvideo.c
libavcodec/bfi.c
libavcodec/c93.c
libavcodec/cavsdec.c
libavcodec/cdgraphics.c
libavcodec/cinepak.c
libavcodec/cljr.c
libavcodec/cscd.c
libavcodec/dnxhddec.c
libavcodec/dpcm.c
libavcodec/dpx.c
libavcodec/dsicinav.c
libavcodec/dvdec.c
libavcodec/dxa.c
libavcodec/eacmv.c
libavcodec/eamad.c
libavcodec/eatgq.c
libavcodec/eatgv.c
libavcodec/eatqi.c
libavcodec/error_resilience.c
libavcodec/escape124.c
libavcodec/ffv1.h
libavcodec/ffv1dec.c
libavcodec/flicvideo.c
libavcodec/fraps.c
libavcodec/frwu.c
libavcodec/g723_1.c
libavcodec/gifdec.c
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_direct.c
libavcodec/h264_loopfilter.c
libavcodec/h264_refs.c
libavcodec/huffyuvdec.c
libavcodec/idcinvideo.c
libavcodec/iff.c
libavcodec/indeo2.c
libavcodec/indeo3.c
libavcodec/internal.h
libavcodec/interplayvideo.c
libavcodec/ivi_common.c
libavcodec/jvdec.c
libavcodec/kgv1dec.c
libavcodec/kmvc.c
libavcodec/lagarith.c
libavcodec/libopenjpegdec.c
libavcodec/mdec.c
libavcodec/mimic.c
libavcodec/mjpegbdec.c
libavcodec/mjpegdec.c
libavcodec/mmvideo.c
libavcodec/motion_est.c
libavcodec/motionpixels.c
libavcodec/mpc7.c
libavcodec/mpeg12.c
libavcodec/mpeg4videodec.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/msrle.c
libavcodec/msvideo1.c
libavcodec/nuv.c
libavcodec/options_table.h
libavcodec/pcx.c
libavcodec/pictordec.c
libavcodec/pngdec.c
libavcodec/pnmdec.c
libavcodec/pthread.c
libavcodec/qpeg.c
libavcodec/qtrle.c
libavcodec/r210dec.c
libavcodec/rawdec.c
libavcodec/roqvideodec.c
libavcodec/rpza.c
libavcodec/smacker.c
libavcodec/smc.c
libavcodec/svq1dec.c
libavcodec/svq1enc.c
libavcodec/targa.c
libavcodec/tiertexseqv.c
libavcodec/tiff.c
libavcodec/tmv.c
libavcodec/truemotion1.c
libavcodec/truemotion2.c
libavcodec/tscc.c
libavcodec/ulti.c
libavcodec/utils.c
libavcodec/utvideodec.c
libavcodec/v210dec.c
libavcodec/v210x.c
libavcodec/vb.c
libavcodec/vble.c
libavcodec/vcr1.c
libavcodec/vmdav.c
libavcodec/vmnc.c
libavcodec/vp3.c
libavcodec/vp56.c
libavcodec/vp56.h
libavcodec/vp6.c
libavcodec/vqavideo.c
libavcodec/wavpack.c
libavcodec/xl.c
libavcodec/xxan.c
libavcodec/zmbv.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/vp8.c')
-rw-r--r-- | libavcodec/vp8.c | 201 |
1 files changed, 112 insertions, 89 deletions
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index fc6fd3728f..9218dff234 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -52,64 +52,59 @@ static void free_buffers(VP8Context *s) s->macroblocks = NULL; } -static int vp8_alloc_frame(VP8Context *s, AVFrame *f) +static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref) { int ret; - if ((ret = ff_thread_get_buffer(s->avctx, f)) < 0) + if ((ret = ff_thread_get_buffer(s->avctx, &f->tf, + ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; - if (s->num_maps_to_be_freed && !s->maps_are_invalid) { - f->ref_index[0] = s->segmentation_maps[--s->num_maps_to_be_freed]; - } else if (!(f->ref_index[0] = av_mallocz(s->mb_width * s->mb_height))) { - ff_thread_release_buffer(s->avctx, f); + if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) { + ff_thread_release_buffer(s->avctx, &f->tf); return AVERROR(ENOMEM); } return 0; } -static void vp8_release_frame(VP8Context *s, AVFrame *f, int prefer_delayed_free, int can_direct_free) +static void vp8_release_frame(VP8Context *s, VP8Frame *f) { - if (f->ref_index[0]) { - if (prefer_delayed_free) { - /* Upon a size change, we want to free the maps but other threads may still - * be using them, so queue them. Upon a seek, all threads are inactive so - * we want to cache one to prevent re-allocation in the next decoding - * iteration, but the rest we can free directly. */ - int max_queued_maps = can_direct_free ? 1 : FF_ARRAY_ELEMS(s->segmentation_maps); - if (s->num_maps_to_be_freed < max_queued_maps) { - s->segmentation_maps[s->num_maps_to_be_freed++] = f->ref_index[0]; - } else if (can_direct_free) /* vp8_decode_flush(), but our queue is full */ { - av_free(f->ref_index[0]); - } /* else: MEMLEAK (should never happen, but better that than crash) */ - f->ref_index[0] = NULL; - } else /* vp8_decode_free() */ { - av_free(f->ref_index[0]); - } + av_buffer_unref(&f->seg_map); + ff_thread_release_buffer(s->avctx, &f->tf); +} + +static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src) +{ + int ret; + + vp8_release_frame(s, dst); + + if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) + return ret; + if (src->seg_map && + !(dst->seg_map = av_buffer_ref(src->seg_map))) { + vp8_release_frame(s, dst); + return AVERROR(ENOMEM); } - ff_thread_release_buffer(s->avctx, f); + + return 0; } -static void vp8_decode_flush_impl(AVCodecContext *avctx, - int prefer_delayed_free, int can_direct_free, int free_mem) + +static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem) { VP8Context *s = avctx->priv_data; int i; - if (!avctx->internal->is_copy) { - for (i = 0; i < 5; i++) - if (s->frames[i].data[0]) - vp8_release_frame(s, &s->frames[i], prefer_delayed_free, can_direct_free); - } + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + vp8_release_frame(s, &s->frames[i]); memset(s->framep, 0, sizeof(s->framep)); - if (free_mem) { + if (free_mem) free_buffers(s); - s->maps_are_invalid = 1; - } } static void vp8_decode_flush(AVCodecContext *avctx) { - vp8_decode_flush_impl(avctx, 1, 1, 0); + vp8_decode_flush_impl(avctx, 0); } static int update_dimensions(VP8Context *s, int width, int height) @@ -122,7 +117,7 @@ static int update_dimensions(VP8Context *s, int width, int height) if (av_image_check_size(width, height, 0, s->avctx)) return AVERROR_INVALIDDATA; - vp8_decode_flush_impl(s->avctx, 1, 0, 1); + vp8_decode_flush_impl(s->avctx, 1); avcodec_set_dimensions(s->avctx, width, height); } @@ -1179,12 +1174,12 @@ static const uint8_t subpel_idx[3][8] = { */ static av_always_inline void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst, - AVFrame *ref, const VP56mv *mv, + ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, int linesize, vp8_mc_func mc_func[3][3]) { - uint8_t *src = ref->data[0]; + uint8_t *src = ref->f->data[0]; if (AV_RN32A(mv)) { @@ -1230,11 +1225,11 @@ 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, - AVFrame *ref, const VP56mv *mv, int x_off, int y_off, + ThreadFrame *ref, const VP56mv *mv, int x_off, int y_off, int block_w, int block_h, int width, int height, int linesize, vp8_mc_func mc_func[3][3]) { - uint8_t *src1 = ref->data[1], *src2 = ref->data[2]; + uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2]; if (AV_RN32A(mv)) { int mx = mv->x&7, mx_idx = subpel_idx[0][mx]; @@ -1273,7 +1268,7 @@ void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1, uint8_t *dst static av_always_inline void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], - AVFrame *ref_frame, int x_off, int y_off, + ThreadFrame *ref_frame, int x_off, int y_off, int bx_off, int by_off, int block_w, int block_h, int width, int height, VP56mv *mv) @@ -1311,7 +1306,7 @@ static av_always_inline void prefetch_motion(VP8Context *s, VP8Macroblock *mb, i int x_off = mb_x << 4, y_off = mb_y << 4; int mx = (mb->mv.x>>2) + x_off + 8; int my = (mb->mv.y>>2) + y_off; - uint8_t **src= s->framep[ref]->data; + uint8_t **src= s->framep[ref]->tf.f->data; int off= mx + (my + (mb_x&3)*4)*s->linesize + 64; /* For threading, a ff_thread_await_progress here might be useful, but * it actually slows down the decoder. Since a bad prefetch doesn't @@ -1331,7 +1326,7 @@ void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], { int x_off = mb_x << 4, y_off = mb_y << 4; int width = 16*s->mb_width, height = 16*s->mb_height; - AVFrame *ref = s->framep[mb->ref_frame]; + ThreadFrame *ref = &s->framep[mb->ref_frame]->tf; VP56mv *bmv = mb->bmv; switch (mb->partitioning) { @@ -1590,17 +1585,9 @@ static av_always_inline void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8Fi } } -static void release_queued_segmaps(VP8Context *s, int is_close) -{ - int leave_behind = is_close ? 0 : !s->maps_are_invalid; - while (s->num_maps_to_be_freed > leave_behind) - av_freep(&s->segmentation_maps[--s->num_maps_to_be_freed]); - s->maps_are_invalid = 0; -} - #define MARGIN (16 << 2) -static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe, - AVFrame *prev_frame) +static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe, + VP8Frame *prev_frame) { VP8Context *s = avctx->priv_data; int mb_x, mb_y; @@ -1618,8 +1605,9 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, AVFrame *curframe, 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->ref_index[0] + mb_xy, - prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 1); + decode_mb_mode(s, 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); s->mv_min.x -= 64; s->mv_max.x -= 64; } @@ -1673,13 +1661,13 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, int mb_y = td->thread_mb_pos>>16; int i, y, mb_x, mb_xy = mb_y*s->mb_width; int num_jobs = s->num_jobs; - AVFrame *curframe = s->curframe, *prev_frame = s->prev_frame; + VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame; VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions-1)]; VP8Macroblock *mb; uint8_t *dst[3] = { - curframe->data[0] + 16*mb_y*s->linesize, - curframe->data[1] + 8*mb_y*s->uvlinesize, - curframe->data[2] + 8*mb_y*s->uvlinesize + curframe->tf.f->data[0] + 16*mb_y*s->linesize, + curframe->tf.f->data[1] + 8*mb_y*s->uvlinesize, + curframe->tf.f->data[2] + 8*mb_y*s->uvlinesize }; if (mb_y == 0) prev_td = td; else prev_td = &s->thread_data[(jobnr + num_jobs - 1)%num_jobs]; @@ -1698,7 +1686,7 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, if (!(avctx->flags & CODEC_FLAG_EMU_EDGE)) { for (i = 0; i < 3; i++) for (y = 0; y < 16>>!!i; y++) - dst[i][y*curframe->linesize[i]-1] = 129; + dst[i][y*curframe->tf.f->linesize[i]-1] = 129; if (mb_y == 1) { s->top_border[0][15] = s->top_border[0][23] = s->top_border[0][31] = 129; } @@ -1721,8 +1709,9 @@ static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, s->vdsp.prefetch(dst[1] + (mb_x&7)*s->uvlinesize + 64, dst[2] - dst[1], 2); if (!s->mb_layout) - decode_mb_mode(s, mb, mb_x, mb_y, curframe->ref_index[0] + mb_xy, - prev_frame && prev_frame->ref_index[0] ? prev_frame->ref_index[0] + mb_xy : NULL, 0); + decode_mb_mode(s, 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); prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS); @@ -1781,7 +1770,7 @@ static void vp8_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; - AVFrame *curframe = s->curframe; + AVFrame *curframe = s->curframe->tf.f; VP8Macroblock *mb; VP8ThreadData *prev_td, *next_td; uint8_t *dst[3] = { @@ -1835,7 +1824,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, VP8Context *s = avctx->priv_data; VP8ThreadData *td = &s->thread_data[jobnr]; VP8ThreadData *next_td = NULL, *prev_td = NULL; - AVFrame *curframe = s->curframe; + VP8Frame *curframe = s->curframe; int mb_y, num_jobs = s->num_jobs; td->thread_nr = threadnr; for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { @@ -1850,7 +1839,7 @@ static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, s->mv_max.y -= 64; if (avctx->active_thread_type == FF_THREAD_FRAME) - ff_thread_report_progress(curframe, mb_y, 0); + ff_thread_report_progress(&curframe->tf, mb_y, 0); } return 0; @@ -1862,9 +1851,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, VP8Context *s = avctx->priv_data; int ret, i, referenced, num_jobs; enum AVDiscard skip_thresh; - AVFrame *av_uninit(curframe), *prev_frame; - - release_queued_segmaps(s, 0); + VP8Frame *av_uninit(curframe), *prev_frame; if ((ret = decode_frame_header(s, avpkt->data, avpkt->size)) < 0) goto err; @@ -1886,12 +1873,12 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // release no longer referenced frames for (i = 0; i < 5; i++) - if (s->frames[i].data[0] && + if (s->frames[i].tf.f->data[0] && &s->frames[i] != prev_frame && &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] && &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) - vp8_release_frame(s, &s->frames[i], 1, 0); + vp8_release_frame(s, &s->frames[i]); // find a free buffer for (i = 0; i < 5; i++) @@ -1906,8 +1893,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, av_log(avctx, AV_LOG_FATAL, "Ran out of free frames!\n"); abort(); } - if (curframe->data[0]) - vp8_release_frame(s, curframe, 1, 0); + if (curframe->tf.f->data[0]) + vp8_release_frame(s, curframe); // Given that arithmetic probabilities are updated every frame, it's quite likely // that the values we have on a random interframe are complete junk if we didn't @@ -1920,10 +1907,9 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, goto err; } - curframe->key_frame = s->keyframe; - curframe->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - curframe->reference = referenced ? 3 : 0; - if ((ret = vp8_alloc_frame(s, curframe))) { + curframe->tf.f->key_frame = s->keyframe; + curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + if ((ret = vp8_alloc_frame(s, curframe, referenced))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n"); goto err; } @@ -1948,8 +1934,8 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ff_thread_finish_setup(avctx); - s->linesize = curframe->linesize[0]; - s->uvlinesize = curframe->linesize[1]; + 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++) @@ -1974,7 +1960,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, // 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, 1, 0); + ff_thread_await_progress(&prev_frame->tf, 1, 0); if (s->mb_layout == 1) vp8_decode_mv_mb_modes(avctx, curframe, prev_frame); @@ -1994,7 +1980,7 @@ static int vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL, num_jobs); - ff_thread_report_progress(curframe, INT_MAX, 0); + ff_thread_report_progress(&curframe->tf, INT_MAX, 0); memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4); skip_decode: @@ -2004,7 +1990,8 @@ skip_decode: s->prob[0] = s->prob[1]; if (!s->invisible) { - *(AVFrame*)data = *curframe; + if ((ret = av_frame_ref(data, curframe->tf.f)) < 0) + return ret; *got_frame = 1; } @@ -2014,33 +2001,62 @@ err: return ret; } +static av_cold int vp8_decode_free(AVCodecContext *avctx) +{ + VP8Context *s = avctx->priv_data; + int i; + + vp8_decode_flush_impl(avctx, 1); + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) + av_frame_free(&s->frames[i].tf.f); + + return 0; +} + +static av_cold int vp8_init_frames(VP8Context *s) +{ + int i; + for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) { + s->frames[i].tf.f = av_frame_alloc(); + if (!s->frames[i].tf.f) + return AVERROR(ENOMEM); + } + return 0; +} + static av_cold int vp8_decode_init(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; + int ret; s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_YUV420P; + avctx->internal->allocate_progress = 1; ff_videodsp_init(&s->vdsp, 8); ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1); ff_vp8dsp_init(&s->vp8dsp); - return 0; -} + if ((ret = vp8_init_frames(s)) < 0) { + vp8_decode_free(avctx); + return ret; + } -static av_cold int vp8_decode_free(AVCodecContext *avctx) -{ - vp8_decode_flush_impl(avctx, 0, 1, 1); - release_queued_segmaps(avctx->priv_data, 1); return 0; } static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) { VP8Context *s = avctx->priv_data; + int ret; s->avctx = avctx; + if ((ret = vp8_init_frames(s)) < 0) { + vp8_decode_free(avctx); + return ret; + } + return 0; } @@ -2050,11 +2066,11 @@ static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx) static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { VP8Context *s = dst->priv_data, *s_src = src->priv_data; + int i; if (s->macroblocks_base && (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) { free_buffers(s); - s->maps_are_invalid = 1; s->mb_width = s_src->mb_width; s->mb_height = s_src->mb_height; } @@ -2064,7 +2080,14 @@ static int vp8_decode_update_thread_context(AVCodecContext *dst, const AVCodecCo s->lf_delta = s_src->lf_delta; memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias)); - memcpy(&s->frames, &s_src->frames, sizeof(s->frames)); + for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) { + if (s_src->frames[i].tf.f->data[0]) { + int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]); + if (ret < 0) + return ret; + } + } + s->framep[0] = REBASE(s_src->next_framep[0]); s->framep[1] = REBASE(s_src->next_framep[1]); s->framep[2] = REBASE(s_src->next_framep[2]); |