[FFmpeg-cvslog] hevcdec: remove HEVCContext usage from hevc_sei
James Almer
git at videolan.org
Tue Oct 31 01:09:26 EET 2017
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Sun May 7 10:51:58 2017 -0300| [648a0b450387d535567a1569cabb9e3dbe08a3e5] | committer: Luca Barbato
hevcdec: remove HEVCContext usage from hevc_sei
Based on the H264 SEI implementation.
This will be mainly useful once support for SEI messages that can be
used by the hevc parser are implemented, like Picture Timing.
Signed-off-by: James Almer <jamrial at gmail.com>
Signed-off-by: Luca Barbato <lu_zero at gentoo.org>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=648a0b450387d535567a1569cabb9e3dbe08a3e5
---
libavcodec/hevc_sei.c | 71 +++++++++++++++++++++++----------------------------
libavcodec/hevcdec.c | 49 ++++++++++++++++++-----------------
libavcodec/hevcdec.h | 45 ++++++++++++++++++++------------
3 files changed, 86 insertions(+), 79 deletions(-)
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 1f8554ad5f..b2a0d67882 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -53,10 +53,9 @@ enum HEVC_SEI_TYPE {
SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144,
};
-static int decode_nal_sei_decoded_picture_hash(HEVCContext *s)
+static int decode_nal_sei_decoded_picture_hash(HEVCSEIPictureHash *s, GetBitContext *gb)
{
int cIdx, i;
- GetBitContext *gb = &s->HEVClc.gb;
uint8_t hash_type = get_bits(gb, 8);
for (cIdx = 0; cIdx < 3; cIdx++) {
@@ -75,15 +74,13 @@ static int decode_nal_sei_decoded_picture_hash(HEVCContext *s)
return 0;
}
-static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
+static int decode_nal_sei_frame_packing_arrangement(HEVCSEIFramePacking *s, GetBitContext *gb)
{
- GetBitContext *gb = &s->HEVClc.gb;
-
get_ue_golomb(gb); // frame_packing_arrangement_id
- s->sei_frame_packing_present = !get_bits1(gb);
+ s->present = !get_bits1(gb);
- if (s->sei_frame_packing_present) {
- s->frame_packing_arrangement_type = get_bits(gb, 7);
+ if (s->present) {
+ s->arrangement_type = get_bits(gb, 7);
s->quincunx_subsampling = get_bits1(gb);
s->content_interpretation_type = get_bits(gb, 6);
@@ -92,7 +89,7 @@ static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
// frame0_self_contained_flag frame1_self_contained_flag
skip_bits(gb, 6);
- if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
+ if (!s->quincunx_subsampling && s->arrangement_type != 5)
skip_bits(gb, 16); // frame[01]_grid_position_[xy]
skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
skip_bits1(gb); // frame_packing_arrangement_persistence_flag
@@ -101,63 +98,58 @@ static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
return 0;
}
-static int decode_nal_sei_display_orientation(HEVCContext *s)
+static int decode_nal_sei_display_orientation(HEVCSEIDisplayOrientation *s, GetBitContext *gb)
{
- GetBitContext *gb = &s->HEVClc.gb;
-
- s->sei_display_orientation_present = !get_bits1(gb);
+ s->present = !get_bits1(gb);
- if (s->sei_display_orientation_present) {
- s->sei_hflip = get_bits1(gb); // hor_flip
- s->sei_vflip = get_bits1(gb); // ver_flip
+ if (s->present) {
+ s->hflip = get_bits1(gb); // hor_flip
+ s->vflip = get_bits1(gb); // ver_flip
- s->sei_anticlockwise_rotation = get_bits(gb, 16);
+ s->anticlockwise_rotation = get_bits(gb, 16);
skip_bits1(gb); // display_orientation_persistence_flag
}
return 0;
}
-static int decode_nal_sei_prefix(HEVCContext *s, int type, int size)
+static int decode_nal_sei_prefix(GetBitContext *gb, void *logctx, HEVCSEI *s,
+ int type, int size)
{
- GetBitContext *gb = &s->HEVClc.gb;
-
switch (type) {
case 256: // Mismatched value from HM 8.1
- return decode_nal_sei_decoded_picture_hash(s);
+ return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb);
case SEI_TYPE_FRAME_PACKING:
- return decode_nal_sei_frame_packing_arrangement(s);
+ return decode_nal_sei_frame_packing_arrangement(&s->frame_packing, gb);
case SEI_TYPE_DISPLAY_ORIENTATION:
- return decode_nal_sei_display_orientation(s);
+ return decode_nal_sei_display_orientation(&s->display_orientation, gb);
default:
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
+ av_log(logctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
skip_bits_long(gb, 8 * size);
return 0;
}
}
-static int decode_nal_sei_suffix(HEVCContext *s, int type, int size)
+static int decode_nal_sei_suffix(GetBitContext *gb, void *logctx, HEVCSEI *s,
+ int type, int size)
{
- GetBitContext *gb = &s->HEVClc.gb;
-
switch (type) {
case SEI_TYPE_DECODED_PICTURE_HASH:
- return decode_nal_sei_decoded_picture_hash(s);
+ return decode_nal_sei_decoded_picture_hash(&s->picture_hash, gb);
default:
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
+ av_log(logctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
skip_bits_long(gb, 8 * size);
return 0;
}
}
-static int decode_nal_sei_message(HEVCContext *s)
+static int decode_nal_sei_message(GetBitContext *gb, void *logctx, HEVCSEI *s,
+ int type)
{
- GetBitContext *gb = &s->HEVClc.gb;
-
int payload_type = 0;
int payload_size = 0;
int byte = 0xFF;
- av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
+ av_log(logctx, AV_LOG_DEBUG, "Decoding SEI\n");
while (byte == 0xFF) {
byte = get_bits(gb, 8);
@@ -168,10 +160,10 @@ static int decode_nal_sei_message(HEVCContext *s)
byte = get_bits(gb, 8);
payload_size += byte;
}
- if (s->nal_unit_type == HEVC_NAL_SEI_PREFIX) {
- return decode_nal_sei_prefix(s, payload_type, payload_size);
+ if (type == HEVC_NAL_SEI_PREFIX) {
+ return decode_nal_sei_prefix(gb, logctx, s, payload_type, payload_size);
} else { /* nal_unit_type == NAL_SEI_SUFFIX */
- return decode_nal_sei_suffix(s, payload_type, payload_size);
+ return decode_nal_sei_suffix(gb, logctx, s, payload_type, payload_size);
}
}
@@ -180,10 +172,11 @@ static int more_rbsp_data(GetBitContext *gb)
return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
}
-int ff_hevc_decode_nal_sei(HEVCContext *s)
+int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s,
+ int type)
{
do {
- decode_nal_sei_message(s);
- } while (more_rbsp_data(&s->HEVClc.gb));
+ decode_nal_sei_message(gb, logctx, s, type);
+ } while (more_rbsp_data(gb));
return 0;
}
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 6a04858587..96e47cd187 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -2362,18 +2362,18 @@ static int set_side_data(HEVCContext *s)
{
AVFrame *out = s->ref->frame;
- if (s->sei_frame_packing_present &&
- s->frame_packing_arrangement_type >= 3 &&
- s->frame_packing_arrangement_type <= 5 &&
- s->content_interpretation_type > 0 &&
- s->content_interpretation_type < 3) {
+ if (s->sei.frame_packing.present &&
+ s->sei.frame_packing.arrangement_type >= 3 &&
+ s->sei.frame_packing.arrangement_type <= 5 &&
+ s->sei.frame_packing.content_interpretation_type > 0 &&
+ s->sei.frame_packing.content_interpretation_type < 3) {
AVStereo3D *stereo = av_stereo3d_create_side_data(out);
if (!stereo)
return AVERROR(ENOMEM);
- switch (s->frame_packing_arrangement_type) {
+ switch (s->sei.frame_packing.arrangement_type) {
case 3:
- if (s->quincunx_subsampling)
+ if (s->sei.frame_packing.quincunx_subsampling)
stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
else
stereo->type = AV_STEREO3D_SIDEBYSIDE;
@@ -2386,13 +2386,14 @@ static int set_side_data(HEVCContext *s)
break;
}
- if (s->content_interpretation_type == 2)
+ if (s->sei.frame_packing.content_interpretation_type == 2)
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);
+ if (s->sei.display_orientation.present &&
+ (s->sei.display_orientation.anticlockwise_rotation ||
+ s->sei.display_orientation.hflip || s->sei.display_orientation.vflip)) {
+ double angle = s->sei.display_orientation.anticlockwise_rotation * 360 / (double) (1 << 16);
AVFrameSideData *rotation = av_frame_new_side_data(out,
AV_FRAME_DATA_DISPLAYMATRIX,
sizeof(int32_t) * 9);
@@ -2401,7 +2402,8 @@ static int set_side_data(HEVCContext *s)
av_display_rotation_set((int32_t *)rotation->data, angle);
av_display_matrix_flip((int32_t *)rotation->data,
- s->sei_hflip, s->sei_vflip);
+ s->sei.display_orientation.hflip,
+ s->sei.display_orientation.vflip);
}
return 0;
@@ -2486,7 +2488,8 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
break;
case HEVC_NAL_SEI_PREFIX:
case HEVC_NAL_SEI_SUFFIX:
- ret = ff_hevc_decode_nal_sei(s);
+ ret = ff_hevc_decode_nal_sei(gb, s->avctx, &s->sei,
+ s->nal_unit_type);
if (ret < 0)
goto fail;
break;
@@ -2680,7 +2683,7 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
int h = (i == 1 || i == 2) ? (height >> desc->log2_chroma_h) : height;
uint8_t md5[16];
- av_md5_init(s->md5_ctx);
+ av_md5_init(s->sei.picture_hash.md5_ctx);
for (j = 0; j < h; j++) {
const uint8_t *src = frame->data[i] + j * frame->linesize[i];
#if HAVE_BIGENDIAN
@@ -2690,11 +2693,11 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
src = s->checksum_buf;
}
#endif
- av_md5_update(s->md5_ctx, src, w << pixel_shift);
+ av_md5_update(s->sei.picture_hash.md5_ctx, src, w << pixel_shift);
}
- av_md5_final(s->md5_ctx, md5);
+ av_md5_final(s->sei.picture_hash.md5_ctx, md5);
- if (!memcmp(md5, s->md5[i], 16)) {
+ if (!memcmp(md5, s->sei.picture_hash.md5[i], 16)) {
av_log (s->avctx, AV_LOG_DEBUG, "plane %d - correct ", i);
print_md5(s->avctx, AV_LOG_DEBUG, md5);
av_log (s->avctx, AV_LOG_DEBUG, "; ");
@@ -2702,7 +2705,7 @@ static int verify_md5(HEVCContext *s, AVFrame *frame)
av_log (s->avctx, AV_LOG_ERROR, "mismatching checksum of plane %d - ", i);
print_md5(s->avctx, AV_LOG_ERROR, md5);
av_log (s->avctx, AV_LOG_ERROR, " != ");
- print_md5(s->avctx, AV_LOG_ERROR, s->md5[i]);
+ print_md5(s->avctx, AV_LOG_ERROR, s->sei.picture_hash.md5[i]);
av_log (s->avctx, AV_LOG_ERROR, "\n");
return AVERROR_INVALIDDATA;
}
@@ -2822,7 +2825,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,
} else {
/* verify the SEI checksum */
if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded &&
- s->is_md5) {
+ s->sei.picture_hash.is_md5) {
ret = verify_md5(s, s->ref->frame);
if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) {
ff_hevc_unref_frame(s, s->ref, ~0);
@@ -2830,7 +2833,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output,
}
}
}
- s->is_md5 = 0;
+ s->sei.picture_hash.is_md5 = 0;
if (s->is_decoded) {
av_log(avctx, AV_LOG_DEBUG, "Decoded frame with POC %d.\n", s->poc);
@@ -2890,7 +2893,7 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx)
pic_arrays_free(s);
- av_freep(&s->md5_ctx);
+ av_freep(&s->sei.picture_hash.md5_ctx);
av_frame_free(&s->tmp_frame);
av_frame_free(&s->output_frame);
@@ -2936,8 +2939,8 @@ static av_cold int hevc_init_context(AVCodecContext *avctx)
s->max_ra = INT_MAX;
- s->md5_ctx = av_md5_alloc();
- if (!s->md5_ctx)
+ s->sei.picture_hash.md5_ctx = av_md5_alloc();
+ if (!s->sei.picture_hash.md5_ctx)
goto fail;
ff_bswapdsp_init(&s->bdsp);
diff --git a/libavcodec/hevcdec.h b/libavcodec/hevcdec.h
index ff192f67ae..68ccfb743a 100644
--- a/libavcodec/hevcdec.h
+++ b/libavcodec/hevcdec.h
@@ -444,6 +444,31 @@ typedef struct HEVCLocalContext {
int boundary_flags;
} HEVCLocalContext;
+typedef struct HEVCSEIPictureHash {
+ struct AVMD5 *md5_ctx;
+ uint8_t md5[3][16];
+ uint8_t is_md5;
+} HEVCSEIPictureHash;
+
+typedef struct HEVCSEIFramePacking {
+ int present;
+ int arrangement_type;
+ int content_interpretation_type;
+ int quincunx_subsampling;
+} HEVCSEIFramePacking;
+
+typedef struct HEVCSEIDisplayOrientation {
+ int present;
+ int anticlockwise_rotation;
+ int hflip, vflip;
+} HEVCSEIDisplayOrientation;
+
+typedef struct HEVCSEI {
+ HEVCSEIPictureHash picture_hash;
+ HEVCSEIFramePacking frame_packing;
+ HEVCSEIDisplayOrientation display_orientation;
+} HEVCSEI;
+
typedef struct HEVCContext {
const AVClass *c; // needed by private avoptions
AVCodecContext *avctx;
@@ -461,6 +486,7 @@ typedef struct HEVCContext {
AVFrame *output_frame;
HEVCParamSets ps;
+ HEVCSEI sei;
AVBufferPool *tab_mvf_pool;
AVBufferPool *rpl_tab_pool;
@@ -522,11 +548,6 @@ typedef struct HEVCContext {
// type of the first VCL NAL of the current frame
enum HEVCNALUnitType first_nal_type;
- // for checking the frame checksums
- struct AVMD5 *md5_ctx;
- uint8_t md5[3][16];
- uint8_t is_md5;
-
uint8_t context_initialized;
uint8_t is_nalff; ///< this flag is != 0 if bitstream is encapsulated
///< as a format defined in 14496-15
@@ -534,20 +555,10 @@ typedef struct HEVCContext {
int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
int nuh_layer_id;
-
- /** frame packing arrangement variables */
- int sei_frame_packing_present;
- int frame_packing_arrangement_type;
- int content_interpretation_type;
- int quincunx_subsampling;
-
- /** display orientation */
- int sei_display_orientation_present;
- int sei_anticlockwise_rotation;
- int sei_hflip, sei_vflip;
} HEVCContext;
-int ff_hevc_decode_nal_sei(HEVCContext *s);
+int ff_hevc_decode_nal_sei(GetBitContext *gb, void *logctx, HEVCSEI *s,
+ int type);
/**
* Mark all frames in DPB as unused for reference.
More information about the ffmpeg-cvslog
mailing list