lavc/hevcdec: move HEVCContext.sao_pixel_buffer_[vh] to HEVCLayerContext

Handle them together with other sps-dependent arrays.

Note that current code only allocates these arrays when hwaccel is not
set, but this is wrong as the relevant code runs BEFORE get_format() is
called and hence before we know whether hwaccel is in use.
release/7.1
Anton Khirnov 8 months ago
parent 6fcf0045cf
commit 672713761b
  1. 22
      libavcodec/hevc/filter.c
  2. 59
      libavcodec/hevc/hevcdec.c
  3. 5
      libavcodec/hevc/hevcdec.h

@ -204,7 +204,7 @@ static void copy_vert(uint8_t *dst, const uint8_t *src,
} }
} }
static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps, static void copy_CTB_to_hv(const HEVCLayerContext *l, const HEVCSPS *sps,
const uint8_t *src, const uint8_t *src,
ptrdiff_t stride_src, int x, int y, int width, int height, ptrdiff_t stride_src, int x, int y, int width, int height,
int c_idx, int x_ctb, int y_ctb) int c_idx, int x_ctb, int y_ctb)
@ -214,15 +214,15 @@ static void copy_CTB_to_hv(const HEVCContext *s, const HEVCSPS *sps,
int h = sps->height >> sps->vshift[c_idx]; int h = sps->height >> sps->vshift[c_idx];
/* copy horizontal edges */ /* copy horizontal edges */
memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh), memcpy(l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb) * w + x) << sh),
src, width << sh); src, width << sh);
memcpy(s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh), memcpy(l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) * w + x) << sh),
src + stride_src * (height - 1), width << sh); src + stride_src * (height - 1), width << sh);
/* copy vertical edges */ /* copy vertical edges */
copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src); copy_vert(l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) * h + y) << sh), src, sh, height, 1 << sh, stride_src);
copy_vert(s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src); copy_vert(l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 1) * h + y) << sh), src + ((width - 1) << sh), sh, height, 1 << sh, stride_src);
} }
static void restore_tqb_pixels(const HEVCLayerContext *l, static void restore_tqb_pixels(const HEVCLayerContext *l,
@ -343,7 +343,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
switch (sao->type_idx[c_idx]) { switch (sao->type_idx[c_idx]) {
case SAO_BAND: case SAO_BAND:
copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx, copy_CTB_to_hv(l, sps, src, stride_src, x0, y0, width, height, c_idx,
x_ctb, y_ctb); x_ctb, y_ctb);
if (pps->transquant_bypass_enable_flag || if (pps->transquant_bypass_enable_flag ||
(sps->pcm_loop_filter_disabled && sps->pcm_enabled)) { (sps->pcm_loop_filter_disabled && sps->pcm_enabled)) {
@ -385,7 +385,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
dst1 = dst - stride_dst - (left << sh); dst1 = dst - stride_dst - (left << sh);
src1[0] = src - stride_src - (left << sh); src1[0] = src - stride_src - (left << sh);
src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh); src1[1] = l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) * w + x0 - left) << sh);
pos = 0; pos = 0;
if (left) { if (left) {
src_idx = (CTB(l->sao, x_ctb-1, y_ctb-1).type_idx[c_idx] == src_idx = (CTB(l->sao, x_ctb-1, y_ctb-1).type_idx[c_idx] ==
@ -412,7 +412,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
dst1 = dst + height * stride_dst - (left << sh); dst1 = dst + height * stride_dst - (left << sh);
src1[0] = src + height * stride_src - (left << sh); src1[0] = src + height * stride_src - (left << sh);
src1[1] = s->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh); src1[1] = l->sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) * w + x0 - left) << sh);
pos = 0; pos = 0;
if (left) { if (left) {
src_idx = (CTB(l->sao, x_ctb-1, y_ctb+1).type_idx[c_idx] == src_idx = (CTB(l->sao, x_ctb-1, y_ctb+1).type_idx[c_idx] ==
@ -434,7 +434,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
if (!left_edge) { if (!left_edge) {
if (CTB(l->sao, x_ctb-1, y_ctb).type_idx[c_idx] == SAO_APPLIED) { if (CTB(l->sao, x_ctb-1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
copy_vert(dst - (1 << sh), copy_vert(dst - (1 << sh),
s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh), l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) * h + y0) << sh),
sh, height, stride_dst, 1 << sh); sh, height, stride_dst, 1 << sh);
} else { } else {
left_pixels = 1; left_pixels = 1;
@ -444,7 +444,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
if (!right_edge) { if (!right_edge) {
if (CTB(l->sao, x_ctb+1, y_ctb).type_idx[c_idx] == SAO_APPLIED) { if (CTB(l->sao, x_ctb+1, y_ctb).type_idx[c_idx] == SAO_APPLIED) {
copy_vert(dst + (width << sh), copy_vert(dst + (width << sh),
s->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh), l->sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) * h + y0) << sh),
sh, height, stride_dst, 1 << sh); sh, height, stride_dst, 1 << sh);
} else { } else {
right_pixels = 1; right_pixels = 1;
@ -456,7 +456,7 @@ static void sao_filter_CTB(HEVCLocalContext *lc, const HEVCLayerContext *l,
(width + left_pixels + right_pixels) << sh, (width + left_pixels + right_pixels) << sh,
height, stride_dst, stride_src); height, stride_dst, stride_src);
copy_CTB_to_hv(s, sps, src, stride_src, x0, y0, width, height, c_idx, copy_CTB_to_hv(l, sps, src, stride_src, x0, y0, width, height, c_idx,
x_ctb, y_ctb); x_ctb, y_ctb);
s->hevcdsp.sao_edge_filter[tab](src, dst, stride_src, sao->offset_val[c_idx], s->hevcdsp.sao_edge_filter[tab](src, dst, stride_src, sao->offset_val[c_idx],
sao->eo_class[c_idx], width, height); sao->eo_class[c_idx], width, height);

@ -85,6 +85,11 @@ static void pic_arrays_free(HEVCLayerContext *l)
av_freep(&l->horizontal_bs); av_freep(&l->horizontal_bs);
av_freep(&l->vertical_bs); av_freep(&l->vertical_bs);
for (int i = 0; i < 3; i++) {
av_freep(&l->sao_pixel_buffer_h[i]);
av_freep(&l->sao_pixel_buffer_v[i]);
}
ff_refstruct_pool_uninit(&l->tab_mvf_pool); ff_refstruct_pool_uninit(&l->tab_mvf_pool);
ff_refstruct_pool_uninit(&l->rpl_tab_pool); ff_refstruct_pool_uninit(&l->rpl_tab_pool);
} }
@ -137,6 +142,24 @@ static int pic_arrays_init(HEVCLayerContext *l, const HEVCSPS *sps)
if (!l->tab_mvf_pool || !l->rpl_tab_pool) if (!l->tab_mvf_pool || !l->rpl_tab_pool)
goto fail; goto fail;
if (sps->sao_enabled) {
int c_count = (sps->chroma_format_idc != 0) ? 3 : 1;
for (int c_idx = 0; c_idx < c_count; c_idx++) {
int w = sps->width >> sps->hshift[c_idx];
int h = sps->height >> sps->vshift[c_idx];
l->sao_pixel_buffer_h[c_idx] =
av_malloc((w * 2 * sps->ctb_height) <<
sps->pixel_shift);
l->sao_pixel_buffer_v[c_idx] =
av_malloc((h * 2 * sps->ctb_width) <<
sps->pixel_shift);
if (!l->sao_pixel_buffer_h[c_idx] ||
!l->sao_pixel_buffer_v[c_idx])
goto fail;
}
}
return 0; return 0;
fail: fail:
@ -529,7 +552,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps) static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
{ {
int ret, i; int ret;
pic_arrays_free(l); pic_arrays_free(l);
s->ps.sps = NULL; s->ps.sps = NULL;
@ -546,30 +569,6 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth); ff_hevc_dsp_init (&s->hevcdsp, sps->bit_depth);
ff_videodsp_init (&s->vdsp, sps->bit_depth); ff_videodsp_init (&s->vdsp, sps->bit_depth);
for (i = 0; i < 3; i++) {
av_freep(&s->sao_pixel_buffer_h[i]);
av_freep(&s->sao_pixel_buffer_v[i]);
}
if (sps->sao_enabled && !s->avctx->hwaccel) {
int c_count = (sps->chroma_format_idc != 0) ? 3 : 1;
int c_idx;
for(c_idx = 0; c_idx < c_count; c_idx++) {
int w = sps->width >> sps->hshift[c_idx];
int h = sps->height >> sps->vshift[c_idx];
s->sao_pixel_buffer_h[c_idx] =
av_malloc((w * 2 * sps->ctb_height) <<
sps->pixel_shift);
s->sao_pixel_buffer_v[c_idx] =
av_malloc((h * 2 * sps->ctb_width) <<
sps->pixel_shift);
if (!s->sao_pixel_buffer_h[c_idx] ||
!s->sao_pixel_buffer_v[c_idx])
goto fail;
}
}
s->ps.sps = sps; s->ps.sps = sps;
s->vps = ff_refstruct_ref_c(sps->vps); s->vps = ff_refstruct_ref_c(sps->vps);
@ -577,10 +576,6 @@ static int set_sps(HEVCContext *s, HEVCLayerContext *l, const HEVCSPS *sps)
fail: fail:
pic_arrays_free(l); pic_arrays_free(l);
for (i = 0; i < 3; i++) {
av_freep(&s->sao_pixel_buffer_h[i]);
av_freep(&s->sao_pixel_buffer_v[i]);
}
s->ps.sps = NULL; s->ps.sps = NULL;
return ret; return ret;
} }
@ -3526,7 +3521,6 @@ static int hevc_ref_frame(HEVCFrame *dst, const HEVCFrame *src)
static av_cold int hevc_decode_free(AVCodecContext *avctx) static av_cold int hevc_decode_free(AVCodecContext *avctx)
{ {
HEVCContext *s = avctx->priv_data; HEVCContext *s = avctx->priv_data;
int i;
for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++) for (int i = 0; i < FF_ARRAY_ELEMS(s->layers); i++)
pic_arrays_free(&s->layers[i]); pic_arrays_free(&s->layers[i]);
@ -3539,11 +3533,6 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
av_freep(&s->md5_ctx); av_freep(&s->md5_ctx);
for (i = 0; i < 3; i++) {
av_freep(&s->sao_pixel_buffer_h[i]);
av_freep(&s->sao_pixel_buffer_v[i]);
}
ff_container_fifo_free(&s->output_fifo); ff_container_fifo_free(&s->output_fifo);
for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) { for (int layer = 0; layer < FF_ARRAY_ELEMS(s->layers); layer++) {

@ -466,6 +466,9 @@ typedef struct HEVCLayerContext {
uint8_t *horizontal_bs; uint8_t *horizontal_bs;
uint8_t *vertical_bs; uint8_t *vertical_bs;
uint8_t *sao_pixel_buffer_h[3];
uint8_t *sao_pixel_buffer_v[3];
struct FFRefStructPool *tab_mvf_pool; struct FFRefStructPool *tab_mvf_pool;
struct FFRefStructPool *rpl_tab_pool; struct FFRefStructPool *rpl_tab_pool;
} HEVCLayerContext; } HEVCLayerContext;
@ -485,8 +488,6 @@ typedef struct HEVCContext {
uint8_t slice_initialized; uint8_t slice_initialized;
struct ContainerFifo *output_fifo; struct ContainerFifo *output_fifo;
uint8_t *sao_pixel_buffer_h[3];
uint8_t *sao_pixel_buffer_v[3];
HEVCParamSets ps; HEVCParamSets ps;
HEVCSEI sei; HEVCSEI sei;

Loading…
Cancel
Save