From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> To: ffmpeg-devel@ffmpeg.org Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Subject: [FFmpeg-devel] [PATCH 02/20] avcodec/h264_sei: Don't use GetBit-API for byte-aligned reads Date: Sun, 3 Jul 2022 00:21:42 +0200 Message-ID: <DB6PR0101MB2214C596CC5B73B4E0A280528FBC9@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com> (raw) In-Reply-To: <DB6PR0101MB2214F50F230E6F64A2428AED8FBC9@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com> SEI NALUs and several SEI messages are naturally byte-aligned, so reading them via the bytestream-API is more natural. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/h264_sei.c | 145 ++++++++++++++++++++---------------------- libavcodec/h264_sei.h | 2 +- 2 files changed, 70 insertions(+), 77 deletions(-) diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 034ddb8f1c..d62a276779 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -33,6 +33,7 @@ #include "libavutil/macros.h" #include "libavutil/mem.h" #include "atsc_a53.h" +#include "bytestream.h" #include "get_bits.h" #include "golomb.h" #include "h264_ps.h" @@ -70,8 +71,10 @@ int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, void *logctx) { GetBitContext gb; + av_unused int ret; - init_get_bits(&gb, h->payload, h->payload_size_bits); + ret = init_get_bits8(&gb, h->payload, h->payload_size_bytes); + av_assert1(ret >= 0); if (sps->nal_hrd_parameters_present_flag || sps->vcl_hrd_parameters_present_flag) { @@ -133,44 +136,36 @@ int ff_h264_sei_process_picture_timing(H264SEIPictureTiming *h, const SPS *sps, return 0; } -static int decode_picture_timing(H264SEIPictureTiming *h, GetBitContext *gb, +static int decode_picture_timing(H264SEIPictureTiming *h, GetByteContext *gb, void *logctx) { - int index = get_bits_count(gb); - int size_bits = get_bits_left(gb); - int size = (size_bits + 7) / 8; + int size = bytestream2_get_bytes_left(gb); - if (index & 7) { - av_log(logctx, AV_LOG_ERROR, "Unaligned SEI payload\n"); - return AVERROR_INVALIDDATA; - } if (size > sizeof(h->payload)) { av_log(logctx, AV_LOG_ERROR, "Picture timing SEI payload too large\n"); return AVERROR_INVALIDDATA; } - memcpy(h->payload, gb->buffer + index / 8, size); + bytestream2_get_bufferu(gb, h->payload, size); - h->payload_size_bits = size_bits; + h->payload_size_bytes = size; h->present = 1; return 0; } -static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int size) +static int decode_registered_user_data_afd(H264SEIAFD *h, GetByteContext *gb) { int flag; - if (size-- < 1) + if (bytestream2_get_bytes_left(gb) <= 0) return AVERROR_INVALIDDATA; - skip_bits(gb, 1); // 0 - flag = get_bits(gb, 1); // active_format_flag - skip_bits(gb, 6); // reserved + + flag = !!(bytestream2_get_byteu(gb) & 0x40); // active_format_flag if (flag) { - if (size-- < 1) + if (bytestream2_get_bytes_left(gb) <= 0) return AVERROR_INVALIDDATA; - skip_bits(gb, 4); // reserved - h->active_format_description = get_bits(gb, 4); + h->active_format_description = bytestream2_get_byteu(gb) & 0xF; h->present = 1; } @@ -178,31 +173,26 @@ static int decode_registered_user_data_afd(H264SEIAFD *h, GetBitContext *gb, int } static int decode_registered_user_data_closed_caption(H264SEIA53Caption *h, - GetBitContext *gb, void *logctx, - int size) + GetByteContext *gb) { - if (size < 3) - return AVERROR(EINVAL); - - return ff_parse_a53_cc(&h->buf_ref, gb->buffer + get_bits_count(gb) / 8, size); + return ff_parse_a53_cc(&h->buf_ref, gb->buffer, + bytestream2_get_bytes_left(gb)); } -static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, - void *logctx, int size) +static int decode_registered_user_data(H264SEIContext *h, GetByteContext *gb, + void *logctx) { int country_code, provider_code; - if (size < 3) + if (bytestream2_get_bytes_left(gb) < 3) return AVERROR_INVALIDDATA; - size -= 3; - country_code = get_bits(gb, 8); // itu_t_t35_country_code + country_code = bytestream2_get_byteu(gb); // itu_t_t35_country_code if (country_code == 0xFF) { - if (size < 1) + if (bytestream2_get_bytes_left(gb) < 3) return AVERROR_INVALIDDATA; - skip_bits(gb, 8); // itu_t_t35_country_code_extension_byte - size--; + bytestream2_skipu(gb, 1); // itu_t_t35_country_code_extension_byte } if (country_code != 0xB5) { // usa_country_code @@ -213,23 +203,21 @@ static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, } /* itu_t_t35_payload_byte follows */ - provider_code = get_bits(gb, 16); + provider_code = bytestream2_get_be16u(gb); switch (provider_code) { case 0x31: { // atsc_provider_code uint32_t user_identifier; - if (size < 4) + if (bytestream2_get_bytes_left(gb) < 4) return AVERROR_INVALIDDATA; - size -= 4; - user_identifier = get_bits_long(gb, 32); + user_identifier = bytestream2_get_be32u(gb); switch (user_identifier) { case MKBETAG('D', 'T', 'G', '1'): // afd_data - return decode_registered_user_data_afd(&h->afd, gb, size); + return decode_registered_user_data_afd(&h->afd, gb); case MKBETAG('G', 'A', '9', '4'): // closed captions - return decode_registered_user_data_closed_caption(&h->a53_caption, gb, - logctx, size); + return decode_registered_user_data_closed_caption(&h->a53_caption, gb); default: av_log(logctx, AV_LOG_VERBOSE, "Unsupported User Data Registered ITU-T T35 SEI message (atsc user_identifier = 0x%04x)\n", @@ -248,11 +236,11 @@ static int decode_registered_user_data(H264SEIContext *h, GetBitContext *gb, return 0; } -static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext *gb, - void *logctx, int size) +static int decode_unregistered_user_data(H264SEIUnregistered *h, GetByteContext *gb, + void *logctx) { uint8_t *user_data; - int e, build, i; + int e, build, size = bytestream2_get_bytes_left(gb); AVBufferRef *buf_ref, **tmp; if (size < 16 || size >= INT_MAX - 1) @@ -268,10 +256,8 @@ static int decode_unregistered_user_data(H264SEIUnregistered *h, GetBitContext * return AVERROR(ENOMEM); user_data = buf_ref->data; - for (i = 0; i < size; i++) - user_data[i] = get_bits(gb, 8); - - user_data[i] = 0; + bytestream2_get_bufferu(gb, user_data, size); + user_data[size] = 0; buf_ref->size = size; h->buf_ref[h->nb_buf_ref++] = buf_ref; @@ -384,36 +370,36 @@ static int decode_display_orientation(H264SEIDisplayOrientation *h, return 0; } -static int decode_green_metadata(H264SEIGreenMetaData *h, GetBitContext *gb) +static int decode_green_metadata(H264SEIGreenMetaData *h, GetByteContext *gb) { - h->green_metadata_type = get_bits(gb, 8); + h->green_metadata_type = bytestream2_get_byte(gb); if (h->green_metadata_type == 0) { - h->period_type = get_bits(gb, 8); + h->period_type = bytestream2_get_byte(gb); if (h->period_type == 2) - h->num_seconds = get_bits(gb, 16); + h->num_seconds = bytestream2_get_be16(gb); else if (h->period_type == 3) - h->num_pictures = get_bits(gb, 16); + h->num_pictures = bytestream2_get_be16(gb); - h->percent_non_zero_macroblocks = get_bits(gb, 8); - h->percent_intra_coded_macroblocks = get_bits(gb, 8); - h->percent_six_tap_filtering = get_bits(gb, 8); - h->percent_alpha_point_deblocking_instance = get_bits(gb, 8); + h->percent_non_zero_macroblocks = bytestream2_get_byte(gb); + h->percent_intra_coded_macroblocks = bytestream2_get_byte(gb); + h->percent_six_tap_filtering = bytestream2_get_byte(gb); + h->percent_alpha_point_deblocking_instance = bytestream2_get_byte(gb); } else if (h->green_metadata_type == 1) { - h->xsd_metric_type = get_bits(gb, 8); - h->xsd_metric_value = get_bits(gb, 16); + h->xsd_metric_type = bytestream2_get_byte(gb); + h->xsd_metric_value = bytestream2_get_be16(gb); } return 0; } static int decode_alternative_transfer(H264SEIAlternativeTransfer *h, - GetBitContext *gb) + GetByteContext *gb) { h->present = 1; - h->preferred_transfer_characteristics = get_bits(gb, 8); + h->preferred_transfer_characteristics = bytestream2_get_byte(gb); return 0; } @@ -463,45 +449,52 @@ static int decode_film_grain_characteristics(H264SEIFilmGrainCharacteristics *h, int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, const H264ParamSets *ps, void *logctx) { + GetByteContext gbyte; int master_ret = 0; - while (get_bits_left(gb) > 16 && show_bits(gb, 16)) { + av_assert1((get_bits_count(gb) % 8) == 0); + bytestream2_init(&gbyte, gb->buffer + get_bits_count(gb) / 8, + get_bits_left(gb) / 8); + + while (bytestream2_get_bytes_left(&gbyte) > 2 && bytestream2_peek_ne16(&gbyte)) { + GetByteContext gbyte_payload; GetBitContext gb_payload; int type = 0; unsigned size = 0; int ret = 0; do { - if (get_bits_left(gb) < 8) + if (bytestream2_get_bytes_left(&gbyte) <= 0) return AVERROR_INVALIDDATA; - type += show_bits(gb, 8); - } while (get_bits(gb, 8) == 255); + type += bytestream2_peek_byteu(&gbyte); + } while (bytestream2_get_byteu(&gbyte) == 255); do { - if (get_bits_left(gb) < 8) + if (bytestream2_get_bytes_left(&gbyte) <= 0) return AVERROR_INVALIDDATA; - size += show_bits(gb, 8); - } while (get_bits(gb, 8) == 255); + size += bytestream2_peek_byteu(&gbyte); + } while (bytestream2_get_byteu(&gbyte) == 255); - if (size > get_bits_left(gb) / 8) { + if (size > bytestream2_get_bytes_left(&gbyte)) { av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", - type, 8*size, get_bits_left(gb)); + type, size, bytestream2_get_bytes_left(&gbyte)); return AVERROR_INVALIDDATA; } - ret = init_get_bits8(&gb_payload, gb->buffer + get_bits_count(gb) / 8, size); + bytestream2_init (&gbyte_payload, gbyte.buffer, size); + ret = init_get_bits8(&gb_payload, gbyte.buffer, size); if (ret < 0) return ret; switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI - ret = decode_picture_timing(&h->picture_timing, &gb_payload, logctx); + ret = decode_picture_timing(&h->picture_timing, &gbyte_payload, logctx); break; case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: - ret = decode_registered_user_data(h, &gb_payload, logctx, size); + ret = decode_registered_user_data(h, &gbyte_payload, logctx); break; case SEI_TYPE_USER_DATA_UNREGISTERED: - ret = decode_unregistered_user_data(&h->unregistered, &gb_payload, logctx, size); + ret = decode_unregistered_user_data(&h->unregistered, &gbyte_payload, logctx); break; case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(&h->recovery_point, &gb_payload, logctx); @@ -516,10 +509,10 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, ret = decode_display_orientation(&h->display_orientation, &gb_payload); break; case SEI_TYPE_GREEN_METADATA: - ret = decode_green_metadata(&h->green_metadata, &gb_payload); + ret = decode_green_metadata(&h->green_metadata, &gbyte_payload); break; case SEI_TYPE_ALTERNATIVE_TRANSFER_CHARACTERISTICS: - ret = decode_alternative_transfer(&h->alternative_transfer, &gb_payload); + ret = decode_alternative_transfer(&h->alternative_transfer, &gbyte_payload); break; case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: ret = decode_film_grain_characteristics(&h->film_grain_characteristics, &gb_payload); @@ -537,7 +530,7 @@ int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, type, -get_bits_left(&gb_payload)); } - skip_bits_long(gb, 8 * size); + bytestream2_skipu(&gbyte, size); } return master_ret; diff --git a/libavcodec/h264_sei.h b/libavcodec/h264_sei.h index f9166b45df..d7866f42ad 100644 --- a/libavcodec/h264_sei.h +++ b/libavcodec/h264_sei.h @@ -66,7 +66,7 @@ typedef struct H264SEITimeCode { typedef struct H264SEIPictureTiming { // maximum size of pic_timing according to the spec should be 274 bits uint8_t payload[40]; - int payload_size_bits; + int payload_size_bytes; int present; H264_SEI_PicStructType pic_struct; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2022-07-02 22:22 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-07-02 22:20 [FFmpeg-devel] [PATCH 01/20] avcodec/hevc_sei: Use proper type for NALU type Andreas Rheinhardt 2022-07-02 22:21 ` Andreas Rheinhardt [this message] 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 03/20] configure: Add (h264|hevc)_sei subsystems Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 04/20] avcodec/sei: Add tag to SEI enumeration Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 05/20] fftools/ffprobe: Improve description of AFD side data Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 06/20] fate/h264: Add Active Format Descriptor test Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 07/20] avcodec/h2645_sei: Factor parsing common SEI messages out Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 08/20] avcodec/h2645_sei: Factor updating H.2645 SEIs out Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 09/20] avcodec/h2645_sei: Factor out freeing common SEI parts Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 10/20] avcodec/h2645_sei: Factor out applying SEIs to frames Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 11/20] avcodec/h264_sei, sei: Make H264_SEI_FpaType generic Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 12/20] avcodec/h2645_sei: Attach AVStereo3D side data generically Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 13/20] avcodec/h2645_sei: Also support Active Format Descriptor for HEVC Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 14/20] avcodec/h264_ps: Don't error out on unknown aspect ratio Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 15/20] avcodec/h264data: Deduplicate H.26[45] aspect ratio table Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 16/20] avcodec/hevc_ps: Fix wrong copyright years Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 17/20] avcodec/h264_ps: Don't output invalid chroma location Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 18/20] avcodec/h26[45]_metadata_bsf: Fix range of chroma_sample_loc_type Andreas Rheinhardt 2022-07-02 22:21 ` [FFmpeg-devel] [PATCH 19/20] avcodec/(h264|hevc)_ps: Factor common VUI code out Andreas Rheinhardt 2022-07-02 22:22 ` [FFmpeg-devel] [PATCH 20/20] avcodec/h2645_sei: Factor attaching film grain side-data to frame out Andreas Rheinhardt 2022-07-02 23:28 ` [FFmpeg-devel] [PATCH 01/20] avcodec/hevc_sei: Use proper type for NALU type Soft Works 2022-11-23 3:19 ` Andreas Rheinhardt 2022-11-23 4:15 ` Soft Works 2022-11-23 5:05 ` Soft Works
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=DB6PR0101MB2214C596CC5B73B4E0A280528FBC9@DB6PR0101MB2214.eurprd01.prod.exchangelabs.com \ --to=andreas.rheinhardt@outlook.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git