This merges committags/n3.4a02ae1c683from libav, originally written by Anton Khirnov and skipped infc63d5ceb3. 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>
| @@ -57,6 +57,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal, | |||
| HEVCSEIContext *sei = &ctx->sei; | |||
| SliceHeader *sh = &ctx->sh; | |||
| GetBitContext *gb = &nal->gb; | |||
| const HEVCWindow *ow; | |||
| int i, num = 0, den = 0; | |||
| 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->vps = (HEVCVPS*)ps->vps_list[ps->sps->vps_id]->data; | |||
| } | |||
| ow = &ps->sps->output_window; | |||
| s->coded_width = ps->sps->width; | |||
| s->coded_height = ps->sps->height; | |||
| s->width = ps->sps->output_width; | |||
| s->height = ps->sps->output_height; | |||
| s->width = ps->sps->width - ow->left_offset - ow->right_offset; | |||
| s->height = ps->sps->height - ow->top_offset - ow->bottom_offset; | |||
| s->format = ps->sps->pix_fmt; | |||
| avctx->profile = ps->sps->ptl.general_ptl.profile_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 apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx) | |||
| { | |||
| HEVCWindow *ow; | |||
| int ret = 0; | |||
| int log2_diff_max_min_transform_block_size; | |||
| 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.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)) { | |||
| sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift)); | |||
| av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d " | |||
| "chroma samples to preserve alignment.\n", | |||
| sps->output_window.left_offset); | |||
| } | |||
| sps->output_width = sps->width - | |||
| (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); | |||
| ow = &sps->output_window; | |||
| if (ow->left_offset >= INT_MAX - ow->right_offset || | |||
| ow->top_offset >= INT_MAX - ow->bottom_offset || | |||
| ow->left_offset + ow->right_offset >= sps->width || | |||
| ow->top_offset + ow->bottom_offset >= sps->height) { | |||
| av_log(avctx, AV_LOG_WARNING, "Invalid cropping offsets: %u/%u/%u/%u\n", | |||
| ow->left_offset, ow->right_offset, ow->top_offset, ow->bottom_offset); | |||
| if (avctx->err_recognition & AV_EF_EXPLODE) { | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| av_log(avctx, AV_LOG_WARNING, | |||
| "Displaying the whole video surface.\n"); | |||
| memset(ow, 0, sizeof(*ow)); | |||
| 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 | |||
| @@ -1221,7 +1213,8 @@ int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx, | |||
| "Parsed SPS: id %d; coded wxh: %dx%d; " | |||
| "cropped wxh: %dx%d; pix_fmt: %s.\n", | |||
| 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)); | |||
| } | |||
| @@ -227,8 +227,6 @@ typedef struct HEVCSPS { | |||
| int chroma_format_idc; | |||
| uint8_t separate_colour_plane_flag; | |||
| ///< output (i.e. cropped) values | |||
| int output_width, output_height; | |||
| HEVCWindow output_window; | |||
| HEVCWindow pic_conf_win; | |||
| @@ -163,7 +163,10 @@ int ff_hevc_set_new_ref(HEVCContext *s, AVFrame **frame, int poc) | |||
| ref->poc = poc; | |||
| 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; | |||
| } | |||
| @@ -204,12 +207,8 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) | |||
| if (nb_output) { | |||
| 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) | |||
| ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT | HEVC_FRAME_FLAG_BUMPING); | |||
| else | |||
| @@ -217,13 +216,6 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) | |||
| if (ret < 0) | |||
| 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, | |||
| "Output frame with POC %d.\n", frame->poc); | |||
| return 1; | |||
| @@ -288,13 +288,14 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps, | |||
| const HEVCSPS *sps) | |||
| { | |||
| const HEVCVPS *vps = (const HEVCVPS*)ps->vps_list[sps->vps_id]->data; | |||
| const HEVCWindow *ow = &sps->output_window; | |||
| unsigned int num = 0, den = 0; | |||
| avctx->pix_fmt = sps->pix_fmt; | |||
| avctx->coded_width = sps->width; | |||
| avctx->coded_height = sps->height; | |||
| avctx->width = sps->output_width; | |||
| avctx->height = sps->output_height; | |||
| avctx->width = sps->width - ow->left_offset - ow->right_offset; | |||
| 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->profile = sps->ptl.general_ptl.profile_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->ctb_count = src->ctb_count; | |||
| dst->window = src->window; | |||
| dst->flags = src->flags; | |||
| dst->sequence = src->sequence; | |||
| @@ -3404,6 +3404,6 @@ AVCodec ff_hevc_decoder = { | |||
| .init_thread_copy = hevc_init_thread_copy, | |||
| .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | | |||
| 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), | |||
| }; | |||
| @@ -317,8 +317,6 @@ typedef struct HEVCFrame { | |||
| int poc; | |||
| struct HEVCFrame *collocated_ref; | |||
| HEVCWindow window; | |||
| AVBufferRef *tab_mvf_buf; | |||
| AVBufferRef *rpl_tab_buf; | |||
| AVBufferRef *rpl_buf; | |||