ffmpeg-cvslog
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
November 2013
- 7 participants
- 1134 discussions
17 Jun '14
ffmpeg | branch: master | Michael Niedermayer <michaelni(a)gmx.at> | Sat Jul 13 13:32:39 2013 +0200| [6af8326354ed6c1c68b53b3f2bba6697fb2d3bff] | committer: Michael Niedermayer
avcodec/ff_init_vlc_sparse: use a spinlock for thread sync
Signed-off-by: Michael Niedermayer <michaelni(a)gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=6af8326354ed6c1c6…
---
libavcodec/bitstream.c | 28 +++++++++++++++++++---------
libavcodec/get_bits.h | 1 +
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index 3c4d176..aac32a5 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -28,6 +28,7 @@
* bitstream api.
*/
+#include "libavutil/atomic.h"
#include "libavutil/avassert.h"
#include "avcodec.h"
#include "mathops.h"
@@ -269,14 +270,17 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
{
VLCcode *buf;
int i, j, ret;
+ void *state;
vlc->bits = nb_bits;
if (flags & INIT_VLC_USE_NEW_STATIC) {
- if (vlc->table_size && vlc->table_size == vlc->table_allocated) {
- return 0;
- } else if(vlc->table_size) {
- abort(); // fatal error, we are called on a partially initialized table
+ while (state = avpriv_atomic_ptr_cas(&vlc->init_state, NULL, vlc)) {
+ if (state == vlc + 1) {
+ av_assert0(vlc->table_size && vlc->table_size == vlc->table_allocated);
+ return 0;
+ }
}
+ av_assert0(!vlc->table_size);
} else {
vlc->table = NULL;
vlc->table_allocated = 0;
@@ -326,12 +330,18 @@ int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes,
ret = build_table(vlc, nb_bits, nb_codes, buf, flags);
av_free(buf);
- if (ret < 0) {
- av_freep(&vlc->table);
- return ret;
+ if (flags & INIT_VLC_USE_NEW_STATIC) {
+ if(vlc->table_size != vlc->table_allocated)
+ av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
+ state = avpriv_atomic_ptr_cas(&vlc->init_state, vlc, vlc+1);
+ av_assert0(state == vlc);
+ av_assert0(ret >= 0);
+ } else {
+ if (ret < 0) {
+ av_freep(&vlc->table);
+ return ret;
+ }
}
- if((flags & INIT_VLC_USE_NEW_STATIC) && vlc->table_size != vlc->table_allocated)
- av_log(NULL, AV_LOG_ERROR, "needed %d had %d\n", vlc->table_size, vlc->table_allocated);
return 0;
}
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index b6cc75a..3967b49 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -64,6 +64,7 @@ typedef struct VLC {
int bits;
VLC_TYPE (*table)[2]; ///< code, bits
int table_size, table_allocated;
+ void *init_state;
} VLC;
typedef struct RL_VLC_ELEM {
4
5
ffmpeg | branch: master | Diego Biurrun <diego(a)biurrun.de> | Tue Nov 5 08:16:31 2013 +0100| [19e30a58fc8ee6187a0bc14aff7f566a13c81421] | committer: Diego Biurrun
Deprecate obsolete XvMC hardware decoding support
XvMC has long ago been superseded by newer acceleration APIs, such as
VDPAU, and few downstreams still support it. Furthermore XvMC is not
implemented within the hwaccel framework, but requires its own specific
code in the MPEG-1/2 decoder, which is a maintenance burden.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=19e30a58fc8ee6187…
---
doc/general.texi | 1 -
libavcodec/allcodecs.c | 5 +++-
libavcodec/avcodec.h | 9 +++++-
libavcodec/codec_desc.c | 6 ++--
libavcodec/error_resilience.c | 10 +++++++
libavcodec/mpeg12.c | 1 -
libavcodec/mpeg12dec.c | 65 +++++++++++++++++++++++++++++++----------
libavcodec/mpegvideo.c | 58 +++++++++++++++++++++++-------------
libavcodec/mpegvideo_xvmc.c | 5 ++++
libavcodec/options_table.h | 2 ++
libavcodec/version.h | 3 ++
libavcodec/x86/dsputil_init.c | 8 +++--
libavcodec/xvmc.h | 8 ++++-
libavcodec/xvmc_internal.h | 5 ++++
libavutil/old_pix_fmts.h | 2 ++
libavutil/pixdesc.c | 3 ++
libavutil/pixfmt.h | 2 ++
libavutil/version.h | 3 ++
18 files changed, 151 insertions(+), 45 deletions(-)
diff --git a/doc/general.texi b/doc/general.texi
index 6c82ac7..811fb9a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -577,7 +577,6 @@ following image formats are supported:
@item Mobotix MxPEG video @tab @tab X
@item Motion Pixels video @tab @tab X
@item MPEG-1 video @tab X @tab X
-@item MPEG-1/2 video XvMC (X-Video Motion Compensation) @tab @tab X
@item MPEG-2 video @tab X @tab X
@item MPEG-4 part 2 @tab X @tab X
@tab libxvidcore can be used alternatively for encoding.
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 6172466..faa94b1 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -24,8 +24,9 @@
* Provide registration of all codecs, parsers and bitstream filters for libavcodec.
*/
-#include "avcodec.h"
#include "config.h"
+#include "avcodec.h"
+#include "version.h"
#define REGISTER_HWACCEL(X, x) \
{ \
@@ -178,7 +179,9 @@ void avcodec_register_all(void)
REGISTER_DECODER(MJPEGB, mjpegb);
REGISTER_DECODER(MMVIDEO, mmvideo);
REGISTER_DECODER(MOTIONPIXELS, motionpixels);
+#if FF_API_XVMC
REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc);
+#endif /* FF_API_XVMC */
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video);
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video);
REGISTER_ENCDEC (MPEG4, mpeg4);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0548f71..831d28e 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -103,7 +103,9 @@ enum AVCodecID {
/* video codecs */
AV_CODEC_ID_MPEG1VIDEO,
AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+#if FF_API_XVMC
AV_CODEC_ID_MPEG2VIDEO_XVMC,
+#endif /* FF_API_XVMC */
AV_CODEC_ID_H261,
AV_CODEC_ID_H263,
AV_CODEC_ID_RV10,
@@ -691,8 +693,10 @@ typedef struct RcOverride{
*/
#define CODEC_CAP_DR1 0x0002
#define CODEC_CAP_TRUNCATED 0x0008
+#if FF_API_XVMC
/* Codec can export data for HW decoding (XvMC). */
#define CODEC_CAP_HWACCEL 0x0010
+#endif /* FF_API_XVMC */
/**
* Encoder or decoder requires flushing with NULL input at the end in order to
* give the complete and correct output.
@@ -1526,12 +1530,15 @@ typedef struct AVCodecContext {
#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+#if FF_API_XVMC
/**
* XVideo Motion Acceleration
* - encoding: forbidden
* - decoding: set by decoder
+ * @deprecated XvMC support is slated for removal.
*/
- int xvmc_acceleration;
+ attribute_deprecated int xvmc_acceleration;
+#endif /* FF_API_XVMC */
/**
* macroblock decision mode
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 73e8f6d..68c895d 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -18,10 +18,10 @@
#include <string.h>
-#include "avcodec.h"
-
#include "libavutil/common.h"
#include "libavutil/internal.h"
+#include "avcodec.h"
+#include "version.h"
static const AVCodecDescriptor codec_descriptors[] = {
/* video codecs */
@@ -39,6 +39,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
.props = AV_CODEC_PROP_LOSSY,
},
+#if FF_API_XVMC
{
.id = AV_CODEC_ID_MPEG2VIDEO_XVMC,
.type = AVMEDIA_TYPE_VIDEO,
@@ -46,6 +47,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
.props = AV_CODEC_PROP_LOSSY,
},
+#endif /* FF_API_XVMC */
{
.id = AV_CODEC_ID_H261,
.type = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index 1769d2b..51ebc04 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -27,11 +27,13 @@
#include <limits.h>
+#include "libavutil/internal.h"
#include "avcodec.h"
#include "error_resilience.h"
#include "mpegvideo.h"
#include "rectangle.h"
#include "thread.h"
+#include "version.h"
/**
* @param stride the number of MVs to get to the next row
@@ -672,11 +674,15 @@ static int is_intra_more_likely(ERContext *s)
if (undamaged_count < 5)
return 0; // almost all MBs damaged -> use temporal prediction
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// prevent dsp.sad() check, that requires access to the image
if (CONFIG_MPEG_XVMC_DECODER &&
s->avctx->xvmc_acceleration &&
s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I)
return 1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
skip_amount = FFMAX(undamaged_count / 50, 1); // check only up to 50 MBs
is_intra_likely = 0;
@@ -1105,9 +1111,13 @@ void ff_er_frame_end(ERContext *s)
} else
guess_mv(s);
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
/* the filters below are not XvMC compatible, skip them */
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
goto ec_clean;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
/* fill DC for inter blocks */
for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index 5724cc8..5797d27 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -34,7 +34,6 @@
#include "mpeg12.h"
#include "mpeg12data.h"
#include "bytestream.h"
-#include "xvmc_internal.h"
#include "thread.h"
uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 1713cfb..2e95c64 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -37,6 +37,7 @@
#include "bytestream.h"
#include "xvmc_internal.h"
#include "thread.h"
+#include "version.h"
typedef struct Mpeg1Context {
MpegEncContext mpeg_enc_ctx;
@@ -756,6 +757,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
} else
memset(s->last_mv, 0, sizeof(s->last_mv)); /* reset mv prediction */
s->mb_intra = 1;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// if 1, we memcpy blocks in xvmcvideo
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
@@ -763,6 +766,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
exchange_uv(s);
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
if (s->flags2 & CODEC_FLAG2_FAST) {
@@ -969,6 +974,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
return -1;
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
//if 1, we memcpy blocks in xvmcvideo
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1) {
ff_xvmc_pack_pblocks(s, cbp);
@@ -976,6 +983,8 @@ static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
exchange_uv(s);
}
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
if (s->flags2 & CODEC_FLAG2_FAST) {
@@ -1098,10 +1107,12 @@ static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
}
}
+#if FF_API_XVMC
static const enum AVPixelFormat pixfmt_xvmc_mpg2_420[] = {
AV_PIX_FMT_XVMC_MPEG2_IDCT,
AV_PIX_FMT_XVMC_MPEG2_MC,
AV_PIX_FMT_NONE };
+#endif /* FF_API_XVMC */
static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = {
#if CONFIG_MPEG2_DXVA2_HWACCEL
@@ -1122,16 +1133,19 @@ static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
Mpeg1Context *s1 = avctx->priv_data;
MpegEncContext *s = &s1->mpeg_enc_ctx;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (avctx->xvmc_acceleration)
return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
- else {
- if (s->chroma_format < 2)
- return avctx->get_format(avctx, mpeg12_hwaccel_pixfmt_list_420);
- else if (s->chroma_format == 2)
- return AV_PIX_FMT_YUV422P;
- else
- return AV_PIX_FMT_YUV444P;
- }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+
+ if (s->chroma_format < 2)
+ return avctx->get_format(avctx, mpeg12_hwaccel_pixfmt_list_420);
+ else if (s->chroma_format == 2)
+ return AV_PIX_FMT_YUV422P;
+ else
+ return AV_PIX_FMT_YUV444P;
}
/* Call this function when we know all parameters.
@@ -1229,10 +1243,13 @@ static int mpeg_decode_postinit(AVCodecContext *avctx)
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
avctx->hwaccel = ff_find_hwaccel(avctx);
// until then pix_fmt may be changed right after codec init
- if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
- avctx->hwaccel)
- if (avctx->idct_algo == FF_IDCT_AUTO)
- avctx->idct_algo = FF_IDCT_SIMPLE;
+#if FF_API_XVMC
+ if ((avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT ||
+ avctx->hwaccel) && avctx->idct_algo == FF_IDCT_AUTO)
+#else
+ if (avctx->hwaccel && avctx->idct_algo == FF_IDCT_AUTO)
+#endif /* FF_API_XVMC */
+ avctx->idct_algo = FF_IDCT_SIMPLE;
/* Quantization matrices may need reordering
* if DCT permutation is changed. */
@@ -1557,11 +1574,15 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
return -1;
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// MPV_frame_start will call this function too,
// but we need to call it on every field
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
if (ff_xvmc_field_start(s, avctx) < 0)
return -1;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
return 0;
}
@@ -1662,9 +1683,13 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
}
for (;;) {
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
// If 1, we memcpy blocks in xvmcvideo.
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)
ff_xvmc_init_block(s); // set s->block
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if (mpeg_decode_mb(s, s->block) < 0)
return -1;
@@ -1854,8 +1879,12 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict)
av_log(avctx, AV_LOG_ERROR, "hardware accelerator failed to decode picture\n");
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
ff_xvmc_field_end(s);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
/* end of slice reached */
if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
@@ -1990,9 +2019,13 @@ static int vcr2_init_sequence(AVCodecContext *avctx)
avctx->pix_fmt = mpeg_get_pixelformat(avctx);
avctx->hwaccel = ff_find_hwaccel(avctx);
- if (avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel)
- if (avctx->idct_algo == FF_IDCT_AUTO)
- avctx->idct_algo = FF_IDCT_SIMPLE;
+#if FF_API_XVMC
+ if ((avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel) &&
+ avctx->idct_algo == FF_IDCT_AUTO)
+#else
+ if (avctx->hwaccel && avctx->idct_algo == FF_IDCT_AUTO)
+#endif /* FF_API_XVMC */
+ avctx->idct_algo = FF_IDCT_SIMPLE;
if (ff_MPV_common_init(s) < 0)
return -1;
@@ -2436,6 +2469,7 @@ AVCodec ff_mpeg2video_decoder = {
.profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
};
+#if FF_API_XVMC
#if CONFIG_MPEG_XVMC_DECODER
static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
{
@@ -2469,3 +2503,4 @@ AVCodec ff_mpeg_xvmc_decoder = {
};
#endif
+#endif /* FF_API_XVMC */
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index d609b54..48a7320 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -30,6 +30,7 @@
#include "libavutil/attributes.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
#include "avcodec.h"
#include "dsputil.h"
#include "internal.h"
@@ -1671,8 +1672,12 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
update_noise_reduction(s);
}
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)
return ff_xvmc_field_start(s, avctx);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
return 0;
}
@@ -1682,31 +1687,37 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
void ff_MPV_frame_end(MpegEncContext *s)
{
int i;
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
/* redraw edges for the frame if decoding didn't complete */
// just to make sure that all data is rendered.
if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) {
ff_xvmc_field_end(s);
- } else if ((s->er.error_count || s->encoding) &&
- !s->avctx->hwaccel &&
- s->unrestricted_mv &&
- s->current_picture.reference &&
- !s->intra_only &&
- !(s->flags & CODEC_FLAG_EMU_EDGE)) {
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
- int hshift = desc->log2_chroma_w;
- int vshift = desc->log2_chroma_h;
- s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize,
- s->h_edge_pos, s->v_edge_pos,
- EDGE_WIDTH, EDGE_WIDTH,
- EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize,
- s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
- EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
- EDGE_TOP | EDGE_BOTTOM);
- s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize,
- s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
- EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
- EDGE_TOP | EDGE_BOTTOM);
+ } else
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+ if ((s->er.error_count || s->encoding) &&
+ !s->avctx->hwaccel &&
+ s->unrestricted_mv &&
+ s->current_picture.reference &&
+ !s->intra_only &&
+ !(s->flags & CODEC_FLAG_EMU_EDGE)) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+ int hshift = desc->log2_chroma_w;
+ int vshift = desc->log2_chroma_h;
+ s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize,
+ s->h_edge_pos, s->v_edge_pos,
+ EDGE_WIDTH, EDGE_WIDTH,
+ EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize,
+ s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+ EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+ EDGE_TOP | EDGE_BOTTOM);
+ s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize,
+ s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+ EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+ EDGE_TOP | EDGE_BOTTOM);
}
emms_c();
@@ -1959,10 +1970,15 @@ void MPV_decode_mb_internal(MpegEncContext *s, int16_t block[12][64],
int is_mpeg12)
{
const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
+
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
ff_xvmc_decode_mb(s);//xvmc uses pblocks
return;
}
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {
/* print DCT coefficients */
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index e95c91f..ec218c2 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -30,6 +30,9 @@
#include "xvmc.h"
#include "xvmc_internal.h"
+#include "version.h"
+
+#if FF_API_XVMC
/**
* Initialize the block field of the MpegEncContext pointer passed as
@@ -329,3 +332,5 @@ void ff_xvmc_decode_mb(MpegEncContext *s)
if (render->filled_mv_blocks_num == render->allocated_mv_blocks)
ff_mpeg_draw_horiz_band(s, 0, 0);
}
+
+#endif /* FF_API_XVMC */
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 99105e3..3554113 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -273,7 +273,9 @@ static const AVOption avcodec_options[] = {
{"deflate", "deflate-based coder", 0, AV_OPT_TYPE_CONST, {.i64 = FF_CODER_TYPE_DEFLATE }, INT_MIN, INT_MAX, V|E, "coder"},
{"context", "context model", OFFSET(context_model), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"slice_flags", NULL, OFFSET(slice_flags), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#if FF_API_XVMC
{"xvmc_acceleration", NULL, OFFSET(xvmc_acceleration), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
+#endif /* FF_API_XVMC */
{"mbd", "macroblock decision algorithm (high quality mode)", OFFSET(mb_decision), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E, "mbd"},
{"simple", "use mbcmp (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_SIMPLE }, INT_MIN, INT_MAX, V|E, "mbd"},
{"bits", "use fewest bits", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MB_DECISION_BITS }, INT_MIN, INT_MAX, V|E, "mbd"},
diff --git a/libavcodec/version.h b/libavcodec/version.h
index c36efce..993d57a 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -97,5 +97,8 @@
#ifndef FF_API_ARCH_ALPHA
#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 56)
#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 56)
+#endif
#endif /* AVCODEC_VERSION_H */
diff --git a/libavcodec/x86/dsputil_init.c b/libavcodec/x86/dsputil_init.c
index cc35d24..aa4e37b 100644
--- a/libavcodec/x86/dsputil_init.c
+++ b/libavcodec/x86/dsputil_init.c
@@ -611,11 +611,15 @@ static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
if (!high_bit_depth) {
+#if FF_API_XVMC
if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
/* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
- c->clear_block = ff_clear_block_sse;
- c->clear_blocks = ff_clear_blocks_sse;
+#endif /* FF_API_XVMC */
+ c->clear_block = ff_clear_block_sse;
+ c->clear_blocks = ff_clear_blocks_sse;
+#if FF_API_XVMC
}
+#endif /* FF_API_XVMC */
}
c->vector_clipf = ff_vector_clipf_sse;
diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h
index 1f77e4e..950ed18 100644
--- a/libavcodec/xvmc.h
+++ b/libavcodec/xvmc.h
@@ -29,8 +29,12 @@
#include <X11/extensions/XvMC.h>
+#include "libavutil/attributes.h"
+#include "version.h"
#include "avcodec.h"
+#if FF_API_XVMC
+
/**
* @defgroup lavc_codec_hwaccel_xvmc XvMC
* @ingroup lavc_codec_hwaccel
@@ -41,7 +45,7 @@
#define AV_XVMC_ID 0x1DC711C0 /**< special value to ensure that regular pixel routines haven't corrupted the struct
the number is 1337 speak for the letters IDCT MCo (motion compensation) */
-struct xvmc_pix_fmt {
+attribute_deprecated struct xvmc_pix_fmt {
/** The field contains the special constant value AV_XVMC_ID.
It is used as a test that the application correctly uses the API,
and that there is no corruption caused by pixel routines.
@@ -165,4 +169,6 @@ struct xvmc_pix_fmt {
* @}
*/
+#endif /* FF_API_XVMC */
+
#endif /* AVCODEC_XVMC_H */
diff --git a/libavcodec/xvmc_internal.h b/libavcodec/xvmc_internal.h
index 3c6aed8..9018e4a 100644
--- a/libavcodec/xvmc_internal.h
+++ b/libavcodec/xvmc_internal.h
@@ -23,6 +23,9 @@
#include "avcodec.h"
#include "mpegvideo.h"
+#include "version.h"
+
+#if FF_API_XVMC
void ff_xvmc_init_block(MpegEncContext *s);
void ff_xvmc_pack_pblocks(MpegEncContext *s, int cbp);
@@ -30,4 +33,6 @@ int ff_xvmc_field_start(MpegEncContext*s, AVCodecContext *avctx);
void ff_xvmc_field_end(MpegEncContext *s);
void ff_xvmc_decode_mb(MpegEncContext *s);
+#endif /* FF_API_XVMC */
+
#endif /* AVCODEC_XVMC_INTERNAL_H */
diff --git a/libavutil/old_pix_fmts.h b/libavutil/old_pix_fmts.h
index a0ae06b..d3e1e5b 100644
--- a/libavutil/old_pix_fmts.h
+++ b/libavutil/old_pix_fmts.h
@@ -42,8 +42,10 @@
PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 49c9072..37ce173 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -27,6 +27,7 @@
#include "pixdesc.h"
#include "internal.h"
#include "intreadwrite.h"
+#include "version.h"
void av_read_image_line(uint16_t *dst,
const uint8_t *data[4], const int linesize[4],
@@ -299,6 +300,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
},
.flags = AV_PIX_FMT_FLAG_PLANAR,
},
+#if FF_API_XVMC
[AV_PIX_FMT_XVMC_MPEG2_MC] = {
.name = "xvmcmc",
.flags = AV_PIX_FMT_FLAG_HWACCEL,
@@ -307,6 +309,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
.name = "xvmcidct",
.flags = AV_PIX_FMT_FLAG_HWACCEL,
},
+#endif /* FF_API_XVMC */
[AV_PIX_FMT_UYVY422] = {
.name = "uyvy422",
.nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 43633e7..0d6e0a3 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -77,8 +77,10 @@ enum AVPixelFormat {
AV_PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV420P and setting color_range
AV_PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV422P and setting color_range
AV_PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of PIX_FMT_YUV444P and setting color_range
+#if FF_API_XVMC
AV_PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing
AV_PIX_FMT_XVMC_MPEG2_IDCT,
+#endif /* FF_API_XVMC */
AV_PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
AV_PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
AV_PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb)
diff --git a/libavutil/version.h b/libavutil/version.h
index aa13a0f..4fabb1b 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -88,6 +88,9 @@
#ifndef FF_API_VDPAU
#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 53)
#endif
+#ifndef FF_API_XVMC
+#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 53)
+#endif
/**
* @}
3
2
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Sat Nov 30 09:37:14 2013 -0500| [f068aed7b8d7eac31da22d88f359e9b844c04b47] | committer: Ronald S. Bultje
vp9: make decode_coeffs() return value void.
It was previously int and would return error if decode_coeffs_b()
returns an error; however, that can never happen, so refactor all
that code to make all dependent functions return void also (all the
way up to decode_coeffs_sb()).
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=f068aed7b8d7eac31…
---
libavcodec/vp9.c | 151 ++++++++++++++++++++++--------------------------------
1 file changed, 61 insertions(+), 90 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 918aa61..a52924c 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -1986,7 +1986,7 @@ static int decode_coeffs_b(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
return i;
}
-static int decode_coeffs(AVCodecContext *ctx)
+static void decode_coeffs(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
VP9Block *b = s->b;
@@ -2031,10 +2031,9 @@ static int decode_coeffs(AVCodecContext *ctx)
b->bs > BS_8x8 ?
n : 0]];
int nnz = a[x] + l[y];
- if ((res = decode_coeffs_b(&s->c, s->block + 16 * n, 16 * step,
- b->tx, c, e, p, nnz, yscans[txtp],
- ynbs[txtp], y_band_counts, qmul[0])) < 0)
- return res;
+ res = decode_coeffs_b(&s->c, s->block + 16 * n, 16 * step,
+ b->tx, c, e, p, nnz, yscans[txtp],
+ ynbs[txtp], y_band_counts, qmul[0]);
a[x] = l[y] = !!res;
if (b->tx > TX_8X8) {
AV_WN16A(&s->eob[n], res);
@@ -2071,11 +2070,9 @@ static int decode_coeffs(AVCodecContext *ctx)
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
for (x = 0; x < end_x; x += uvstep1d, n += uvstep) {
int nnz = a[x] + l[y];
- if ((res = decode_coeffs_b(&s->c, s->uvblock[pl] + 16 * n,
- 16 * uvstep, b->uvtx, c, e, p, nnz,
- uvscan, uvnb, uv_band_counts,
- qmul[1])) < 0)
- return res;
+ res = decode_coeffs_b(&s->c, s->uvblock[pl] + 16 * n,
+ 16 * uvstep, b->uvtx, c, e, p, nnz,
+ uvscan, uvnb, uv_band_counts, qmul[1]);
a[x] = l[y] = !!res;
if (b->uvtx > TX_8X8) {
AV_WN16A(&s->uveob[pl][n], res);
@@ -2091,8 +2088,6 @@ static int decode_coeffs(AVCodecContext *ctx)
memset(&a[x + 1], a[x], FFMIN(end_x - x - 1, uvstep1d - 1));
}
}
-
- return 0;
}
static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a,
@@ -2696,14 +2691,14 @@ static av_always_inline void mask_edges(struct VP9Filter *lflvl, int is_uv,
}
}
-static int decode_b(AVCodecContext *ctx, int row, int col,
- struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
- enum BlockLevel bl, enum BlockPartition bp)
+static void decode_b(AVCodecContext *ctx, int row, int col,
+ struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
+ enum BlockLevel bl, enum BlockPartition bp)
{
VP9Context *s = ctx->priv_data;
VP9Block *b = s->b;
enum BlockSize bs = bl * 3 + bp;
- int res, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
+ int y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
AVFrame *f = s->frames[CUR_FRAME].tf.f;
@@ -2723,8 +2718,7 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
if (!b->skip) {
- if ((res = decode_coeffs(ctx)) < 0)
- return res;
+ decode_coeffs(ctx);
} else {
int pl;
@@ -2744,7 +2738,7 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
s->uveob[0] += w4 * h4;
s->uveob[1] += w4 * h4;
- return 0;
+ return;
}
}
@@ -2846,16 +2840,14 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
s->uveob[0] += w4 * h4;
s->uveob[1] += w4 * h4;
}
-
- return 0;
}
-static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
- ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
{
VP9Context *s = ctx->priv_data;
int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) |
- (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1), res;
+ (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
const uint8_t *p = s->keyframe ? vp9_default_kf_partition_probs[bl][c] :
s->prob.p.partition[bl][c];
enum BlockPartition bp;
@@ -2865,128 +2857,111 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
if (bl == BL_8X8) {
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
} else if (col + hbs < s->cols) { // FIXME why not <=?
if (row + hbs < s->rows) { // FIXME why not <=?
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
switch (bp) {
case PARTITION_NONE:
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_H:
- if (!(res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp))) {
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 4 * uv_stride;
- res = decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
- }
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_V:
- if (!(res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp))) {
- yoff += hbs * 8;
- uvoff += hbs * 4;
- res = decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
- }
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
break;
case PARTITION_SPLIT:
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
- if (!(res = decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1))) {
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 4 * uv_stride;
- if (!(res = decode_sb(ctx, row + hbs, col, lflvl,
- yoff, uvoff, bl + 1)))
- res = decode_sb(ctx, row + hbs, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
- }
- }
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
break;
default:
av_assert0(0);
}
} else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
bp = PARTITION_SPLIT;
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1)))
- res = decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
} else {
bp = PARTITION_H;
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
}
} else if (row + hbs < s->rows) { // FIXME why not <=?
if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
bp = PARTITION_SPLIT;
- if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 4 * uv_stride;
- res = decode_sb(ctx, row + hbs, col, lflvl,
- yoff, uvoff, bl + 1);
- }
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
} else {
bp = PARTITION_V;
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
}
} else {
bp = PARTITION_SPLIT;
- res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
}
s->counts.partition[bl][c][bp]++;
-
- return res;
}
-static int decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
- ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
{
VP9Context *s = ctx->priv_data;
VP9Block *b = s->b;
ptrdiff_t hbs = 4 >> bl;
AVFrame *f = s->frames[CUR_FRAME].tf.f;
ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
- int res;
if (bl == BL_8X8) {
av_assert2(b->bl == BL_8X8);
- res = decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
} else if (s->b->bl == bl) {
- if ((res = decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp)) < 0)
- return res;
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
if (b->bp == PARTITION_H && row + hbs < s->rows) {
yoff += hbs * 8 * y_stride;
uvoff += hbs * 4 * uv_stride;
- res = decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
} else if (b->bp == PARTITION_V && col + hbs < s->cols) {
yoff += hbs * 8;
uvoff += hbs * 4;
- res = decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
}
} else {
- if ((res = decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1)) < 0)
- return res;
+ decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
if (col + hbs < s->cols) { // FIXME why not <=?
if (row + hbs < s->rows) {
- if ((res = decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs,
- uvoff + 4 * hbs, bl + 1)) < 0)
- return res;
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs,
+ uvoff + 4 * hbs, bl + 1);
yoff += hbs * 8 * y_stride;
uvoff += hbs * 4 * uv_stride;
- if ((res = decode_sb_mem(ctx, row + hbs, col, lflvl, yoff,
- uvoff, bl + 1)) < 0)
- return res;
- res = decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
} else {
yoff += hbs * 8;
uvoff += hbs * 4;
- res = decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
}
} else if (row + hbs < s->rows) {
yoff += hbs * 8 * y_stride;
uvoff += hbs * 4 * uv_stride;
- res = decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
}
}
-
- return res;
}
static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
@@ -3652,15 +3627,11 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
}
if (s->pass == 2) {
- res = decode_sb_mem(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64);
+ decode_sb_mem(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
} else {
- res = decode_sb(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64);
- }
- if (res < 0) {
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
- return res;
+ decode_sb(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
}
}
if (s->pass != 2) {
1
0
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Fri Nov 29 18:51:27 2013 -0500| [65f41b5c5cdb22e60a83321fe564ebb0155a35ce] | committer: Ronald S. Bultje
vp9: add a new segmentation sample.
The old one didn't use segmentation. One uses segmentation in all frame
types (--aq-mode=1), and the other uses all segmentation features, but
only in inter frames (mbgraph).
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=65f41b5c5cdb22e60…
---
tests/fate/vpx.mak | 3 +-
tests/ref/fate/vp9-segmentation-akiyo | 55 ------------------------------
tests/ref/fate/vp9-segmentation-aq-akiyo | 30 ++++++++++++++++
tests/ref/fate/vp9-segmentation-sf-akiyo | 30 ++++++++++++++++
4 files changed, 62 insertions(+), 56 deletions(-)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index 1602cc2..de0b58f 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -79,7 +79,8 @@ $(foreach W,$(VP9_SIZE_A),$(eval $(foreach H,$(VP9_SIZE_A),$(eval $(call FATE_VP
$(foreach W,$(VP9_SIZE_B),$(eval $(foreach H,$(VP9_SIZE_B),$(eval $(call FATE_VP9_SUITE,03-size-$(W)x$(H),$(1),$(2))))))
$(eval $(call FATE_VP9_SUITE,03-deltaq,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,2pass-akiyo,$(1),$(2)))
-$(eval $(call FATE_VP9_SUITE,segmentation-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,segmentation-sf-akiyo,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,segmentation-aq-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,parallelmode-akiyo,$(1),$(2)))
endef
diff --git a/tests/ref/fate/vp9-segmentation-akiyo b/tests/ref/fate/vp9-segmentation-akiyo
deleted file mode 100644
index b850754..0000000
--- a/tests/ref/fate/vp9-segmentation-akiyo
+++ /dev/null
@@ -1,55 +0,0 @@
-#format: frame checksums
-#version: 1
-#hash: MD5
-#tb 0: 1001/30000
-#stream#, dts, pts, duration, size, hash
-0, 0, 0, 1, 152064, 20cf714300c5e28ffb77bf9c682129bc
-0, 1, 1, 1, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
-0, 2, 2, 1, 152064, 2f271e4de29f87d6b90511fbafdf9fbb
-0, 3, 3, 1, 152064, a88532a043f5f2c6bce729a8e20ee5af
-0, 4, 4, 1, 152064, 8d7b5482ed8072a7c95d722783773436
-0, 5, 5, 1, 152064, 04872d8619b163b5e0c20123ccddf7dc
-0, 6, 6, 1, 152064, ed6d9677782aa6e87b6576541391557f
-0, 7, 7, 1, 152064, 689f71108e9bf024cd9ccf48800dcdc7
-0, 8, 8, 1, 152064, f7c555792884499bb62a8e739b201739
-0, 9, 9, 1, 152064, 7fed82c38ce428a178c56f6131eff5ec
-0, 10, 10, 1, 152064, fb638e587ade05baa027bb63edc7ec7c
-0, 11, 11, 1, 152064, 319295f5aa44661a80570e844050156a
-0, 12, 12, 1, 152064, de2d8635966a1cd57290eac449a5fb4b
-0, 13, 13, 1, 152064, 9ac3d711a00aac6b17004bb6451e4cab
-0, 14, 14, 1, 152064, d12eced084e72b5230493e2dc2de0f0a
-0, 15, 15, 1, 152064, 197761d11407fed723a63b8e28cb8e19
-0, 16, 16, 1, 152064, 28d8e807bc142b74f1eaf30dbbf1b7bd
-0, 17, 17, 1, 152064, abe88f1f7490d13ba3def9511beaceec
-0, 18, 18, 1, 152064, 7d297b9c989ebc0408fd41b14900242a
-0, 19, 19, 1, 152064, d5e7adfa2b207d860feff5c894585fd1
-0, 20, 20, 1, 152064, aea3e9de9de237f8379785f3467dc9c9
-0, 21, 21, 1, 152064, 211967cd949c1d83a8cc4c8267aa6034
-0, 22, 22, 1, 152064, 3f49bf8e0434114c15b867be2d53d283
-0, 23, 23, 1, 152064, 8d5e629c0e941ca6f049ed2bb59d09a8
-0, 24, 24, 1, 152064, d359620957877534bc94cd137dc652fe
-0, 25, 25, 1, 152064, 83610fc1969fdfa267e7e462a83ea40c
-0, 26, 26, 1, 152064, b2d20dcc3f77a238ce7210991eebe1a7
-0, 27, 27, 1, 152064, a42ad37808f30e1d968882bf42e9c641
-0, 28, 28, 1, 152064, 55084cded938266a2c3c658dcc162781
-0, 29, 29, 1, 152064, e392a3a7d33e10e95fc9cdf0a2080eac
-0, 30, 30, 1, 152064, 73977c4827463c17e63c0769bb90722f
-0, 31, 31, 1, 152064, cb5dd87344af7d6fd4ed0e06cb90d9c2
-0, 32, 32, 1, 152064, 533338860124e392cef2039468c22f75
-0, 33, 33, 1, 152064, da30f077490042367502a6fe11a46e0f
-0, 34, 34, 1, 152064, 860ab1bfbd3fe6a27bee5ef8c4e0b600
-0, 35, 35, 1, 152064, 339ec3863eaed689d46289ffe47bc45d
-0, 36, 36, 1, 152064, ffa6c990577093106796ed0dee56c483
-0, 37, 37, 1, 152064, 3fcdc2bc064c79f35ea81a715ff089d0
-0, 38, 38, 1, 152064, adaef9ec97e23a542db22bcd23c740bd
-0, 39, 39, 1, 152064, ddcff4bd2c9579181182eb49add0ce3c
-0, 40, 40, 1, 152064, b3b039c84cffb9272c8ddf9086748696
-0, 41, 41, 1, 152064, 70939a961ec1e4697031b79e7ebb7919
-0, 42, 42, 1, 152064, 6b3ff2e003749c6ffeb2d71edecf884c
-0, 43, 43, 1, 152064, 5e4efc96971f81218c472482b5a79374
-0, 44, 44, 1, 152064, 279132c87d81a5747824b06423bf6785
-0, 45, 45, 1, 152064, 1da48caa08007523aab41a56e21dd99b
-0, 46, 46, 1, 152064, 36ecffb2bfcb587d2556fddcbbd3448b
-0, 47, 47, 1, 152064, 7823e3c86cd5a05c2959c7ef4d1cfa89
-0, 48, 48, 1, 152064, b53f78afbad1a43f7aea58814eacd824
-0, 49, 49, 1, 152064, b9b127b4bc54123bec19b2f4a3fa157c
diff --git a/tests/ref/fate/vp9-segmentation-aq-akiyo b/tests/ref/fate/vp9-segmentation-aq-akiyo
new file mode 100644
index 0000000..5c931b6
--- /dev/null
+++ b/tests/ref/fate/vp9-segmentation-aq-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, b208eac12f0ae74a812bc9e314bdfac7
+0, 1, 1, 1, 152064, ebb2259451c3acf3ad6379d1f4092efb
+0, 2, 2, 1, 152064, 33de46060afd14aa359b7bd0d9ff1be8
+0, 3, 3, 1, 152064, 33de46060afd14aa359b7bd0d9ff1be8
+0, 4, 4, 1, 152064, 5d087d8df10fd406d59172710ea0341a
+0, 5, 5, 1, 152064, 3570ed7fb90ac9b5335b97adf0539e94
+0, 6, 6, 1, 152064, 68a8c56b889a3befc75c9ec4293c7fda
+0, 7, 7, 1, 152064, f871f7c0456f644cfb0ec896132a097f
+0, 8, 8, 1, 152064, 14e939bfeb2b878e0782a7ce68ecd214
+0, 9, 9, 1, 152064, bd3e97881ebece0f876d46d067c6a7ff
+0, 10, 10, 1, 152064, a20529c091ef3e68a901c574371224b3
+0, 11, 11, 1, 152064, 5253f16c8b0329d33d38d275124487fb
+0, 12, 12, 1, 152064, c9c2f7d8835e620709a53ff8adfe72bf
+0, 13, 13, 1, 152064, dc8f1df0d7ab8e4f9daf2ccfd96de855
+0, 14, 14, 1, 152064, d09d43208d4de7f81d54f48cff310b6f
+0, 15, 15, 1, 152064, 0dcf7212075c1f15219690ad6ffe2940
+0, 16, 16, 1, 152064, 3b52e3eb4f972318c6912dd29a95dcf3
+0, 17, 17, 1, 152064, aa1414343067749fbd743ace93553492
+0, 18, 18, 1, 152064, 6951cb7a78e0a03f9a3f6264084de6dc
+0, 19, 19, 1, 152064, 5324f2f03c4d5fe35446561af654e9ec
+0, 20, 20, 1, 152064, dff11b046a02ca34c6b1aecc857632ec
+0, 21, 21, 1, 152064, 971182c013c1524d4864fd946b8c1550
+0, 22, 22, 1, 152064, 3306f1dcd5760ba92dd9cec8bfc21b08
+0, 23, 23, 1, 152064, f1f7b13c33332fece576b4d175f91832
+0, 24, 24, 1, 152064, 9e66573fbfe847149eb32e8a9c242c18
diff --git a/tests/ref/fate/vp9-segmentation-sf-akiyo b/tests/ref/fate/vp9-segmentation-sf-akiyo
new file mode 100644
index 0000000..0fdb3f2
--- /dev/null
+++ b/tests/ref/fate/vp9-segmentation-sf-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, f4e04a0f92fab3a52d858bb222807ac0
+0, 1, 1, 1, 152064, 493cb96b8202a1518c6c9bdb848540e4
+0, 2, 2, 1, 152064, 60b5b63f832cff119a43de82102758f4
+0, 3, 3, 1, 152064, 0d9bd42e279d480603f9c670f0a8ffe3
+0, 4, 4, 1, 152064, 25ca563f233688f32f40fec985a116a2
+0, 5, 5, 1, 152064, dd14b43d538708a91de41606703dbe1c
+0, 6, 6, 1, 152064, 01bb23cb43960ff185a97ea79936d3b4
+0, 7, 7, 1, 152064, 85045c4310ee80cd12979bdea4f3f86e
+0, 8, 8, 1, 152064, c8e015ea13359a05483de349313a6686
+0, 9, 9, 1, 152064, 8dbb0406bf6fe19c30a9c9253fcdfe7f
+0, 10, 10, 1, 152064, 84881463643069036d03e8120a5f15e9
+0, 11, 11, 1, 152064, 9abcd3f2f86ff31f8d357389b330df59
+0, 12, 12, 1, 152064, 19ada6395c4e656578d2ceeaba291bb2
+0, 13, 13, 1, 152064, fc29773a6f32eed2bfa44143f8f505b1
+0, 14, 14, 1, 152064, 5e56bd91f5e3d1457c124b5702bdc3b6
+0, 15, 15, 1, 152064, 5b920d73e301adb6c45699a209f09a33
+0, 16, 16, 1, 152064, 4d06ec294270638c6abdd1c2303b34fc
+0, 17, 17, 1, 152064, dc99797067851f74708d7e6ff54367d8
+0, 18, 18, 1, 152064, 5df68b49124219592b043916affb1311
+0, 19, 19, 1, 152064, cfb52d101fad76acb1bb0d48c513bffd
+0, 20, 20, 1, 152064, 206dbd55680b8a83d8bafe33c54c3e36
+0, 21, 21, 1, 152064, 171f2e26771db631788065eecf6c44d9
+0, 22, 22, 1, 152064, b10809dcf9ecfdb4f86a6f3236ac273e
+0, 23, 23, 1, 152064, b354107bdea9bd011b09d9f4a32d4e89
+0, 24, 24, 1, 152064, 0c18be13dc6fbf79a613f2b24bb301c1
1
0
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Thu Nov 28 16:26:14 2013 -0500| [1d6bb21348711a05f25123b9aad065a08e1e5b58] | committer: Ronald S. Bultje
vp9: add fate sample for parallelmode.
This disables backward probability updates, which makes the codec more
friendly for frame-level multi-threading.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1d6bb21348711a05f…
---
tests/fate/vpx.mak | 1 +
tests/ref/fate/vp9-parallelmode-akiyo | 30 ++++++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index 4dc0640..1602cc2 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -81,6 +81,7 @@ $(eval $(call FATE_VP9_SUITE,03-deltaq,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,2pass-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,segmentation-akiyo,$(1),$(2)))
$(eval $(call FATE_VP9_SUITE,tiling-pedestrian,$(1),$(2)))
+$(eval $(call FATE_VP9_SUITE,parallelmode-akiyo,$(1),$(2)))
endef
$(eval $(call FATE_VP9_FULL))
diff --git a/tests/ref/fate/vp9-parallelmode-akiyo b/tests/ref/fate/vp9-parallelmode-akiyo
new file mode 100644
index 0000000..9668c54
--- /dev/null
+++ b/tests/ref/fate/vp9-parallelmode-akiyo
@@ -0,0 +1,30 @@
+#format: frame checksums
+#version: 1
+#hash: MD5
+#tb 0: 1001/30000
+#stream#, dts, pts, duration, size, hash
+0, 0, 0, 1, 152064, f5bc602db15c69545307e56990f9f9f7
+0, 1, 1, 1, 152064, b56428b6f97669938c8b9b05458fca70
+0, 2, 2, 1, 152064, b56428b6f97669938c8b9b05458fca70
+0, 3, 3, 1, 152064, 3098d2eb9129beddb6975e3ae332a4ab
+0, 4, 4, 1, 152064, 6719f3a6c22f05dc53dd3906e4154bd7
+0, 5, 5, 1, 152064, 8cd9a12761e35f67c278949cd3aee88f
+0, 6, 6, 1, 152064, 8cd9a12761e35f67c278949cd3aee88f
+0, 7, 7, 1, 152064, 0160dec415234d39f148e91f72d264ab
+0, 8, 8, 1, 152064, 9f90d96d67d9e9b3716abe2a3faa854e
+0, 9, 9, 1, 152064, 1edb312f9d0be7835b964a3ffa014759
+0, 10, 10, 1, 152064, 7614fd674609afccacd355aa2f714c75
+0, 11, 11, 1, 152064, cb46868706dd246878bebf354aff66f4
+0, 12, 12, 1, 152064, da36fe96cb4956036f890bb2f6d05b98
+0, 13, 13, 1, 152064, af0a178c68b719b369c8fa8537d38e65
+0, 14, 14, 1, 152064, ff03dbc436376fc60ac240cd6c4fc518
+0, 15, 15, 1, 152064, b0bf25e139556bd9067616db7e4f47b5
+0, 16, 16, 1, 152064, e70d5480c1f82fc877bbe1a8093f807a
+0, 17, 17, 1, 152064, 622fb43e6ff63834f0f680a68b49f6e6
+0, 18, 18, 1, 152064, c331ebba15f2290f174533dbffb3c27b
+0, 19, 19, 1, 152064, 15cb153425c55f7065fb36606c48972e
+0, 20, 20, 1, 152064, b95c7699639c51b08b3615ef7fa7046c
+0, 21, 21, 1, 152064, b4774148c71c9c184bda5a18294e459c
+0, 22, 22, 1, 152064, 795b7ce4c5e0dc343bd8f80ad6c1a454
+0, 23, 23, 1, 152064, 19163601b7b6138e2940cf28f6df6c7f
+0, 24, 24, 1, 152064, b9b388e0892c52df0680a30bfa954506
1
0
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Mon Nov 25 07:31:57 2013 -0500| [47c6d9403d9dc96d6d9a58968ca1fc3a9f165417] | committer: Ronald S. Bultje
vp9: cosmetics.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=47c6d9403d9dc96d6…
---
libavcodec/vp9.c | 146 +++++++++++++++++++++++++++---------------------------
1 file changed, 73 insertions(+), 73 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 417833b..918aa61 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -3593,62 +3593,62 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
s->uveob[0] = s->uveob_base[0];
s->uveob[1] = s->uveob_base[1];
- for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
- set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
- tile_row, s->tiling.log2_tile_rows, s->sb_rows);
+ for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
+ set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
+ tile_row, s->tiling.log2_tile_rows, s->sb_rows);
if (s->pass != 2) {
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- unsigned tile_size;
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ unsigned tile_size;
- if (tile_col == s->tiling.tile_cols - 1 &&
- tile_row == s->tiling.tile_rows - 1) {
- tile_size = size;
- } else {
- tile_size = AV_RB32(data);
- data += 4;
- size -= 4;
- }
- if (tile_size > size)
- return AVERROR_INVALIDDATA;
- ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
- if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
- return AVERROR_INVALIDDATA;
- data += tile_size;
- size -= tile_size;
- }
+ if (tile_col == s->tiling.tile_cols - 1 &&
+ tile_row == s->tiling.tile_rows - 1) {
+ tile_size = size;
+ } else {
+ tile_size = AV_RB32(data);
+ data += 4;
+ size -= 4;
+ }
+ if (tile_size > size)
+ return AVERROR_INVALIDDATA;
+ ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
+ if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) // marker bit
+ return AVERROR_INVALIDDATA;
+ data += tile_size;
+ size -= tile_size;
+ }
}
- for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
- row += 8, yoff += ls_y * 64, uvoff += ls_uv * 32) {
- struct VP9Filter *lflvl_ptr = s->lflvl;
- ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
+ for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
+ row += 8, yoff += ls_y * 64, uvoff += ls_uv * 32) {
+ struct VP9Filter *lflvl_ptr = s->lflvl;
+ ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
- tile_col, s->tiling.log2_tile_cols, s->sb_cols);
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
+ tile_col, s->tiling.log2_tile_cols, s->sb_cols);
if (s->pass != 2) {
- memset(s->left_partition_ctx, 0, 8);
- memset(s->left_skip_ctx, 0, 8);
- if (s->keyframe || s->intraonly) {
- memset(s->left_mode_ctx, DC_PRED, 16);
- } else {
- memset(s->left_mode_ctx, NEARESTMV, 8);
- }
- memset(s->left_y_nnz_ctx, 0, 16);
- memset(s->left_uv_nnz_ctx, 0, 16);
- memset(s->left_segpred_ctx, 0, 8);
+ memset(s->left_partition_ctx, 0, 8);
+ memset(s->left_skip_ctx, 0, 8);
+ if (s->keyframe || s->intraonly) {
+ memset(s->left_mode_ctx, DC_PRED, 16);
+ } else {
+ memset(s->left_mode_ctx, NEARESTMV, 8);
+ }
+ memset(s->left_y_nnz_ctx, 0, 16);
+ memset(s->left_uv_nnz_ctx, 0, 16);
+ memset(s->left_segpred_ctx, 0, 8);
- memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
+ memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
}
- for (col = s->tiling.tile_col_start;
- col < s->tiling.tile_col_end;
- col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
- // FIXME integrate with lf code (i.e. zero after each
- // use, similar to invtxfm coefficients, or similar)
+ for (col = s->tiling.tile_col_start;
+ col < s->tiling.tile_col_end;
+ col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
+ // FIXME integrate with lf code (i.e. zero after each
+ // use, similar to invtxfm coefficients, or similar)
if (s->pass != 1) {
- memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
+ memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
}
if (s->pass == 2) {
@@ -3656,53 +3656,53 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
yoff2, uvoff2, BL_64X64);
} else {
res = decode_sb(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64);
+ yoff2, uvoff2, BL_64X64);
}
if (res < 0) {
ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
return res;
}
- }
+ }
if (s->pass != 2) {
- memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
+ memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
}
- }
+ }
if (s->pass == 1) {
continue;
}
- // backup pre-loopfilter reconstruction data for intra
- // prediction of next row of sb64s
- if (row + 8 < s->rows) {
- memcpy(s->intra_pred_data[0],
- f->data[0] + yoff + 63 * ls_y,
- 8 * s->cols);
- memcpy(s->intra_pred_data[1],
- f->data[1] + uvoff + 31 * ls_uv,
- 4 * s->cols);
- memcpy(s->intra_pred_data[2],
- f->data[2] + uvoff + 31 * ls_uv,
- 4 * s->cols);
- }
-
- // loopfilter one row
- if (s->filter.level) {
- yoff2 = yoff;
- uvoff2 = uvoff;
- lflvl_ptr = s->lflvl;
- for (col = 0; col < s->cols;
- col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
- loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
+ // backup pre-loopfilter reconstruction data for intra
+ // prediction of next row of sb64s
+ if (row + 8 < s->rows) {
+ memcpy(s->intra_pred_data[0],
+ f->data[0] + yoff + 63 * ls_y,
+ 8 * s->cols);
+ memcpy(s->intra_pred_data[1],
+ f->data[1] + uvoff + 31 * ls_uv,
+ 4 * s->cols);
+ memcpy(s->intra_pred_data[2],
+ f->data[2] + uvoff + 31 * ls_uv,
+ 4 * s->cols);
+ }
+
+ // loopfilter one row
+ if (s->filter.level) {
+ yoff2 = yoff;
+ uvoff2 = uvoff;
+ lflvl_ptr = s->lflvl;
+ for (col = 0; col < s->cols;
+ col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
+ loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
+ }
}
- }
// FIXME maybe we can make this more finegrained by running the
// loopfilter per-block instead of after each sbrow
// In fact that would also make intra pred left preparation easier?
ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0);
+ }
}
- }
if (s->pass < 2 && s->refreshctx && !s->parallelmode) {
adapt_probs(s);
1
0
30 Nov '13
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Sat Nov 23 12:10:12 2013 -0500| [46955ae43087bcd2d27fc262bbaa4c96ba46fe2d] | committer: Ronald S. Bultje
vp9: allocate 'b', 'block/uvblock' and 'eob/uveob' dynamically.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=46955ae43087bcd2d…
---
libavcodec/vp9.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index df9b197..0202f3fa9 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -98,7 +98,7 @@ typedef struct VP9Context {
VP56RangeCoder c;
VP56RangeCoder *c_b;
unsigned c_b_size;
- VP9Block b;
+ VP9Block *b_base, *b;
int row, row7, col, col7;
uint8_t *dst[3];
ptrdiff_t y_stride, uv_stride;
@@ -228,10 +228,8 @@ typedef struct VP9Context {
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
// block reconstruction intermediates
- DECLARE_ALIGNED(32, int16_t, block)[4096];
- DECLARE_ALIGNED(32, int16_t, uvblock)[2][1024];
- uint8_t eob[256];
- uint8_t uveob[2][64];
+ int16_t *block_base, *block, *uvblock_base[2], *uvblock[2];
+ uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2];
VP56mv min_mv, max_mv;
DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64];
DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32];
@@ -330,6 +328,18 @@ static int update_size(AVCodecContext *ctx, int w, int h)
assign(s->above_mv_ctx, VP56mv(*)[2], 16);
#undef assign
+ av_free(s->b_base);
+ av_free(s->block_base);
+ s->b_base = av_malloc(sizeof(VP9Block));
+ s->block_base = av_mallocz((64 * 64 + 128) * 3);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + 64 * 64;
+ s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32);
+ s->uveob_base[0] = s->eob_base + 256;
+ s->uveob_base[1] = s->uveob_base[0] + 64;
+
return 0;
}
@@ -908,7 +918,7 @@ static void find_ref_mvs(VP9Context *s,
[BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
};
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
int row = s->row, col = s->col, row7 = s->row7;
const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
#define INVALID_MV 0x80008000U
@@ -1121,7 +1131,7 @@ static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp)
static void fill_mv(VP9Context *s,
VP56mv *mv, int mode, int sb)
{
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
if (mode == ZEROMV) {
memset(mv, 0, sizeof(*mv) * 2);
@@ -1204,7 +1214,7 @@ static void decode_mode(AVCodecContext *ctx)
TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4
};
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
int row = s->row, col = s->col, row7 = s->row7;
enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
int w4 = FFMIN(s->cols - col, bwh_tab[1][b->bs][0]);
@@ -1952,7 +1962,7 @@ static int decode_coeffs_b(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
static int decode_coeffs(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
int row = s->row, col = s->col;
uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
@@ -2196,7 +2206,7 @@ static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **
static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
int row = s->row, col = s->col;
int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
@@ -2337,7 +2347,7 @@ static void inter_recon(AVCodecContext *ctx)
{ 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 },
};
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
int row = s->row, col = s->col;
ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]];
AVFrame *ref1 = tref1->f;
@@ -2654,7 +2664,7 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
enum BlockLevel bl, enum BlockPartition bp)
{
VP9Context *s = ctx->priv_data;
- VP9Block *const b = &s->b;
+ VP9Block *b = s->b;
enum BlockSize bs = bl * 3 + bp;
int res, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
@@ -3367,6 +3377,8 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx)
}
av_freep(&s->above_partition_ctx);
av_freep(&s->c_b);
+ av_freep(&s->b_base);
+ av_freep(&s->block_base);
return 0;
}
@@ -3433,6 +3445,13 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
memset(s->above_segpred_ctx, 0, s->cols);
+ s->b = s->b_base;
+ s->block = s->block_base;
+ s->uvblock[0] = s->uvblock_base[0];
+ s->uvblock[1] = s->uvblock_base[1];
+ s->eob = s->eob_base;
+ s->uveob[0] = s->uveob_base[0];
+ s->uveob[1] = s->uveob_base[1];
for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
tile_row, s->tiling.log2_tile_rows, s->sb_rows);
1
0
30 Nov '13
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Sat Nov 30 09:08:54 2013 -0500| [76bd878d959c79ef17ed90cc7d13dffea9327ee2] | committer: Ronald S. Bultje
vp9: add a 2-pass decoding mode, and add frame-mt support.
For a random 1080p sample, decoding time went from 9.7sec (1 threads)
to 6.0sec (2 threads) and 5.2sec (4 threads) in 2-pass decoding mode.
I don't have any samples that use the parallelmode feature, but the
gains should be higher.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=76bd878d959c79ef1…
---
libavcodec/vp9.c | 380 +++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 290 insertions(+), 90 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 0202f3fa9..417833b 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -88,7 +88,8 @@ typedef struct VP9Block {
VP56mv mv[4 /* b_idx */][2 /* ref */];
enum BlockSize bs;
enum TxfmMode tx, uvtx;
-
+ enum BlockLevel bl;
+ enum BlockPartition bp;
} VP9Block;
typedef struct VP9Context {
@@ -99,6 +100,7 @@ typedef struct VP9Context {
VP56RangeCoder *c_b;
unsigned c_b_size;
VP9Block *b_base, *b;
+ int pass, uses_2pass, last_uses_2pass;
int row, row7, col, col7;
uint8_t *dst[3];
ptrdiff_t y_stride, uv_stride;
@@ -261,6 +263,11 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
f->segmentation_map = f->extradata->data;
f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
+ // retain segmentation map if it doesn't update
+ if (s->segmentation.enabled && !s->segmentation.update_map) {
+ memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz);
+ }
+
return 0;
}
@@ -330,15 +337,29 @@ static int update_size(AVCodecContext *ctx, int w, int h)
av_free(s->b_base);
av_free(s->block_base);
- s->b_base = av_malloc(sizeof(VP9Block));
- s->block_base = av_mallocz((64 * 64 + 128) * 3);
- if (!s->b_base || !s->block_base)
- return AVERROR(ENOMEM);
- s->uvblock_base[0] = s->block_base + 64 * 64;
- s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32;
- s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32);
- s->uveob_base[0] = s->eob_base + 256;
- s->uveob_base[1] = s->uveob_base[0] + 64;
+ if (ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode) {
+ int sbs = s->sb_cols * s->sb_rows;
+
+ s->b_base = av_malloc(sizeof(VP9Block) * s->cols * s->rows);
+ s->block_base = av_mallocz((64 * 64 + 128) * sbs * 3);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + sbs * 64 * 64;
+ s->uvblock_base[1] = s->uvblock_base[0] + sbs * 32 * 32;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * 32 * 32);
+ s->uveob_base[0] = s->eob_base + 256 * sbs;
+ s->uveob_base[1] = s->uveob_base[0] + 64 * sbs;
+ } else {
+ s->b_base = av_malloc(sizeof(VP9Block));
+ s->block_base = av_mallocz((64 * 64 + 128) * 3);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + 64 * 64;
+ s->uvblock_base[1] = s->uvblock_base[0] + 32 * 32;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + 32 * 32);
+ s->uveob_base[0] = s->eob_base + 256;
+ s->uveob_base[1] = s->uveob_base[0] + 64;
+ }
return 0;
}
@@ -439,6 +460,7 @@ static int decode_frame_header(AVCodecContext *ctx,
*ref = get_bits(&s->gb, 3);
return 0;
}
+ s->last_uses_2pass = s->uses_2pass;
s->last_keyframe = s->keyframe;
s->keyframe = !get_bits1(&s->gb);
last_invisible = s->invisible;
@@ -1018,6 +1040,8 @@ static void find_ref_mvs(VP9Context *s,
if (s->use_last_frame_mvs) {
struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
+ if (!s->last_uses_2pass)
+ ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0);
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
} else if (mv->ref[1] == ref) {
@@ -1058,6 +1082,7 @@ static void find_ref_mvs(VP9Context *s,
if (s->use_last_frame_mvs) {
struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
+ // no need to await_progress, because we already did that above
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
}
@@ -1234,6 +1259,8 @@ static void decode_mode(AVCodecContext *ctx)
int pred = 8, x;
uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map;
+ if (!s->last_uses_2pass)
+ ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0);
for (y = 0; y < h4; y++)
for (x = 0; x < w4; x++)
pred = FFMIN(pred, refsegmap[(y + row) * 8 * s->sb_cols + x + col]);
@@ -2276,10 +2303,11 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
uint8_t *dst, ptrdiff_t dst_stride,
const uint8_t *ref, ptrdiff_t ref_stride,
+ ThreadFrame *ref_frame,
ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
int bw, int bh, int w, int h)
{
- int mx = mv->x, my = mv->y;
+ int mx = mv->x, my = mv->y, th;
y += my >> 3;
x += mx >> 3;
@@ -2287,6 +2315,10 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
mx &= 7;
my &= 7;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> 6;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
@@ -2305,10 +2337,11 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
ptrdiff_t dst_stride,
const uint8_t *ref_u, ptrdiff_t src_stride_u,
const uint8_t *ref_v, ptrdiff_t src_stride_v,
+ ThreadFrame *ref_frame,
ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
int bw, int bh, int w, int h)
{
- int mx = mv->x, my = mv->y;
+ int mx = mv->x, my = mv->y, th;
y += my >> 4;
x += mx >> 4;
@@ -2317,6 +2350,10 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func (*mc)[2],
mx &= 15;
my &= 15;
// FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> 5;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
if (x < !!mx * 3 || y < !!my * 3 ||
x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
@@ -2360,36 +2397,36 @@ static void inter_recon(AVCodecContext *ctx)
if (b->bs > BS_8x8) {
if (b->bs == BS_8x4) {
mc_luma_dir(s, s->dsp.mc[3][b->filter][0], s->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][0],
s->dst[0] + 4 * ls_y, ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[3][b->filter][1], s->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][1],
s->dst[0] + 4 * ls_y, ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);
}
} else if (b->bs == BS_4x8) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);
}
} else {
@@ -2398,34 +2435,34 @@ static void inter_recon(AVCodecContext *ctx)
// FIXME if two horizontally adjacent blocks have the same MV,
// do a w8 instead of a w4 call
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
s->dst[0] + 4 * ls_y, ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
s->dst[0] + 4 * ls_y + 4, ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
(row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);
if (b->comp) {
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
s->dst[0] + 4 * ls_y, ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
s->dst[0] + 4 * ls_y + 4, ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
(row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);
}
}
@@ -2434,12 +2471,12 @@ static void inter_recon(AVCodecContext *ctx)
int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;
mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], s->dst[0], ls_y,
- ref1->data[0], ref1->linesize[0],
+ ref1->data[0], ref1->linesize[0], tref1,
row << 3, col << 3, &b->mv[0][0],bw, bh, w, h);
if (b->comp)
mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], s->dst[0], ls_y,
- ref2->data[0], ref2->linesize[0],
+ ref2->data[0], ref2->linesize[0], tref2,
row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);
}
@@ -2461,7 +2498,7 @@ static void inter_recon(AVCodecContext *ctx)
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],
s->dst[1], s->dst[2], ls_uv,
ref1->data[1], ref1->linesize[1],
- ref1->data[2], ref1->linesize[2],
+ ref1->data[2], ref1->linesize[2], tref1,
row << 2, col << 2, &mvuv, bw, bh, w, h);
if (b->comp) {
@@ -2474,7 +2511,7 @@ static void inter_recon(AVCodecContext *ctx)
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],
s->dst[1], s->dst[2], ls_uv,
ref2->data[1], ref2->linesize[1],
- ref2->data[2], ref2->linesize[2],
+ ref2->data[2], ref2->linesize[2], tref2,
row << 2, col << 2, &mvuv, bw, bh, w, h);
}
}
@@ -2678,21 +2715,36 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
s->min_mv.y = -(128 + row * 64);
s->max_mv.x = 128 + (s->cols - col - w4) * 64;
s->max_mv.y = 128 + (s->rows - row - h4) * 64;
- b->bs = bs;
- decode_mode(ctx);
- b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
+ if (s->pass < 2) {
+ b->bs = bs;
+ b->bl = bl;
+ b->bp = bp;
+ decode_mode(ctx);
+ b->uvtx = b->tx - (w4 * 2 == (1 << b->tx) || h4 * 2 == (1 << b->tx));
+
+ if (!b->skip) {
+ if ((res = decode_coeffs(ctx)) < 0)
+ return res;
+ } else {
+ int pl;
- if (!b->skip) {
- if ((res = decode_coeffs(ctx)) < 0)
- return res;
- } else {
- int pl;
+ memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
+ memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
+ for (pl = 0; pl < 2; pl++) {
+ memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
+ memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
+ }
+ }
+ if (s->pass == 1) {
+ s->b++;
+ s->block += w4 * h4 * 64;
+ s->uvblock[0] += w4 * h4 * 16;
+ s->uvblock[1] += w4 * h4 * 16;
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += w4 * h4;
+ s->uveob[1] += w4 * h4;
- memset(&s->above_y_nnz_ctx[col * 2], 0, w4 * 2);
- memset(&s->left_y_nnz_ctx[(row & 7) << 1], 0, h4 * 2);
- for (pl = 0; pl < 2; pl++) {
- memset(&s->above_uv_nnz_ctx[pl][col], 0, w4);
- memset(&s->left_uv_nnz_ctx[pl][row & 7], 0, h4);
+ return 0;
}
}
@@ -2785,6 +2837,16 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
}
}
+ if (s->pass == 2) {
+ s->b++;
+ s->block += w4 * h4 * 64;
+ s->uvblock[0] += w4 * h4 * 16;
+ s->uvblock[1] += w4 * h4 * 16;
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += w4 * h4;
+ s->uveob[1] += w4 * h4;
+ }
+
return 0;
}
@@ -2804,8 +2866,8 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
if (bl == BL_8X8) {
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- } else if (col + hbs < s->cols) {
- if (row + hbs < s->rows) {
+ } else if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) { // FIXME why not <=?
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
switch (bp) {
case PARTITION_NONE:
@@ -2850,7 +2912,7 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
bp = PARTITION_H;
res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
}
- } else if (row + hbs < s->rows) {
+ } else if (row + hbs < s->rows) { // FIXME why not <=?
if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
bp = PARTITION_SPLIT;
if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
@@ -2872,6 +2934,61 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
return res;
}
+static int decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
+ int res;
+
+ if (bl == BL_8X8) {
+ av_assert2(b->bl == BL_8X8);
+ res = decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (s->b->bl == bl) {
+ if ((res = decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp)) < 0)
+ return res;
+ if (b->bp == PARTITION_H && row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ res = decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (b->bp == PARTITION_V && col + hbs < s->cols) {
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ res = decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
+ }
+ } else {
+ if ((res = decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1)) < 0)
+ return res;
+ if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) {
+ if ((res = decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs,
+ uvoff + 4 * hbs, bl + 1)) < 0)
+ return res;
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ if ((res = decode_sb_mem(ctx, row + hbs, col, lflvl, yoff,
+ uvoff, bl + 1)) < 0)
+ return res;
+ res = decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1);
+ } else {
+ yoff += hbs * 8;
+ uvoff += hbs * 4;
+ res = decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
+ }
+ } else if (row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
+ res = decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ }
+ }
+
+ return res;
+}
+
static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
{
@@ -3377,6 +3494,7 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx)
}
av_freep(&s->above_partition_ctx);
av_freep(&s->c_b);
+ s->c_b_size = 0;
av_freep(&s->b_base);
av_freep(&s->block_base);
@@ -3384,14 +3502,14 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx)
}
-static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
+static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
int *got_frame, AVPacket *pkt)
{
const uint8_t *data = pkt->data;
int size = pkt->size;
VP9Context *s = ctx->priv_data;
int res, tile_row, tile_col, i, ref, row, col;
- ptrdiff_t yoff = 0, uvoff = 0, ls_y, ls_uv;
+ ptrdiff_t yoff, uvoff, ls_y, ls_uv;
AVFrame *f;
if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
@@ -3425,13 +3543,17 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
ls_uv =f->linesize[1];
// ref frame setup
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 8; i++) {
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
if (s->refreshrefmask & (1 << i)) {
- if (s->next_refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->next_refs[i]);
- if ((res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf)) < 0)
- return res;
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf);
+ } else {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i]);
}
+ if (res < 0)
+ return res;
+ }
// main tile decode loop
memset(s->above_partition_ctx, 0, s->cols);
@@ -3445,16 +3567,36 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 8);
memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 8);
memset(s->above_segpred_ctx, 0, s->cols);
- s->b = s->b_base;
- s->block = s->block_base;
- s->uvblock[0] = s->uvblock_base[0];
- s->uvblock[1] = s->uvblock_base[1];
- s->eob = s->eob_base;
- s->uveob[0] = s->uveob_base[0];
- s->uveob[1] = s->uveob_base[1];
+ s->pass = s->uses_2pass =
+ ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode;
+ if (s->refreshctx && s->parallelmode) {
+ int j, k, l, m;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++)
+ memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
+ s->prob.coef[i][j][k][l][m], 3);
+ s->prob_ctx[s->framectxid].p = s->prob.p;
+ ff_thread_finish_setup(ctx);
+ }
+
+ do {
+ yoff = uvoff = 0;
+ s->b = s->b_base;
+ s->block = s->block_base;
+ s->uvblock[0] = s->uvblock_base[0];
+ s->uvblock[1] = s->uvblock_base[1];
+ s->eob = s->eob_base;
+ s->uveob[0] = s->uveob_base[0];
+ s->uveob[1] = s->uveob_base[1];
+
for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
tile_row, s->tiling.log2_tile_rows, s->sb_rows);
+ if (s->pass != 2) {
for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
unsigned tile_size;
@@ -3474,6 +3616,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
data += tile_size;
size -= tile_size;
}
+ }
for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
row += 8, yoff += ls_y * 64, uvoff += ls_uv * 32) {
@@ -3484,6 +3627,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
tile_col, s->tiling.log2_tile_cols, s->sb_cols);
+ if (s->pass != 2) {
memset(s->left_partition_ctx, 0, 8);
memset(s->left_skip_ctx, 0, 8);
if (s->keyframe || s->intraonly) {
@@ -3496,20 +3640,38 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
memset(s->left_segpred_ctx, 0, 8);
memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
+ }
+
for (col = s->tiling.tile_col_start;
col < s->tiling.tile_col_end;
col += 8, yoff2 += 64, uvoff2 += 32, lflvl_ptr++) {
// FIXME integrate with lf code (i.e. zero after each
// use, similar to invtxfm coefficients, or similar)
+ if (s->pass != 1) {
memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
+ }
- if ((res = decode_sb(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64)) < 0)
- return res;
+ if (s->pass == 2) {
+ res = decode_sb_mem(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ } else {
+ res = decode_sb(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ }
+ if (res < 0) {
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ return res;
+ }
}
+ if (s->pass != 2) {
memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
+ }
}
+ if (s->pass == 1) {
+ continue;
+ }
+
// backup pre-loopfilter reconstruction data for intra
// prediction of next row of sb64s
if (row + 8 < s->rows) {
@@ -3534,27 +3696,20 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
}
}
+
+ // FIXME maybe we can make this more finegrained by running the
+ // loopfilter per-block instead of after each sbrow
+ // In fact that would also make intra pred left preparation easier?
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0);
}
}
- // bw adaptivity (or in case of parallel decoding mode, fw adaptivity
- // probability maintenance between frames)
- if (s->refreshctx) {
- if (s->parallelmode) {
- int j, k, l, m;
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++)
- memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
- s->prob.coef[i][j][k][l][m], 3);
- s->prob_ctx[s->framectxid].p = s->prob.p;
- } else {
+ if (s->pass < 2 && s->refreshctx && !s->parallelmode) {
adapt_probs(s);
+ ff_thread_finish_setup(ctx);
}
- }
+ } while (s->pass++ == 1);
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
// ref frame setup
for (i = 0; i < 8; i++) {
@@ -3613,6 +3768,7 @@ static av_cold int vp9_decode_init(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
+ ctx->internal->allocate_progress = 1;
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
ff_vp9dsp_init(&s->dsp);
ff_videodsp_init(&s->vdsp, 8);
@@ -3621,15 +3777,59 @@ static av_cold int vp9_decode_init(AVCodecContext *ctx)
return init_frames(ctx);
}
+static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ return init_frames(avctx);
+}
+
+static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ int i, res;
+ VP9Context *s = dst->priv_data, *ssrc = src->priv_data;
+
+ // FIXME scalability, size, etc.
+
+ for (i = 0; i < 2; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(dst, &s->frames[i]);
+ if (ssrc->frames[i].tf.f->data[0]) {
+ if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)
+ return res;
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(dst, &s->refs[i]);
+ if (ssrc->next_refs[i].f->data[0]) {
+ if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)
+ return res;
+ }
+ }
+
+ s->invisible = ssrc->invisible;
+ s->keyframe = ssrc->keyframe;
+ s->uses_2pass = ssrc->uses_2pass;
+ memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));
+ memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta));
+ if (ssrc->segmentation.enabled) {
+ memcpy(&s->segmentation.feat, &ssrc->segmentation.feat,
+ sizeof(s->segmentation.feat));
+ }
+
+ return 0;
+}
+
AVCodec ff_vp9_decoder = {
- .name = "vp9",
- .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP9,
- .priv_data_size = sizeof(VP9Context),
- .init = vp9_decode_init,
- .close = vp9_decode_free,
- .capabilities = CODEC_CAP_DR1,
- .flush = vp9_decode_flush,
+ .name = "vp9",
+ .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP9,
+ .priv_data_size = sizeof(VP9Context),
+ .init = vp9_decode_init,
+ .close = vp9_decode_free,
.decode = vp9_decode_frame,
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+ .flush = vp9_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context),
};
1
0
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Sat Nov 23 10:27:18 2013 -0500| [fc7d910b2ebac9b71ce7f77ce9b602369ca25792] | committer: Ronald S. Bultje
vp9: split last/cur_frame from the reference buffers.
We need more information from last/cur_frame than from reference
buffers, so we can use a simplified structure for reference buffers,
and then store mvs and segmentation map information in last/cur.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=fc7d910b2ebac9b71…
---
libavcodec/vp9.c | 304 ++++++++++++++++++++++++++++++++++++------------------
1 file changed, 202 insertions(+), 102 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 83f4a57..df9b197 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -24,6 +24,7 @@
#include "avcodec.h"
#include "get_bits.h"
#include "internal.h"
+#include "thread.h"
#include "videodsp.h"
#include "vp56.h"
#include "vp9.h"
@@ -68,6 +69,13 @@ struct VP9mvrefPair {
int8_t ref[2];
};
+typedef struct VP9Frame {
+ ThreadFrame tf;
+ AVBufferRef *extradata;
+ uint8_t *segmentation_map;
+ struct VP9mvrefPair *mv;
+} VP9Frame;
+
struct VP9Filter {
uint8_t level[8 * 8];
uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
@@ -116,7 +124,10 @@ typedef struct VP9Context {
uint8_t refidx[3];
uint8_t signbias[3];
uint8_t varcompref[2];
- AVFrame *refs[8], *f;
+ ThreadFrame refs[8], next_refs[8];
+#define CUR_FRAME 0
+#define LAST_FRAME 1
+ VP9Frame frames[2];
struct {
uint8_t level;
@@ -213,8 +224,6 @@ typedef struct VP9Context {
// whole-frame cache
uint8_t *intra_pred_data[3];
- uint8_t *segmentation_map;
- struct VP9mvrefPair *mv[2];
struct VP9Filter *lflvl;
DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80];
@@ -238,6 +247,48 @@ static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
}
};
+static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ VP9Context *s = ctx->priv_data;
+ int ret, sz;
+
+ if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+ sz = 64 * s->sb_cols * s->sb_rows;
+ if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) {
+ ff_thread_release_buffer(ctx, &f->tf);
+ return AVERROR(ENOMEM);
+ }
+
+ f->segmentation_map = f->extradata->data;
+ f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
+
+ return 0;
+}
+
+static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ ff_thread_release_buffer(ctx, &f->tf);
+ av_buffer_unref(&f->extradata);
+}
+
+static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
+{
+ int res;
+
+ if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
+ return res;
+ } else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
+ vp9_unref_frame(ctx, dst);
+ return AVERROR(ENOMEM);
+ }
+
+ dst->segmentation_map = src->segmentation_map;
+ dst->mv = src->mv;
+
+ return 0;
+}
+
static int update_size(AVCodecContext *ctx, int w, int h)
{
VP9Context *s = ctx->priv_data;
@@ -257,8 +308,7 @@ static int update_size(AVCodecContext *ctx, int w, int h)
#define assign(var, type, n) var = (type) p; p += s->sb_cols * n * sizeof(*var)
av_freep(&s->above_partition_ctx);
- p = av_malloc(s->sb_cols * (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx) +
- 64 * s->sb_rows * (1 + sizeof(*s->mv[0]) * 2)));
+ p = av_malloc(s->sb_cols * (240 + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx)));
if (!p)
return AVERROR(ENOMEM);
assign(s->above_partition_ctx, uint8_t *, 8);
@@ -278,9 +328,6 @@ static int update_size(AVCodecContext *ctx, int w, int h)
assign(s->above_filter_ctx, uint8_t *, 8);
assign(s->lflvl, struct VP9Filter *, 1);
assign(s->above_mv_ctx, VP56mv(*)[2], 16);
- assign(s->segmentation_map, uint8_t *, 64 * s->sb_rows);
- assign(s->mv[0], struct VP9mvrefPair *, 64 * s->sb_rows);
- assign(s->mv[1], struct VP9mvrefPair *, 64 * s->sb_rows);
#undef assign
return 0;
@@ -427,21 +474,21 @@ static int decode_frame_header(AVCodecContext *ctx,
s->signbias[1] = get_bits1(&s->gb);
s->refidx[2] = get_bits(&s->gb, 3);
s->signbias[2] = get_bits1(&s->gb);
- if (!s->refs[s->refidx[0]]->buf[0] ||
- !s->refs[s->refidx[1]]->buf[0] ||
- !s->refs[s->refidx[2]]->buf[0]) {
+ if (!s->refs[s->refidx[0]].f->data[0] ||
+ !s->refs[s->refidx[1]].f->data[0] ||
+ !s->refs[s->refidx[2]].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Not all references are available\n");
return AVERROR_INVALIDDATA;
}
if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[0]]->width;
- h = s->refs[s->refidx[0]]->height;
+ w = s->refs[s->refidx[0]].f->width;
+ h = s->refs[s->refidx[0]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[1]]->width;
- h = s->refs[s->refidx[1]]->height;
+ w = s->refs[s->refidx[1]].f->width;
+ h = s->refs[s->refidx[1]].f->height;
} else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[2]]->width;
- h = s->refs[s->refidx[2]]->height;
+ w = s->refs[s->refidx[2]].f->width;
+ h = s->refs[s->refidx[2]].f->height;
} else {
w = get_bits(&s->gb, 16) + 1;
h = get_bits(&s->gb, 16) + 1;
@@ -922,7 +969,7 @@ static void find_ref_mvs(VP9Context *s,
} while (0)
if (row > 0) {
- struct VP9mvrefPair *mv = &s->mv[0][(row - 1) * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
if (mv->ref[0] == ref) {
RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
} else if (mv->ref[1] == ref) {
@@ -930,7 +977,7 @@ static void find_ref_mvs(VP9Context *s,
}
}
if (col > s->tiling.tile_col_start) {
- struct VP9mvrefPair *mv = &s->mv[0][row * s->sb_cols * 8 + col - 1];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
if (mv->ref[0] == ref) {
RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
} else if (mv->ref[1] == ref) {
@@ -947,7 +994,7 @@ static void find_ref_mvs(VP9Context *s,
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
@@ -959,7 +1006,7 @@ static void find_ref_mvs(VP9Context *s,
// MV at this position in previous frame, using same reference frame
if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
if (mv->ref[0] == ref) {
RETURN_MV(mv->mv[0]);
@@ -983,7 +1030,7 @@ static void find_ref_mvs(VP9Context *s,
int c = p[i][0] + col, r = p[i][1] + row;
if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->mv[0][r * s->sb_cols * 8 + c];
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
@@ -999,7 +1046,7 @@ static void find_ref_mvs(VP9Context *s,
// MV at this position in previous frame, using different reference frame
if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->mv[1][row * s->sb_cols * 8 + col];
+ struct VP9mvrefPair *mv = &s->frames[LAST_FRAME].mv[row * s->sb_cols * 8 + col];
if (mv->ref[0] != ref && mv->ref[0] >= 0) {
RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
@@ -1175,10 +1222,11 @@ static void decode_mode(AVCodecContext *ctx)
s->prob.segpred[s->above_segpred_ctx[col] +
s->left_segpred_ctx[row7]]))) {
int pred = 8, x;
+ uint8_t *refsegmap = s->frames[LAST_FRAME].segmentation_map;
for (y = 0; y < h4; y++)
for (x = 0; x < w4; x++)
- pred = FFMIN(pred, s->segmentation_map[(y + row) * 8 * s->sb_cols + x + col]);
+ pred = FFMIN(pred, refsegmap[(y + row) * 8 * s->sb_cols + x + col]);
av_assert1(pred < 8);
b->seg_id = pred;
@@ -1192,9 +1240,10 @@ static void decode_mode(AVCodecContext *ctx)
memset(&s->left_segpred_ctx[row7], 0, h4);
}
if ((s->segmentation.enabled && s->segmentation.update_map) || s->keyframe) {
+ uint8_t *segmap = s->frames[CUR_FRAME].segmentation_map;
+
for (y = 0; y < h4; y++)
- memset(&s->segmentation_map[(y + row) * 8 * s->sb_cols + col],
- b->seg_id, w4);
+ memset(&segmap[(y + row) * 8 * s->sb_cols + col], b->seg_id, w4);
}
b->skip = s->segmentation.enabled &&
@@ -1768,24 +1817,25 @@ static void decode_mode(AVCodecContext *ctx)
// FIXME kinda ugly
for (y = 0; y < h4; y++) {
int x, o = (row + y) * s->sb_cols * 8 + col;
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[o];
if (b->intra) {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] =
- s->mv[0][o + x].ref[1] = -1;
+ mv[x].ref[0] =
+ mv[x].ref[1] = -1;
}
} else if (b->comp) {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] = b->ref[0];
- s->mv[0][o + x].ref[1] = b->ref[1];
- AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
- AV_COPY32(&s->mv[0][o + x].mv[1], &b->mv[3][1]);
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = b->ref[1];
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
+ AV_COPY32(&mv[x].mv[1], &b->mv[3][1]);
}
} else {
for (x = 0; x < w4; x++) {
- s->mv[0][o + x].ref[0] = b->ref[0];
- s->mv[0][o + x].ref[1] = -1;
- AV_COPY32(&s->mv[0][o + x].mv[0], &b->mv[3][0]);
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = -1;
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
}
}
}
@@ -2154,7 +2204,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = s->dst[0], *dst_r = s->f->data[0] + y_off;
+ uint8_t *dst = s->dst[0], *dst_r = s->frames[CUR_FRAME].tf.f->data[0] + y_off;
for (n = 0, y = 0; y < end_y; y += step1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
@@ -2167,7 +2217,8 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
enum TxfmType txtp = vp9_intra_txfm_type[mode];
int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
- mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[0],
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[0],
ptr, s->y_stride, l,
col, x, w4, row, y, b->tx, 0);
s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a);
@@ -2175,7 +2226,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
s->block + 16 * n, eob);
}
- dst_r += 4 * s->f->linesize[0] * step1d;
+ dst_r += 4 * step1d * s->frames[CUR_FRAME].tf.f->linesize[0];
dst += 4 * step1d * s->y_stride;
}
@@ -2187,7 +2238,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
dst = s->dst[1 + p];
- dst_r = s->f->data[1 + p] + uv_off;
+ dst_r = s->frames[CUR_FRAME].tf.f->data[1 + p] + uv_off;
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d,
@@ -2197,7 +2248,8 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
uint8_t *a = &a_buf[16], l[32];
int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
- mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[1],
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[1],
ptr, s->uv_stride, l,
col, x, w4, row, y, b->uvtx, p + 1);
s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a);
@@ -2205,7 +2257,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
- dst_r += 4 * uvstep1d * s->f->linesize[1];
+ dst_r += 4 * uvstep1d * s->frames[CUR_FRAME].tf.f->linesize[1];
dst += 4 * uvstep1d * s->uv_stride;
}
}
@@ -2286,9 +2338,11 @@ static void inter_recon(AVCodecContext *ctx)
};
VP9Context *s = ctx->priv_data;
VP9Block *const b = &s->b;
- AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]];
- AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL;
int row = s->row, col = s->col;
+ ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]];
+ AVFrame *ref1 = tref1->f;
+ ThreadFrame *tref2 = b->comp ? &s->refs[s->refidx[b->ref[1]]] : NULL;
+ AVFrame *ref2 = b->comp ? tref2->f : NULL;
int w = ctx->width, h = ctx->height;
ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride;
@@ -2604,6 +2658,7 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
enum BlockSize bs = bl * 3 + bp;
int res, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
s->row = row;
s->row7 = row & 7;
@@ -2634,25 +2689,25 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
// emulated overhangs if the stride of the target buffer can't hold. This
// allows to support emu-edge and so on even if we have large block
// overhangs
- emu[0] = (col + w4) * 8 > s->f->linesize[0] ||
+ emu[0] = (col + w4) * 8 > f->linesize[0] ||
(row + h4) > s->rows + 2 * !(ctx->flags & CODEC_FLAG_EMU_EDGE);
- emu[1] = (col + w4) * 4 > s->f->linesize[1] ||
+ emu[1] = (col + w4) * 4 > f->linesize[1] ||
(row + h4) > s->rows + 2 * !(ctx->flags & CODEC_FLAG_EMU_EDGE);
if (emu[0]) {
s->dst[0] = s->tmp_y;
s->y_stride = 64;
} else {
- s->dst[0] = s->f->data[0] + yoff;
- s->y_stride = s->f->linesize[0];
+ s->dst[0] = f->data[0] + yoff;
+ s->y_stride = f->linesize[0];
}
if (emu[1]) {
s->dst[1] = s->tmp_uv[0];
s->dst[2] = s->tmp_uv[1];
s->uv_stride = 32;
} else {
- s->dst[1] = s->f->data[1] + uvoff;
- s->dst[2] = s->f->data[2] + uvoff;
- s->uv_stride = s->f->linesize[1];
+ s->dst[1] = f->data[1] + uvoff;
+ s->dst[2] = f->data[2] + uvoff;
+ s->uv_stride = f->linesize[1];
}
if (b->intra) {
intra_recon(ctx, yoff, uvoff);
@@ -2667,7 +2722,7 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
av_assert2(n <= 4);
if (w & bw) {
- s->dsp.mc[n][0][0][0][0](s->f->data[0] + yoff + o, s->f->linesize[0],
+ s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, f->linesize[0],
s->tmp_y + o, 64, h, 0, 0);
o += bw;
}
@@ -2681,9 +2736,9 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
av_assert2(n <= 4);
if (w & bw) {
- s->dsp.mc[n][0][0][0][0](s->f->data[1] + uvoff + o, s->f->linesize[1],
+ s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, f->linesize[1],
s->tmp_uv[0] + o, 32, h, 0, 0);
- s->dsp.mc[n][0][0][0][0](s->f->data[2] + uvoff + o, s->f->linesize[2],
+ s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, f->linesize[2],
s->tmp_uv[1] + o, 32, h, 0, 0);
o += bw;
}
@@ -2733,6 +2788,8 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
s->prob.p.partition[bl][c];
enum BlockPartition bp;
ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
if (bl == BL_8X8) {
bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
@@ -2746,8 +2803,8 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
break;
case PARTITION_H:
if (!(res = decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
res = decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
}
break;
@@ -2762,8 +2819,8 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
if (!(res = decode_sb(ctx, row, col + hbs, lflvl,
yoff + 8 * hbs, uvoff + 4 * hbs, bl + 1))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
if (!(res = decode_sb(ctx, row + hbs, col, lflvl,
yoff, uvoff, bl + 1)))
res = decode_sb(ctx, row + hbs, col + hbs, lflvl,
@@ -2787,8 +2844,8 @@ static int decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lf
if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
bp = PARTITION_SPLIT;
if (!(res = decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1))) {
- yoff += hbs * 8 * s->f->linesize[0];
- uvoff += hbs * 4 * s->f->linesize[1];
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 4 * uv_stride;
res = decode_sb(ctx, row + hbs, col, lflvl,
yoff, uvoff, bl + 1);
}
@@ -2809,8 +2866,9 @@ static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
{
VP9Context *s = ctx->priv_data;
- uint8_t *dst = s->f->data[0] + yoff, *lvl = lflvl->level;
- ptrdiff_t ls_y = s->f->linesize[0], ls_uv = s->f->linesize[1];
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ uint8_t *dst = f->data[0] + yoff, *lvl = lflvl->level;
+ ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1];
int y, x, p;
// FIXME in how far can we interleave the v/h loopfilter calls? E.g.
@@ -2887,7 +2945,7 @@ static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
// block1
// filter edges between rows, Y plane (e.g. ------)
// block2
- dst = s->f->data[0] + yoff;
+ dst = f->data[0] + yoff;
lvl = lflvl->level;
for (y = 0; y < 8; y++, dst += 8 * ls_y, lvl += 8) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[0][1][y];
@@ -2951,7 +3009,7 @@ static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
// same principle but for U/V planes
for (p = 0; p < 2; p++) {
lvl = lflvl->level;
- dst = s->f->data[1 + p] + uvoff;
+ dst = f->data[1 + p] + uvoff;
for (y = 0; y < 8; y += 4, dst += 16 * ls_uv, lvl += 32) {
uint8_t *ptr = dst, *l = lvl, *hmask1 = lflvl->mask[1][0][y];
uint8_t *hmask2 = lflvl->mask[1][0][y + 2];
@@ -2996,7 +3054,7 @@ static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
}
}
lvl = lflvl->level;
- dst = s->f->data[1 + p] + uvoff;
+ dst = f->data[1 + p] + uvoff;
for (y = 0; y < 8; y++, dst += 4 * ls_uv) {
uint8_t *ptr = dst, *l = lvl, *vmask = lflvl->mask[1][1][y];
unsigned vm = vmask[0] | vmask[1] | vmask[2];
@@ -3294,8 +3352,19 @@ static av_cold int vp9_decode_free(AVCodecContext *ctx)
VP9Context *s = ctx->priv_data;
int i;
- for (i = 0; i < 8; i++)
- av_frame_free(&s->refs[i]);
+ for (i = 0; i < 2; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[i]);
+ av_frame_free(&s->frames[i].tf.f);
+ }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ av_frame_free(&s->refs[i].f);
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ av_frame_free(&s->next_refs[i].f);
+ }
av_freep(&s->above_partition_ctx);
av_freep(&s->c_b);
@@ -3310,17 +3379,17 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
int size = pkt->size;
VP9Context *s = ctx->priv_data;
int res, tile_row, tile_col, i, ref, row, col;
- ptrdiff_t yoff = 0, uvoff = 0;
- //AVFrame *prev_frame = s->f; // for segmentation map
+ ptrdiff_t yoff = 0, uvoff = 0, ls_y, ls_uv;
+ AVFrame *f;
if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
return res;
} else if (res == 0) {
- if (!s->refs[ref]->buf[0]) {
+ if (!s->refs[ref].f->data[0]) {
av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);
return AVERROR_INVALIDDATA;
}
- if ((res = av_frame_ref(frame, s->refs[ref])) < 0)
+ if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0)
return res;
*got_frame = 1;
return 0;
@@ -3328,12 +3397,29 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
data += res;
size -= res;
- s->f = frame;
- if ((res = ff_get_buffer(ctx, s->f,
- s->refreshrefmask ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+ if (s->frames[LAST_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[LAST_FRAME]);
+ if (!s->keyframe && s->frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->frames[LAST_FRAME], &s->frames[CUR_FRAME])) < 0)
+ return res;
+ if (s->frames[CUR_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[CUR_FRAME]);
+ if ((res = vp9_alloc_frame(ctx, &s->frames[CUR_FRAME])) < 0)
return res;
- s->f->key_frame = s->keyframe;
- s->f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ f = s->frames[CUR_FRAME].tf.f;
+ f->key_frame = s->keyframe;
+ f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ ls_y = f->linesize[0];
+ ls_uv =f->linesize[1];
+
+ // ref frame setup
+ for (i = 0; i < 8; i++)
+ if (s->refreshrefmask & (1 << i)) {
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ if ((res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf)) < 0)
+ return res;
+ }
// main tile decode loop
memset(s->above_partition_ctx, 0, s->cols);
@@ -3370,10 +3456,8 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
size -= tile_size;
}
- for (row = s->tiling.tile_row_start;
- row < s->tiling.tile_row_end;
- row += 8, yoff += s->f->linesize[0] * 64,
- uvoff += s->f->linesize[1] * 32) {
+ for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
+ row += 8, yoff += ls_y * 64, uvoff += ls_uv * 32) {
struct VP9Filter *lflvl_ptr = s->lflvl;
ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
@@ -3411,13 +3495,13 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
// prediction of next row of sb64s
if (row + 8 < s->rows) {
memcpy(s->intra_pred_data[0],
- s->f->data[0] + yoff + 63 * s->f->linesize[0],
+ f->data[0] + yoff + 63 * ls_y,
8 * s->cols);
memcpy(s->intra_pred_data[1],
- s->f->data[1] + uvoff + 31 * s->f->linesize[1],
+ f->data[1] + uvoff + 31 * ls_uv,
4 * s->cols);
memcpy(s->intra_pred_data[2],
- s->f->data[2] + uvoff + 31 * s->f->linesize[2],
+ f->data[2] + uvoff + 31 * ls_uv,
4 * s->cols);
}
@@ -3438,7 +3522,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
// probability maintenance between frames)
if (s->refreshctx) {
if (s->parallelmode) {
- int i, j, k, l, m;
+ int j, k, l, m;
for (i = 0; i < 4; i++)
for (j = 0; j < 2; j++)
@@ -3452,19 +3536,17 @@ static int vp9_decode_frame(AVCodecContext *ctx, AVFrame *frame,
adapt_probs(s);
}
}
- FFSWAP(struct VP9mvrefPair *, s->mv[0], s->mv[1]);
// ref frame setup
- for (i = 0; i < 8; i++)
- if (s->refreshrefmask & (1 << i)) {
- av_frame_unref(s->refs[i]);
- if ((res = av_frame_ref(s->refs[i], s->f)) < 0)
- return res;
- }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ ff_thread_ref_frame(&s->refs[i], &s->next_refs[i]);
+ }
- if (s->invisible) {
- av_frame_unref(s->f);
- } else {
+ if (!s->invisible) {
+ if ((res = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f)) < 0)
+ return res;
*got_frame = 1;
}
@@ -3476,32 +3558,50 @@ static void vp9_decode_flush(AVCodecContext *ctx)
VP9Context *s = ctx->priv_data;
int i;
+ for (i = 0; i < 2; i++)
+ vp9_unref_frame(ctx, &s->frames[i]);
for (i = 0; i < 8; i++)
- av_frame_unref(s->refs[i]);
- s->f = NULL;
+ ff_thread_release_buffer(ctx, &s->refs[i]);
}
-static av_cold int vp9_decode_init(AVCodecContext *ctx)
+static int init_frames(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
int i;
- ctx->pix_fmt = AV_PIX_FMT_YUV420P;
- ff_vp9dsp_init(&s->dsp);
- ff_videodsp_init(&s->vdsp, 8);
+ for (i = 0; i < 2; i++) {
+ s->frames[i].tf.f = av_frame_alloc();
+ if (!s->frames[i].tf.f) {
+ vp9_decode_free(ctx);
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
+ return AVERROR(ENOMEM);
+ }
+ }
for (i = 0; i < 8; i++) {
- s->refs[i] = av_frame_alloc();
- if (!s->refs[i]) {
+ s->refs[i].f = av_frame_alloc();
+ s->next_refs[i].f = av_frame_alloc();
+ if (!s->refs[i].f || !s->next_refs[i].f) {
vp9_decode_free(ctx);
av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
return AVERROR(ENOMEM);
}
}
- s->filter.sharpness = -1;
return 0;
}
+static av_cold int vp9_decode_init(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+
+ ctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ ff_vp9dsp_init(&s->dsp);
+ ff_videodsp_init(&s->vdsp, 8);
+ s->filter.sharpness = -1;
+
+ return init_frames(ctx);
+}
+
AVCodec ff_vp9_decoder = {
.name = "vp9",
.long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
1
0
ffmpeg | branch: master | Ronald S. Bultje <rsbultje(a)gmail.com> | Mon Nov 25 21:42:13 2013 -0500| [39b244002ae5853adfa18a5ac7db4743c71eb483] | committer: Ronald S. Bultje
vp9: move some entries out of VP9Block into VP9Context.
They aren't really block-related variables in the sense that they are
not block-coded, rather they are state trackers.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=39b244002ae5853ad…
---
libavcodec/vp9.c | 118 +++++++++++++++++++++++++++---------------------------
1 file changed, 59 insertions(+), 59 deletions(-)
diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index 91f4eeb..83f4a57 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -81,9 +81,6 @@ typedef struct VP9Block {
enum BlockSize bs;
enum TxfmMode tx, uvtx;
- int row, row7, col, col7;
- uint8_t *dst[3];
- ptrdiff_t y_stride, uv_stride;
} VP9Block;
typedef struct VP9Context {
@@ -94,6 +91,9 @@ typedef struct VP9Context {
VP56RangeCoder *c_b;
unsigned c_b_size;
VP9Block b;
+ int row, row7, col, col7;
+ uint8_t *dst[3];
+ ptrdiff_t y_stride, uv_stride;
// bitstream header
uint8_t profile;
@@ -862,7 +862,7 @@ static void find_ref_mvs(VP9Context *s,
{ -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
};
VP9Block *const b = &s->b;
- int row = b->row, col = b->col, row7 = b->row7;
+ int row = s->row, col = s->col, row7 = s->row7;
const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
#define INVALID_MV 0x80008000U
uint32_t mem = INVALID_MV;
@@ -1158,7 +1158,7 @@ static void decode_mode(AVCodecContext *ctx)
};
VP9Context *s = ctx->priv_data;
VP9Block *const b = &s->b;
- int row = b->row, col = b->col, row7 = b->row7;
+ int row = s->row, col = s->col, row7 = s->row7;
enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
int w4 = FFMIN(s->cols - col, bwh_tab[1][b->bs][0]);
int h4 = FFMIN(s->rows - row, bwh_tab[1][b->bs][1]), y;
@@ -1903,7 +1903,7 @@ static int decode_coeffs(AVCodecContext *ctx)
{
VP9Context *s = ctx->priv_data;
VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
+ int row = s->row, col = s->col;
uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
@@ -2147,14 +2147,14 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
{
VP9Context *s = ctx->priv_data;
VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
+ int row = s->row, col = s->col;
int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
int end_x = FFMIN(2 * (s->cols - col), w4);
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = b->dst[0], *dst_r = s->f->data[0] + y_off;
+ uint8_t *dst = s->dst[0], *dst_r = s->f->data[0] + y_off;
for (n = 0, y = 0; y < end_y; y += step1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
@@ -2168,15 +2168,15 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[0],
- ptr, b->y_stride, l,
+ ptr, s->y_stride, l,
col, x, w4, row, y, b->tx, 0);
- s->dsp.intra_pred[b->tx][mode](ptr, b->y_stride, l, a);
+ s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a);
if (eob)
- s->dsp.itxfm_add[tx][txtp](ptr, b->y_stride,
+ s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
s->block + 16 * n, eob);
}
dst_r += 4 * s->f->linesize[0] * step1d;
- dst += 4 * b->y_stride * step1d;
+ dst += 4 * step1d * s->y_stride;
}
// U/V
@@ -2186,7 +2186,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
- dst = b->dst[1 + p];
+ dst = s->dst[1 + p];
dst_r = s->f->data[1 + p] + uv_off;
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst, *ptr_r = dst_r;
@@ -2198,15 +2198,15 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
mode = check_intra_mode(s, mode, &a, ptr_r, s->f->linesize[1],
- ptr, b->uv_stride, l,
+ ptr, s->uv_stride, l,
col, x, w4, row, y, b->uvtx, p + 1);
- s->dsp.intra_pred[b->uvtx][mode](ptr, b->uv_stride, l, a);
+ s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a);
if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
dst_r += 4 * uvstep1d * s->f->linesize[1];
- dst += 4 * uvstep1d * b->uv_stride;
+ dst += 4 * uvstep1d * s->uv_stride;
}
}
}
@@ -2286,45 +2286,45 @@ static void inter_recon(AVCodecContext *ctx)
};
VP9Context *s = ctx->priv_data;
VP9Block *const b = &s->b;
- int row = b->row, col = b->col;
AVFrame *ref1 = s->refs[s->refidx[b->ref[0]]];
AVFrame *ref2 = b->comp ? s->refs[s->refidx[b->ref[1]]] : NULL;
+ int row = s->row, col = s->col;
int w = ctx->width, h = ctx->height;
- ptrdiff_t ls_y = b->y_stride, ls_uv = b->uv_stride;
+ ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride;
// y inter pred
if (b->bs > BS_8x8) {
if (b->bs == BS_8x4) {
- mc_luma_dir(s, s->dsp.mc[3][b->filter][0], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[3][b->filter][0], s->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][0],
- b->dst[0] + 4 * ls_y, ls_y,
+ s->dst[0] + 4 * ls_y, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[3][b->filter][1], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[3][b->filter][1], s->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 8, 4, w, h);
mc_luma_dir(s, s->dsp.mc[3][b->filter][1],
- b->dst[0] + 4 * ls_y, ls_y,
+ s->dst[0] + 4 * ls_y, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w, h);
}
} else if (b->bs == BS_4x8) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 4, 8, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 4, 8, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w, h);
}
@@ -2333,34 +2333,34 @@ static void inter_recon(AVCodecContext *ctx)
// FIXME if two horizontally adjacent blocks have the same MV,
// do a w8 instead of a w4 call
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0], 4, 4, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][0], b->dst[0] + 4, ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
- b->dst[0] + 4 * ls_y, ls_y,
+ s->dst[0] + 4 * ls_y, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][0],
- b->dst[0] + 4 * ls_y + 4, ls_y,
+ s->dst[0] + 4 * ls_y + 4, ls_y,
ref1->data[0], ref1->linesize[0],
(row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w, h);
if (b->comp) {
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], 4, 4, w, h);
- mc_luma_dir(s, s->dsp.mc[4][b->filter][1], b->dst[0] + 4, ls_y,
+ mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
- b->dst[0] + 4 * ls_y, ls_y,
+ s->dst[0] + 4 * ls_y, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w, h);
mc_luma_dir(s, s->dsp.mc[4][b->filter][1],
- b->dst[0] + 4 * ls_y + 4, ls_y,
+ s->dst[0] + 4 * ls_y + 4, ls_y,
ref2->data[0], ref2->linesize[0],
(row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w, h);
}
@@ -2369,12 +2369,12 @@ static void inter_recon(AVCodecContext *ctx)
int bwl = bwlog_tab[0][b->bs];
int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4;
- mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], s->dst[0], ls_y,
ref1->data[0], ref1->linesize[0],
row << 3, col << 3, &b->mv[0][0],bw, bh, w, h);
if (b->comp)
- mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], b->dst[0], ls_y,
+ mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], s->dst[0], ls_y,
ref2->data[0], ref2->linesize[0],
row << 3, col << 3, &b->mv[0][1], bw, bh, w, h);
}
@@ -2395,7 +2395,7 @@ static void inter_recon(AVCodecContext *ctx)
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0],
- b->dst[1], b->dst[2], ls_uv,
+ s->dst[1], s->dst[2], ls_uv,
ref1->data[1], ref1->linesize[1],
ref1->data[2], ref1->linesize[2],
row << 2, col << 2, &mvuv, bw, bh, w, h);
@@ -2408,7 +2408,7 @@ static void inter_recon(AVCodecContext *ctx)
mvuv = b->mv[0][1];
}
mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1],
- b->dst[1], b->dst[2], ls_uv,
+ s->dst[1], s->dst[2], ls_uv,
ref2->data[1], ref2->linesize[1],
ref2->data[2], ref2->linesize[2],
row << 2, col << 2, &mvuv, bw, bh, w, h);
@@ -2424,7 +2424,7 @@ static void inter_recon(AVCodecContext *ctx)
int end_y = FFMIN(2 * (s->rows - row), h4);
int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = b->dst[0];
+ uint8_t *dst = s->dst[0];
// y itxfm add
for (n = 0, y = 0; y < end_y; y += step1d) {
@@ -2433,10 +2433,10 @@ static void inter_recon(AVCodecContext *ctx)
int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
if (eob)
- s->dsp.itxfm_add[tx][DCT_DCT](ptr, b->y_stride,
+ s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride,
s->block + 16 * n, eob);
}
- dst += 4 * b->y_stride * step1d;
+ dst += 4 * s->y_stride * step1d;
}
// uv itxfm add
@@ -2446,17 +2446,17 @@ static void inter_recon(AVCodecContext *ctx)
end_y >>= 1;
step = 1 << (b->uvtx * 2);
for (p = 0; p < 2; p++) {
- dst = b->dst[p + 1];
+ dst = s->dst[p + 1];
for (n = 0, y = 0; y < end_y; y += uvstep1d) {
uint8_t *ptr = dst;
for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, n += step) {
int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, b->uv_stride,
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
s->uvblock[p] + 16 * n, eob);
}
- dst += 4 * uvstep1d * b->uv_stride;
+ dst += 4 * uvstep1d * s->uv_stride;
}
}
}
@@ -2605,10 +2605,10 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
int res, y, w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
int emu[2];
- b->row = row;
- b->row7 = row & 7;
- b->col = col;
- b->col7 = col & 7;
+ s->row = row;
+ s->row7 = row & 7;
+ s->col = col;
+ s->col7 = col & 7;
s->min_mv.x = -(128 + col * 64);
s->min_mv.y = -(128 + row * 64);
s->max_mv.x = 128 + (s->cols - col - w4) * 64;
@@ -2639,20 +2639,20 @@ static int decode_b(AVCodecContext *ctx, int row, int col,
emu[1] = (col + w4) * 4 > s->f->linesize[1] ||
(row + h4) > s->rows + 2 * !(ctx->flags & CODEC_FLAG_EMU_EDGE);
if (emu[0]) {
- b->dst[0] = s->tmp_y;
- b->y_stride = 64;
+ s->dst[0] = s->tmp_y;
+ s->y_stride = 64;
} else {
- b->dst[0] = s->f->data[0] + yoff;
- b->y_stride = s->f->linesize[0];
+ s->dst[0] = s->f->data[0] + yoff;
+ s->y_stride = s->f->linesize[0];
}
if (emu[1]) {
- b->dst[1] = s->tmp_uv[0];
- b->dst[2] = s->tmp_uv[1];
- b->uv_stride = 32;
+ s->dst[1] = s->tmp_uv[0];
+ s->dst[2] = s->tmp_uv[1];
+ s->uv_stride = 32;
} else {
- b->dst[1] = s->f->data[1] + uvoff;
- b->dst[2] = s->f->data[2] + uvoff;
- b->uv_stride = s->f->linesize[1];
+ s->dst[1] = s->f->data[1] + uvoff;
+ s->dst[2] = s->f->data[2] + uvoff;
+ s->uv_stride = s->f->linesize[1];
}
if (b->intra) {
intra_recon(ctx, yoff, uvoff);
1
0