#include "libavutil/attributes.h"
#include "libavutil/common.h"
+#include "libavutil/display.h"
#include "libavutil/internal.h"
#include "libavutil/md5.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
+#include "bswapdsp.h"
#include "bytestream.h"
#include "cabac_functions.h"
-#include "dsputil.h"
#include "golomb.h"
#include "hevc.h"
{
av_freep(&s->sao);
av_freep(&s->deblock);
- av_freep(&s->split_cu_flag);
av_freep(&s->skip_flag);
av_freep(&s->tab_ct_depth);
int log2_min_cb_size = sps->log2_min_cb_size;
int width = sps->width;
int height = sps->height;
- int pic_size = width * height;
int pic_size_in_ctb = ((width >> log2_min_cb_size) + 1) *
((height >> log2_min_cb_size) + 1);
int ctb_count = sps->ctb_width * sps->ctb_height;
s->sao = av_mallocz_array(ctb_count, sizeof(*s->sao));
s->deblock = av_mallocz_array(ctb_count, sizeof(*s->deblock));
- s->split_cu_flag = av_malloc(pic_size);
- if (!s->sao || !s->deblock || !s->split_cu_flag)
+ if (!s->sao || !s->deblock)
goto fail;
s->skip_flag = av_malloc(pic_size_in_ctb);
s->avctx->width = sps->output_width;
s->avctx->height = sps->output_height;
s->avctx->pix_fmt = sps->pix_fmt;
- s->avctx->sample_aspect_ratio = sps->vui.sar;
s->avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
+ ff_set_sar(s->avctx, sps->vui.sar);
+
if (sps->vui.video_signal_type_present_flag)
s->avctx->color_range = sps->vui.video_full_range_flag ? AVCOL_RANGE_JPEG
: AVCOL_RANGE_MPEG;
if (IS_IDR(s))
ff_hevc_clear_refs(s);
}
- if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23)
+ if (IS_IRAP(s))
sh->no_output_of_prior_pics_flag = get_bits1(gb);
sh->pps_id = get_ue_golomb_long(gb);
return AVERROR_INVALIDDATA;
}
+ // when flag is not present, picture is inferred to be output
+ sh->pic_output_flag = 1;
if (s->pps->output_flag_present_flag)
sh->pic_output_flag = get_bits1(gb);
int trafo_size = 1 << log2_trafo_size;
ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
- s->hpc.intra_pred(s, x0, y0, log2_trafo_size, 0);
+ s->hpc.intra_pred[log2_trafo_size - 2](s, x0, y0, 0);
if (log2_trafo_size > 2) {
trafo_size = trafo_size << (s->sps->hshift[1] - 1);
ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);
- s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 1);
- s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 2);
+ s->hpc.intra_pred[log2_trafo_size - 3](s, x0, y0, 1);
+ s->hpc.intra_pred[log2_trafo_size - 3](s, x0, y0, 2);
} else if (blk_idx == 3) {
trafo_size = trafo_size << s->sps->hshift[1];
ff_hevc_set_neighbour_available(s, xBase, yBase,
trafo_size, trafo_size);
- s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 1);
- s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 2);
+ s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 1);
+ s->hpc.intra_pred[log2_trafo_size - 2](s, xBase, yBase, 2);
}
}
lc->tt.cbf_luma = 1;
- lc->tt.inter_split_flag = s->sps->max_transform_hierarchy_depth_inter == 0 &&
- lc->cu.pred_mode == MODE_INTER &&
- lc->cu.part_mode != PART_2Nx2N &&
- trafo_depth == 0;
-
if (log2_trafo_size <= s->sps->log2_max_trafo_size &&
log2_trafo_size > s->sps->log2_min_tb_size &&
trafo_depth < lc->cu.max_trafo_depth &&
!(lc->cu.intra_split_flag && trafo_depth == 0)) {
split_transform_flag = ff_hevc_split_transform_flag_decode(s, log2_trafo_size);
} else {
+ int inter_split = s->sps->max_transform_hierarchy_depth_inter == 0 &&
+ lc->cu.pred_mode == MODE_INTER &&
+ lc->cu.part_mode != PART_2Nx2N &&
+ trafo_depth == 0;
+
split_transform_flag = log2_trafo_size > s->sps->log2_max_trafo_size ||
(lc->cu.intra_split_flag && trafo_depth == 0) ||
- lc->tt.inter_split_flag;
+ inter_split;
}
if (log2_trafo_size > 2) {
}
if (split_transform_flag) {
- int x1 = x0 + ((1 << log2_trafo_size) >> 1);
- int y1 = y0 + ((1 << log2_trafo_size) >> 1);
+ const int trafo_size_split = 1 << (log2_trafo_size - 1);
+ const int x1 = x0 + trafo_size_split;
+ const int y1 = y0 + trafo_size_split;
+
+#define SUBDIVIDE(x, y, idx) \
+do { \
+ ret = hls_transform_tree(s, x, y, x0, y0, cb_xBase, cb_yBase, log2_cb_size, \
+ log2_trafo_size - 1, trafo_depth + 1, idx); \
+ if (ret < 0) \
+ return ret; \
+} while (0)
- ret = hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase,
- log2_cb_size, log2_trafo_size - 1,
- trafo_depth + 1, 0);
- if (ret < 0)
- return ret;
- ret = hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase,
- log2_cb_size, log2_trafo_size - 1,
- trafo_depth + 1, 1);
- if (ret < 0)
- return ret;
- ret = hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase,
- log2_cb_size, log2_trafo_size - 1,
- trafo_depth + 1, 2);
- if (ret < 0)
- return ret;
- ret = hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase,
- log2_cb_size, log2_trafo_size - 1,
- trafo_depth + 1, 3);
- if (ret < 0)
- return ret;
+ SUBDIVIDE(x0, y0, 0);
+ SUBDIVIDE(x1, y0, 1);
+ SUBDIVIDE(x0, y1, 2);
+ SUBDIVIDE(x1, y1, 3);
+
+#undef SUBDIVIDE
} else {
int min_tu_size = 1 << s->sps->log2_min_tb_size;
int log2_min_tu_size = s->sps->log2_min_tb_size;
uint8_t *dst2 = &s->frame->data[2][(y0 >> s->sps->vshift[2]) * stride2 + ((x0 >> s->sps->hshift[2]) << s->sps->pixel_shift)];
int length = cb_size * cb_size * s->sps->pcm.bit_depth + ((cb_size * cb_size) >> 1) * s->sps->pcm.bit_depth_chroma;
- const uint8_t *pcm = skip_bytes(&s->HEVClc.cc, (length + 7) >> 3);
+ const uint8_t *pcm = skip_bytes(&lc->cc, (length + 7) >> 3);
int ret;
ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size,
{
HEVCLocalContext *lc = &s->HEVClc;
const int cb_size = 1 << log2_cb_size;
+ int split_cu;
lc->ct.depth = cb_depth;
if (x0 + cb_size <= s->sps->width &&
y0 + cb_size <= s->sps->height &&
log2_cb_size > s->sps->log2_min_cb_size) {
- SAMPLE(s->split_cu_flag, x0, y0) =
- ff_hevc_split_coding_unit_flag_decode(s, cb_depth, x0, y0);
+ split_cu = ff_hevc_split_coding_unit_flag_decode(s, cb_depth, x0, y0);
} else {
- SAMPLE(s->split_cu_flag, x0, y0) =
- (log2_cb_size > s->sps->log2_min_cb_size);
+ split_cu = (log2_cb_size > s->sps->log2_min_cb_size);
}
if (s->pps->cu_qp_delta_enabled_flag &&
log2_cb_size >= s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth) {
lc->tu.cu_qp_delta = 0;
}
- if (SAMPLE(s->split_cu_flag, x0, y0)) {
+ if (split_cu) {
const int cb_size_split = cb_size >> 1;
const int x1 = x0 + cb_size_split;
const int y1 = y0 + cb_size_split;
stereo->flags = AV_STEREO3D_FLAG_INVERT;
}
+ if (s->sei_display_orientation_present &&
+ (s->sei_anticlockwise_rotation || s->sei_hflip || s->sei_vflip)) {
+ double angle = s->sei_anticlockwise_rotation * 360 / (double) (1 << 16);
+ AVFrameSideData *rotation = av_frame_new_side_data(out,
+ AV_FRAME_DATA_DISPLAYMATRIX,
+ sizeof(int32_t) * 9);
+ if (!rotation)
+ return AVERROR(ENOMEM);
+
+ av_display_rotation_set((int32_t *)rotation->data, angle);
+ av_display_matrix_flip((int32_t *)rotation->data,
+ s->sei_vflip, s->sei_hflip);
+ }
+
return 0;
}
goto fail;
}
+ s->ref->frame->key_frame = IS_IRAP(s);
+
ret = set_side_data(s);
if (ret < 0)
goto fail;
const uint8_t *src = frame->data[i] + j * frame->linesize[i];
#if HAVE_BIGENDIAN
if (pixel_shift) {
- s->dsp.bswap16_buf((uint16_t*)s->checksum_buf,
- (const uint16_t*)src, w);
+ s->bdsp.bswap16_buf((uint16_t *) s->checksum_buf,
+ (const uint16_t *) src, w);
src = s->checksum_buf;
}
#endif
if (!s->md5_ctx)
goto fail;
- ff_dsputil_init(&s->dsp, avctx);
+ ff_bswapdsp_init(&s->bdsp);
s->context_initialized = 1;