avcodec/hevcdec: export cropping information instead of handling it internally

This merges commit a02ae1c683 from libav,
originally written by Anton Khirnov and skipped in
fc63d5ceb3.

 libavcodec/hevc_parser.c |  6 ++++--
 libavcodec/hevc_ps.c     | 31 ++++++++++++-------------------
 libavcodec/hevc_ps.h     |  2 --
 libavcodec/hevc_refs.c   | 18 +++++-------------
 libavcodec/hevcdec.c     |  7 ++++---
 libavcodec/hevcdec.h     |  2 --
 6 files changed, 25 insertions(+), 41 deletions(-)

Signed-off-by: James Almer <jamrial@gmail.com>
pull/28/merge
James Almer 8 years ago
parent 43c394dcae
commit 000fb61a71
  1. 6
      libavcodec/hevc_parser.c
  2. 31
      libavcodec/hevc_ps.c
  3. 2
      libavcodec/hevc_ps.h
  4. 18
      libavcodec/hevc_refs.c
  5. 8
      libavcodec/hevcdec.c
  6. 2
      libavcodec/hevcdec.h

@ -57,6 +57,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
HEVCSEIContext *sei = &ctx->sei; HEVCSEIContext *sei = &ctx->sei;
SliceHeader *sh = &ctx->sh; SliceHeader *sh = &ctx->sh;
GetBitContext *gb = &nal->gb; GetBitContext *gb = &nal->gb;
const HEVCWindow *ow;
int i, num = 0, den = 0; int i, num = 0, den = 0;
sh->first_slice_in_pic_flag = get_bits1(gb); sh->first_slice_in_pic_flag = get_bits1(gb);
@ -83,11 +84,12 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data; ps->sps = (HEVCSPS*)ps->sps_list[ps->pps->sps_id]->data;
ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data; ps->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data;
} }
ow = &ps->sps->output_window;
s->coded_width = ps->sps->width; s->coded_width = ps->sps->width;
s->coded_height = ps->sps->height; s->coded_height = ps->sps->height;
s->width = ps->sps->output_width; s->width = ps->sps->width - ow->left_offset - ow->right_offset;
s->height = ps->sps->output_height; s->height = ps->sps->height - ow->top_offset - ow->bottom_offset;
s->format = ps->sps->pix_fmt; s->format = ps->sps->pix_fmt;
avctx->profile = ps->sps->ptl.general_ptl.profile_idc; avctx->profile = ps->sps->ptl.general_ptl.profile_idc;
avctx->level = ps->sps->ptl.general_ptl.level_idc; avctx->level = ps->sps->ptl.general_ptl.level_idc;

@ -826,6 +826,7 @@ static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps)
int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id, int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx) int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx)
{ {
HEVCWindow *ow;
int ret = 0; int ret = 0;
int log2_diff_max_min_transform_block_size; int log2_diff_max_min_transform_block_size;
int bit_depth_chroma, start, vui_present, sublayer_ordering_info; int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
@ -1092,30 +1093,21 @@ int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
sps->output_window.top_offset += sps->vui.def_disp_win.top_offset; sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset; sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
} }
if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
!(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) { ow = &sps->output_window;
sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift)); if (ow->left_offset >= INT_MAX - ow->right_offset ||
av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d " ow->top_offset >= INT_MAX - ow->bottom_offset ||
"chroma samples to preserve alignment.\n", ow->left_offset + ow->right_offset >= sps->width ||
sps->output_window.left_offset); ow->top_offset + ow->bottom_offset >= sps->height) {
} av_log(avctx, AV_LOG_WARNING, "Invalid cropping offsets: %u/%u/%u/%u\n",
sps->output_width = sps->width - ow->left_offset, ow->right_offset, ow->top_offset, ow->bottom_offset);
(sps->output_window.left_offset + sps->output_window.right_offset);
sps->output_height = sps->height -
(sps->output_window.top_offset + sps->output_window.bottom_offset);
if (sps->width <= sps->output_window.left_offset + (int64_t)sps->output_window.right_offset ||
sps->height <= sps->output_window.top_offset + (int64_t)sps->output_window.bottom_offset) {
av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
sps->output_width, sps->output_height);
if (avctx->err_recognition & AV_EF_EXPLODE) { if (avctx->err_recognition & AV_EF_EXPLODE) {
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
av_log(avctx, AV_LOG_WARNING, av_log(avctx, AV_LOG_WARNING,
"Displaying the whole video surface.\n"); "Displaying the whole video surface.\n");
memset(ow, 0, sizeof(*ow));
memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win)); memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
memset(&sps->output_window, 0, sizeof(sps->output_window));
sps->output_width = sps->width;
sps->output_height = sps->height;
} }
// Inferred parameters // Inferred parameters
@ -1221,7 +1213,8 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx,
"Parsed SPS: id %d; coded wxh: %dx%d; " "Parsed SPS: id %d; coded wxh: %dx%d; "
"cropped wxh: %dx%d; pix_fmt: %s.\n", "cropped wxh: %dx%d; pix_fmt: %s.\n",
sps_id, sps->width, sps->height, sps_id, sps->width, sps->height,
sps->output_width, sps->output_height, sps->width - (sps->output_window.left_offset + sps->output_window.right_offset),
sps->height - (sps->output_window.top_offset + sps->output_window.bottom_offset),
av_get_pix_fmt_name(sps->pix_fmt)); av_get_pix_fmt_name(sps->pix_fmt));
} }

