int ff_h264_decode_sei(H264Context *h) { while (get_bits_left(&h->gb) > 16) { int size = 0; int type = 0; int ret = 0; int last = 0; while (get_bits_left(&h->gb) >= 8 && (last = get_bits(&h->gb, 8)) == 255) { type += 255; } type += last; last = 0; while (get_bits_left(&h->gb) >= 8 && (last = get_bits(&h->gb, 8)) == 255) { size += 255; } size += last; if (size > get_bits_left(&h->gb) / 8) { av_log(h->avctx, AV_LOG_ERROR, "SEI type %d truncated at %d\n", type, get_bits_left(&h->gb)); return AVERROR_INVALIDDATA; } switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI ret = decode_picture_timing(h); break; case SEI_TYPE_USER_DATA_REGISTERED: ret = decode_registered_user_data(h, size); break; case SEI_TYPE_USER_DATA_UNREGISTERED: ret = decode_unregistered_user_data(h, size); break; case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(h); break; case SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(h); break; case SEI_TYPE_FRAME_PACKING: ret = decode_frame_packing_arrangement(h); break; case SEI_TYPE_DISPLAY_ORIENTATION: ret = decode_display_orientation(h); break; default: av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); skip_bits(&h->gb, 8 * size); } if (ret < 0) return ret; // FIXME check bits here align_get_bits(&h->gb); } return 0; }
int ff_h264_decode_sei(H264Context *h) { while (get_bits_left(&h->gb) > 16 && show_bits(&h->gb, 16)) { int type = 0; unsigned size = 0; unsigned next; int ret = 0; do { if (get_bits_left(&h->gb) < 8) return AVERROR_INVALIDDATA; type += show_bits(&h->gb, 8); } while (get_bits(&h->gb, 8) == 255); do { if (get_bits_left(&h->gb) < 8) return AVERROR_INVALIDDATA; size += show_bits(&h->gb, 8); } while (get_bits(&h->gb, 8) == 255); if (h->avctx->debug&FF_DEBUG_STARTCODE) av_log(h->avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size); if (size > get_bits_left(&h->gb) / 8) { av_log(h->avctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", type, 8*size, get_bits_left(&h->gb)); return AVERROR_INVALIDDATA; } next = get_bits_count(&h->gb) + 8 * size; switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI ret = decode_picture_timing(h); break; case SEI_TYPE_USER_DATA_REGISTERED: ret = decode_registered_user_data(h, size); break; case SEI_TYPE_USER_DATA_UNREGISTERED: ret = decode_unregistered_user_data(h, size); break; case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(h); break; case SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(h); break; case SEI_TYPE_FRAME_PACKING: ret = decode_frame_packing_arrangement(h); break; case SEI_TYPE_DISPLAY_ORIENTATION: ret = decode_display_orientation(h); break; case SEI_TYPE_GREEN_METADATA: ret = decode_GreenMetadata(h); break; default: av_log(h->avctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); } if (ret < 0) return ret; skip_bits_long(&h->gb, next - get_bits_count(&h->gb)); // FIXME check bits here align_get_bits(&h->gb); } return 0; }
int ff_h264_sei_decode(H264SEIContext *h, GetBitContext *gb, const H264ParamSets *ps, void *logctx) { int master_ret = 0; while (get_bits_left(gb) > 16 && show_bits(gb, 16)) { int type = 0; unsigned size = 0; unsigned next; int ret = 0; do { if (get_bits_left(gb) < 8) return AVERROR_INVALIDDATA; type += show_bits(gb, 8); } while (get_bits(gb, 8) == 255); do { if (get_bits_left(gb) < 8) return AVERROR_INVALIDDATA; size += show_bits(gb, 8); } while (get_bits(gb, 8) == 255); if (size > get_bits_left(gb) / 8) { av_log(logctx, AV_LOG_ERROR, "SEI type %d size %d truncated at %d\n", type, 8*size, get_bits_left(gb)); return AVERROR_INVALIDDATA; } next = get_bits_count(gb) + 8 * size; switch (type) { case SEI_TYPE_PIC_TIMING: // Picture timing SEI ret = decode_picture_timing(&h->picture_timing, gb, ps, logctx); break; case SEI_TYPE_USER_DATA_REGISTERED: ret = decode_registered_user_data(h, gb, logctx, size); break; case SEI_TYPE_USER_DATA_UNREGISTERED: ret = decode_unregistered_user_data(&h->unregistered, gb, logctx, size); break; case SEI_TYPE_RECOVERY_POINT: ret = decode_recovery_point(&h->recovery_point, gb); break; case SEI_TYPE_BUFFERING_PERIOD: ret = decode_buffering_period(&h->buffering_period, gb, ps, logctx); break; case SEI_TYPE_FRAME_PACKING: ret = decode_frame_packing_arrangement(&h->frame_packing, gb); break; case SEI_TYPE_DISPLAY_ORIENTATION: ret = decode_display_orientation(&h->display_orientation, gb); break; case SEI_TYPE_GREEN_METADATA: ret = decode_green_metadata(&h->green_metadata, gb); break; default: av_log(logctx, AV_LOG_DEBUG, "unknown SEI type %d\n", type); } if (ret < 0 && ret != AVERROR_PS_NOT_FOUND) return ret; if (ret < 0) master_ret = ret; skip_bits_long(gb, next - get_bits_count(gb)); // FIXME check bits here align_get_bits(gb); } return master_ret; }