summaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-12-18 21:11:47 +0100
committerAnton Khirnov <anton@khirnov.net>2017-01-12 16:27:56 +0100
commita02ae1c6837a54ed9e7735da2b1f789b2f4b6e13 (patch)
tree204060552648d600f0a9f68090fde798692cfe80 /libavcodec
parent019ab88a95cb31b698506d90e8ce56695a7f1cc5 (diff)
downloadffmpeg-streaming-a02ae1c6837a54ed9e7735da2b1f789b2f4b6e13.zip
ffmpeg-streaming-a02ae1c6837a54ed9e7735da2b1f789b2f4b6e13.tar.gz
hevcdec: export cropping information instead of handling it internally
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/hevc_parser.c6
-rw-r--r--libavcodec/hevc_ps.c33
-rw-r--r--libavcodec/hevc_ps.h2
-rw-r--r--libavcodec/hevc_refs.c19
-rw-r--r--libavcodec/hevcdec.c7
-rw-r--r--libavcodec/hevcdec.h2
6 files changed, 24 insertions, 45 deletions
diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c
index 49e7122..74a0257 100644
--- a/libavcodec/hevc_parser.c
+++ b/libavcodec/hevc_parser.c
@@ -49,6 +49,7 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
HEVCPPS *pps;
HEVCSPS *sps;
+ HEVCWindow *ow;
unsigned int pps_id;
get_bits1(gb); // first slice in pic
@@ -62,12 +63,13 @@ static int hevc_parse_slice_header(AVCodecParserContext *s, H2645NAL *nal,
}
pps = (HEVCPPS*)ctx->ps.pps_list[pps_id]->data;
sps = (HEVCSPS*)ctx->ps.sps_list[pps->sps_id]->data;
+ ow = &sps->output_window;
/* export the stream parameters */
s->coded_width = sps->width;
s->coded_height = sps->height;
- s->width = sps->output_width;
- s->height = sps->output_height;
+ s->width = sps->width - ow->left_offset - ow->right_offset;
+ s->height = sps->height - ow->top_offset - ow->bottom_offset;
s->format = sps->pix_fmt;
avctx->profile = sps->ptl.general_ptl.profile_idc;
avctx->level = sps->ptl.general_ptl.level_idc;
diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c
index 2471907..4a5a47e 100644
--- a/libavcodec/hevc_ps.c
+++ b/libavcodec/hevc_ps.c
@@ -682,6 +682,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;
@@ -902,32 +903,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->output_width <= 0 || sps->output_height <= 0) {
- 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) {
ret = AVERROR_INVALIDDATA;
goto err;
}
av_log(avctx, AV_LOG_WARNING,
"Displaying the whole video surface.\n");
- sps->output_window.left_offset =
- sps->output_window.right_offset =
- sps->output_window.top_offset =
- sps->output_window.bottom_offset = 0;
- sps->output_width = sps->width;
- sps->output_height = sps->height;
+ memset(ow, 0, sizeof(*ow));
}
// Inferred parameters
@@ -1008,7 +998,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));
}
diff --git a/libavcodec/hevc_ps.h b/libavcodec/hevc_ps.h
index d95aa51..89a481b 100644
--- a/libavcodec/hevc_ps.h
+++ b/libavcodec/hevc_ps.h
@@ -141,8 +141,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;
diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c
index 30409ba..0c19187 100644
--- a/libavcodec/hevc_refs.c
+++ b/libavcodec/hevc_refs.c
@@ -162,7 +162,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;
}
@@ -193,26 +196,12 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush)
if (nb_output) {
HEVCFrame *frame = &s->DPB[min_idx];
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->frame->format);
- int pixel_shift;
-
- if (!desc)
- return AVERROR_BUG;
-
- pixel_shift = desc->comp[0].depth > 8;
ret = av_frame_ref(out, frame->frame);
ff_hevc_unref_frame(s, frame, HEVC_FRAME_FLAG_OUTPUT);
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) * out->linesize[i];
- out->data[i] += off;
- }
av_log(s->avctx, AV_LOG_DEBUG,
"Output frame with POC %d.\n", frame->poc);
return 1;
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 700b5f0..a4c936e 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -338,13 +338,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;
@@ -2864,7 +2865,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;
@@ -3092,4 +3092,5 @@ AVCodec ff_hevc_decoder = {
.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_FRAME_THREADS,
.profiles = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
+ .caps_internal = FF_CODEC_CAP_EXPORTS_CROPPING,
};
diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h
index 82adad2..ff192f6 100644
--- a/libavcodec/hevcdec.h
+++ b/libavcodec/hevcdec.h
@@ -374,8 +374,6 @@ typedef struct HEVCFrame {
int poc;
struct HEVCFrame *collocated_ref;
- HEVCWindow window;
-
AVBufferRef *tab_mvf_buf;
AVBufferRef *rpl_tab_buf;
AVBufferRef *rpl_buf;
OpenPOWER on IntegriCloud