@ -227,8 +227,6 @@ typedef struct HEVCSPS {
int chroma_format_idc; int chroma_format_idc;
uint8_t separate_colour_plane_flag; uint8_t separate_colour_plane_flag;
///< output (i.e. cropped) values
int output_width, output_height;
HEVCWindow output_window; HEVCWindow output_window;
HEVCWindow pic_conf_win; HEVCWindow pic_conf_win;

@ -163,7 +163,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc)
ref->poc = poc; ref->poc = poc;
ref->sequence = s->seq_decode; ref->sequence = s->seq_decode;
ref->window = s->ps.sps->output_window; ref->frame->crop_left = s->ps.sps->output_window.left_offset;
ref->frame->crop_right = s->ps.sps->output_window.right_offset;
ref->frame->crop_top = s->ps.sps->output_window.top_offset;
ref->frame->crop_bottom = s->ps.sps->output_window.bottom_offset;
return 0; return 0;
} }
@ -204,12 +207,8 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
if (nb_output) { if (nb_output) {
HEVCFrame *frame = &s->DPB[min_idx]; HEVCFrame *frame = &s->DPB[min_idx];
AVFrame *dst = out;
AVFrame *src = frame->frame;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format);
int pixel_shift = !!(desc->comp[0].depth > 8);
ret = av_frame_ref(out, src); ret = av_frame_ref(out, frame->frame);
if (frame->flags & HEVC_FRAME_FLAG_BUMPING) if (frame->flags & HEVC_FRAME_FLAG_BUMPING)
ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING);
else else
@ -217,13 +216,6 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
if (ret < 0) if (ret < 0)
return ret; return ret;
for (i = 0; i < 3; i++) {
int hshift = (i > 0) ? desc->log2_chroma_w : 0;
int vshift = (i > 0) ? desc->log2_chroma_h : 0;
int off = ((frame->window.left_offset >> hshift) << pixel_shift) +
(frame->window.top_offset >> vshift) * dst->linesize[i];
dst->data[i] += off;
}
av_log(s->avctx, AV_LOG_DEBUG, av_log(s->avctx, AV_LOG_DEBUG,
"Output frame with POC %d.\n", frame->poc); "Output frame with POC %d.\n", frame->poc);
return 1; return 1;

@ -288,13 +288,14 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps,
const HEVCSPS *sps) const HEVCSPS *sps)
{ {
const HEVCVPS *vps = (const HEVCVPS*)ps->vps_list[sps->vps_id]->data; const HEVCVPS *vps = (const HEVCVPS*)ps->vps_list[sps->vps_id]->data;
const HEVCWindow *ow = &sps->output_window;
unsigned int num = 0, den = 0; unsigned int num = 0, den = 0;
avctx->pix_fmt = sps->pix_fmt; avctx->pix_fmt = sps->pix_fmt;
avctx->coded_width = sps->width; avctx->coded_width = sps->width;
avctx->coded_height = sps->height; avctx->coded_height = sps->height;
avctx->width = sps->output_width; avctx->width = sps->width - ow->left_offset - ow->right_offset;
avctx->height = sps->output_height; avctx->height = sps->height - ow->top_offset - ow->bottom_offset;
avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics; avctx->has_b_frames = sps->temporal_layer[sps->max_sub_layers - 1].num_reorder_pics;
avctx->profile = sps->ptl.general_ptl.profile_idc; avctx->profile = sps->ptl.general_ptl.profile_idc;
avctx->level = sps->ptl.general_ptl.level_idc; avctx->level = sps->ptl.general_ptl.level_idc;
@ -3118,7 +3119,6 @@ static int hevc_ref_frame(HEVCContext *s, HEVCFrame *dst, HEVCFrame *src)
dst->poc = src->poc; dst->poc = src->poc;
dst->ctb_count = src->ctb_count; dst->ctb_count = src->ctb_count;
dst->window = src->window;
dst->flags = src->flags; dst->flags = src->flags;
dst->sequence = src->sequence; dst->sequence = src->sequence;
@ -3404,6 +3404,6 @@ AVCodec ff_hevc_decoder = {
.init_thread_copy = hevc_init_thread_copy, .init_thread_copy = hevc_init_thread_copy,
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
.profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles), .profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
}; };

@ -317,8 +317,6 @@ typedef struct HEVCFrame {
int poc; int poc;
struct HEVCFrame *collocated_ref; struct HEVCFrame *collocated_ref;
HEVCWindow window;
AVBufferRef *tab_mvf_buf; AVBufferRef *tab_mvf_buf;
AVBufferRef *rpl_tab_buf; AVBufferRef *rpl_tab_buf;
AVBufferRef *rpl_buf; AVBufferRef *rpl_buf;

Loading…
Cancel
Save