Unified · Split
| @@ -167,7 +167,7 @@ OBJS-$(CONFIG_STARTCODE) += startcode.o · 166 unmodified lines | ||
| 167 | 167 | OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o |
| 168 | 168 | OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o |
| 169 | 169 | OBJS-$(CONFIG_TPELDSP) += tpeldsp.o |
| 170 | −OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o | |
| 170 | +OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o hw_base_encode_h264.o | |
| 171 | 171 | OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o |
| 172 | 172 | OBJS-$(CONFIG_VC1DSP) += vc1dsp.o |
| 173 | 173 | OBJS-$(CONFIG_VIDEODSP) += videodsp.o |
| @@ -0,0 +1,265 @@ | ||
| 1 | +/* | |
| 2 | + * This file is part of FFmpeg. | |
| 3 | + * | |
| 4 | + * FFmpeg is free software; you can redistribute it and/or | |
| 5 | + * modify it under the terms of the GNU Lesser General Public | |
| 6 | + * License as published by the Free Software Foundation; either | |
| 7 | + * version 2.1 of the License, or (at your option) any later version. | |
| 8 | + * | |
| 9 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | + * Lesser General Public License for more details. | |
| 13 | + * | |
| 14 | + * You should have received a copy of the GNU Lesser General Public | |
| 15 | + * License along with FFmpeg; if not, write to the Free Software | |
| 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#include "hw_base_encode_h264.h" | |
| 20 | + | |
| 21 | +#include "h2645data.h" | |
| 22 | +#include "h264_levels.h" | |
| 23 | + | |
| 24 | +#include "libavutil/pixdesc.h" | |
| 25 | + | |
| 26 | +int ff_hw_base_encode_init_params_h264(FFHWBaseEncodeContext *base_ctx, | |
| 27 | + AVCodecContext *avctx, | |
| 28 | + FFHWBaseEncodeH264 *common, | |
| 29 | + FFHWBaseEncodeH264Opts *opts) | |
| 30 | +{ | |
| 31 | + H264RawSPS *sps = &common->raw_sps; | |
| 32 | + H264RawPPS *pps = &common->raw_pps; | |
| 33 | + const AVPixFmtDescriptor *desc; | |
| 34 | + int bit_depth; | |
| 35 | + | |
| 36 | + memset(sps, 0, sizeof(*sps)); | |
| 37 | + memset(pps, 0, sizeof(*pps)); | |
| 38 | + | |
| 39 | + desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format); | |
| 40 | + av_assert0(desc); | |
| 41 | + if (desc->nb_components == 1 || desc->log2_chroma_w != 1 || desc->log2_chroma_h != 1) { | |
| 42 | + av_log(avctx, AV_LOG_ERROR, "Chroma format of input pixel format " | |
| 43 | + "%s is not supported.\n", desc->name); | |
| 44 | + return AVERROR(EINVAL); | |
| 45 | + } | |
| 46 | + bit_depth = desc->comp[0].depth; | |
| 47 | + | |
| 48 | + sps->nal_unit_header.nal_ref_idc = 3; | |
| 49 | + sps->nal_unit_header.nal_unit_type = H264_NAL_SPS; | |
| 50 | + | |
| 51 | + sps->profile_idc = avctx->profile & 0xff; | |
| 52 | + | |
| 53 | + if (avctx->profile == AV_PROFILE_H264_CONSTRAINED_BASELINE || | |
| 54 | + avctx->profile == AV_PROFILE_H264_MAIN) | |
| 55 | + sps->constraint_set1_flag = 1; | |
| 56 | + | |
| 57 | + if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) | |
| 58 | + sps->constraint_set3_flag = base_ctx->gop_size == 1; | |
| 59 | + | |
| 60 | + if (avctx->profile == AV_PROFILE_H264_MAIN || | |
| 61 | + avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) { | |
| 62 | + sps->constraint_set4_flag = 1; | |
| 63 | + sps->constraint_set5_flag = base_ctx->b_per_p == 0; | |
| 64 | + } | |
| 65 | + | |
| 66 | + if (base_ctx->gop_size == 1) | |
| 67 | + common->dpb_frames = 0; | |
| 68 | + else | |
| 69 | + common->dpb_frames = 1 + base_ctx->max_b_depth; | |
| 70 | + | |
| 71 | + if (avctx->level != AV_LEVEL_UNKNOWN) { | |
| 72 | + sps->level_idc = avctx->level; | |
| 73 | + } else { | |
| 74 | + const H264LevelDescriptor *level; | |
| 75 | + int framerate; | |
| 76 | + | |
| 77 | + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) | |
| 78 | + framerate = avctx->framerate.num / avctx->framerate.den; | |
| 79 | + else | |
| 80 | + framerate = 0; | |
| 81 | + | |
| 82 | + level = ff_h264_guess_level(sps->profile_idc, | |
| 83 | + opts->bit_rate, | |
| 84 | + framerate, | |
| 85 | + opts->mb_width * 16, | |
| 86 | + opts->mb_height * 16, | |
| 87 | + common->dpb_frames); | |
| 88 | + if (level) { | |
| 89 | + av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); | |
| 90 | + if (level->constraint_set3_flag) | |
| 91 | + sps->constraint_set3_flag = 1; | |
| 92 | + sps->level_idc = level->level_idc; | |
| 93 | + } else { | |
| 94 | + av_log(avctx, AV_LOG_WARNING, "Stream will not conform " | |
| 95 | + "to any level: using level 6.2.\n"); | |
| 96 | + sps->level_idc = 62; | |
| 97 | + } | |
| 98 | + } | |
| 99 | + | |
| 100 | + sps->seq_parameter_set_id = 0; | |
| 101 | + sps->chroma_format_idc = 1; | |
| 102 | + sps->bit_depth_luma_minus8 = bit_depth - 8; | |
| 103 | + sps->bit_depth_chroma_minus8 = bit_depth - 8; | |
| 104 | + | |
| 105 | + sps->log2_max_frame_num_minus4 = 4; | |
| 106 | + sps->pic_order_cnt_type = base_ctx->max_b_depth ? 0 : 2; | |
| 107 | + if (sps->pic_order_cnt_type == 0) { | |
| 108 | + sps->log2_max_pic_order_cnt_lsb_minus4 = 4; | |
| 109 | + } | |
| 110 | + | |
| 111 | + sps->max_num_ref_frames = common->dpb_frames; | |
| 112 | + | |
| 113 | + sps->pic_width_in_mbs_minus1 = opts->mb_width - 1; | |
| 114 | + sps->pic_height_in_map_units_minus1 = opts->mb_height - 1; | |
| 115 | + | |
| 116 | + sps->frame_mbs_only_flag = 1; | |
| 117 | + sps->direct_8x8_inference_flag = 1; | |
| 118 | + | |
| 119 | + if (avctx->width != 16 * opts->mb_width || | |
| 120 | + avctx->height != 16 * opts->mb_height) { | |
| 121 | + sps->frame_cropping_flag = 1; | |
| 122 | + | |
| 123 | + sps->frame_crop_left_offset = 0; | |
| 124 | + sps->frame_crop_right_offset = | |
| 125 | + (16 * opts->mb_width - avctx->width) / 2; | |
| 126 | + sps->frame_crop_top_offset = 0; | |
| 127 | + sps->frame_crop_bottom_offset = | |
| 128 | + (16 * opts->mb_height - avctx->height) / 2; | |
| 129 | + } else { | |
| 130 | + sps->frame_cropping_flag = 0; | |
| 131 | + } | |
| 132 | + | |
| 133 | + sps->vui_parameters_present_flag = 1; | |
| 134 | + | |
| 135 | + if (avctx->sample_aspect_ratio.num != 0 && | |
| 136 | + avctx->sample_aspect_ratio.den != 0) { | |
| 137 | + int num, den, i; | |
| 138 | + av_reduce(&num, &den, avctx->sample_aspect_ratio.num, | |
| 139 | + avctx->sample_aspect_ratio.den, 65535); | |
| 140 | + for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { | |
| 141 | + if (num == ff_h2645_pixel_aspect[i].num && | |
| 142 | + den == ff_h2645_pixel_aspect[i].den) { | |
| 143 | + sps->vui.aspect_ratio_idc = i; | |
| 144 | + break; | |
| 145 | + } | |
| 146 | + } | |
| 147 | + if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { | |
| 148 | + sps->vui.aspect_ratio_idc = 255; | |
| 149 | + sps->vui.sar_width = num; | |
| 150 | + sps->vui.sar_height = den; | |
| 151 | + } | |
| 152 | + sps->vui.aspect_ratio_info_present_flag = 1; | |
| 153 | + } | |
| 154 | + | |
| 155 | + // Unspecified video format, from table E-2. | |
| 156 | + sps->vui.video_format = 5; | |
| 157 | + sps->vui.video_full_range_flag = | |
| 158 | + avctx->color_range == AVCOL_RANGE_JPEG; | |
| 159 | + sps->vui.colour_primaries = avctx->color_primaries; | |
| 160 | + sps->vui.transfer_characteristics = avctx->color_trc; | |
| 161 | + sps->vui.matrix_coefficients = avctx->colorspace; | |
| 162 | + if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || | |
| 163 | + avctx->color_trc != AVCOL_TRC_UNSPECIFIED || | |
| 164 | + avctx->colorspace != AVCOL_SPC_UNSPECIFIED) | |
| 165 | + sps->vui.colour_description_present_flag = 1; | |
| 166 | + if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || | |
| 167 | + sps->vui.colour_description_present_flag) | |
| 168 | + sps->vui.video_signal_type_present_flag = 1; | |
| 169 | + | |
| 170 | + if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { | |
| 171 | + sps->vui.chroma_loc_info_present_flag = 1; | |
| 172 | + sps->vui.chroma_sample_loc_type_top_field = | |
| 173 | + sps->vui.chroma_sample_loc_type_bottom_field = | |
| 174 | + avctx->chroma_sample_location - 1; | |
| 175 | + } | |
| 176 | + | |
| 177 | + sps->vui.timing_info_present_flag = 1; | |
| 178 | + if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { | |
| 179 | + sps->vui.num_units_in_tick = avctx->framerate.den; | |
| 180 | + sps->vui.time_scale = 2 * avctx->framerate.num; | |
| 181 | + sps->vui.fixed_frame_rate_flag = 1; | |
| 182 | + } else { | |
| 183 | + sps->vui.num_units_in_tick = avctx->time_base.num; | |
| 184 | + sps->vui.time_scale = 2 * avctx->time_base.den; | |
| 185 | + sps->vui.fixed_frame_rate_flag = 0; | |
| 186 | + } | |
| 187 | + | |
| 188 | + if (opts->flags & FF_HW_H264_SEI_TIMING) { | |
| 189 | + H264RawHRD *hrd = &sps->vui.nal_hrd_parameters; | |
| 190 | + H264RawSEIBufferingPeriod *bp = &common->sei_buffering_period; | |
| 191 | + | |
| 192 | + sps->vui.nal_hrd_parameters_present_flag = 1; | |
| 193 | + | |
| 194 | + hrd->cpb_cnt_minus1 = 0; | |
| 195 | + | |
| 196 | + // Try to scale these to a sensible range so that the | |
| 197 | + // golomb encode of the value is not overlong. | |
| 198 | + hrd->bit_rate_scale = | |
| 199 | + av_clip_uintp2(av_log2(opts->bit_rate) - 15 - 6, 4); | |
| 200 | + hrd->bit_rate_value_minus1[0] = | |
| 201 | + (opts->bit_rate >> hrd->bit_rate_scale + 6) - 1; | |
| 202 | + | |
| 203 | + hrd->cpb_size_scale = | |
| 204 | + av_clip_uintp2(av_log2(opts->hrd_buffer_size) - 15 - 4, 4); | |
| 205 | + hrd->cpb_size_value_minus1[0] = | |
| 206 | + (opts->hrd_buffer_size >> hrd->cpb_size_scale + 4) - 1; | |
| 207 | + | |
| 208 | + // CBR mode as defined for the HRD cannot be achieved without filler | |
| 209 | + // data, so this flag cannot be set even with VAAPI CBR modes. | |
| 210 | + hrd->cbr_flag[0] = 0; | |
| 211 | + | |
| 212 | + hrd->initial_cpb_removal_delay_length_minus1 = 23; | |
| 213 | + hrd->cpb_removal_delay_length_minus1 = 23; | |
| 214 | + hrd->dpb_output_delay_length_minus1 = 7; | |
| 215 | + hrd->time_offset_length = 0; | |
| 216 | + | |
| 217 | + bp->seq_parameter_set_id = sps->seq_parameter_set_id; | |
| 218 | + | |
| 219 | + // This calculation can easily overflow 32 bits. | |
| 220 | + bp->nal.initial_cpb_removal_delay[0] = 90000 * | |
| 221 | + (uint64_t)opts->initial_buffer_fullness / | |
| 222 | + opts->hrd_buffer_size; | |
| 223 | + bp->nal.initial_cpb_removal_delay_offset[0] = 0; | |
| 224 | + } else { | |
| 225 | + sps->vui.nal_hrd_parameters_present_flag = 0; | |
| 226 | + sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag; | |
| 227 | + } | |
| 228 | + | |
| 229 | + sps->vui.bitstream_restriction_flag = 1; | |
| 230 | + sps->vui.motion_vectors_over_pic_boundaries_flag = 1; | |
| 231 | + sps->vui.log2_max_mv_length_horizontal = 15; | |
| 232 | + sps->vui.log2_max_mv_length_vertical = 15; | |
| 233 | + sps->vui.max_num_reorder_frames = base_ctx->max_b_depth; | |
| 234 | + sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1; | |
| 235 | + | |
| 236 | + pps->nal_unit_header.nal_ref_idc = 3; | |
| 237 | + pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; | |
| 238 | + | |
| 239 | + pps->pic_parameter_set_id = 0; | |
| 240 | + pps->seq_parameter_set_id = 0; | |
| 241 | + | |
| 242 | + pps->entropy_coding_mode_flag = | |
| 243 | + !(sps->profile_idc == AV_PROFILE_H264_BASELINE || | |
| 244 | + sps->profile_idc == AV_PROFILE_H264_EXTENDED || | |
| 245 | + sps->profile_idc == AV_PROFILE_H264_CAVLC_444); | |
| 246 | + if (!opts->cabac && pps->entropy_coding_mode_flag) | |
| 247 | + pps->entropy_coding_mode_flag = 0; | |
| 248 | + | |
| 249 | + pps->num_ref_idx_l0_default_active_minus1 = 0; | |
| 250 | + pps->num_ref_idx_l1_default_active_minus1 = 0; | |
| 251 | + | |
| 252 | + pps->pic_init_qp_minus26 = opts->fixed_qp_idr - 26; | |
| 253 | + | |
| 254 | + if (sps->profile_idc == AV_PROFILE_H264_BASELINE || | |
| 255 | + sps->profile_idc == AV_PROFILE_H264_EXTENDED || | |
| 256 | + sps->profile_idc == AV_PROFILE_H264_MAIN) { | |
| 257 | + pps->more_rbsp_data = 0; | |
| 258 | + } else { | |
| 259 | + pps->more_rbsp_data = 1; | |
| 260 | + | |
| 261 | + pps->transform_8x8_mode_flag = 1; | |
| 262 | + } | |
| 263 | + | |
| 264 | + return 0; | |
| 265 | +} | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/* | |
| 2 | + * This file is part of FFmpeg. | |
| 3 | + * | |
| 4 | + * FFmpeg is free software; you can redistribute it and/or | |
| 5 | + * modify it under the terms of the GNU Lesser General Public | |
| 6 | + * License as published by the Free Software Foundation; either | |
| 7 | + * version 2.1 of the License, or (at your option) any later version. | |
| 8 | + * | |
| 9 | + * FFmpeg is distributed in the hope that it will be useful, | |
| 10 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 12 | + * Lesser General Public License for more details. | |
| 13 | + * | |
| 14 | + * You should have received a copy of the GNU Lesser General Public | |
| 15 | + * License along with FFmpeg; if not, write to the Free Software | |
| 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
| 17 | + */ | |
| 18 | + | |
| 19 | +#ifndef AVCODEC_HW_BASE_ENCODE_H264_H | |
| 20 | +#define AVCODEC_HW_BASE_ENCODE_H264_H | |
| 21 | + | |
| 22 | +#include "hw_base_encode.h" | |
| 23 | +#include "cbs_h264.h" | |
| 24 | + | |
| 25 | +typedef struct FFHWBaseEncodeH264 { | |
| 26 | + H264RawSPS raw_sps; | |
| 27 | + H264RawPPS raw_pps; | |
| 28 | + H264RawAUD raw_aud; | |
| 29 | + | |
| 30 | + H264RawSEIBufferingPeriod sei_buffering_period; | |
| 31 | + | |
| 32 | + int dpb_frames; | |
| 33 | +} FFHWBaseEncodeH264; | |
| 34 | + | |
| 35 | +typedef struct FFHWBaseEncodeH264Opts { | |
| 36 | + int flags; | |
| 37 | +#define FF_HW_H264_SEI_TIMING (1 << 0) | |
| 38 | + | |
| 39 | + int mb_width; | |
| 40 | + int mb_height; | |
| 41 | + int64_t bit_rate; | |
| 42 | + int cabac; | |
| 43 | + int fixed_qp_idr; | |
| 44 | + uint64_t hrd_buffer_size; | |
| 45 | + uint64_t initial_buffer_fullness; | |
| 46 | +} FFHWBaseEncodeH264Opts; | |
| 47 | + | |
| 48 | +int ff_hw_base_encode_init_params_h264(FFHWBaseEncodeContext *base_ctx, | |
| 49 | + AVCodecContext *avctx, | |
| 50 | + FFHWBaseEncodeH264 *common, | |
| 51 | + FFHWBaseEncodeH264Opts *opts); | |
| 52 | + | |
| 53 | +#endif /* AVCODEC_HW_BASE_ENCODE_H264_H */ | |
| @@ -33,6 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | #include "cbs_h264.h" |
| 34 | 34 | #include "codec_internal.h" |
| 35 | 35 | #include "h264.h" |
| 36 | +#include "hw_base_encode_h264.h" | |
| 36 | 37 | #include "h264_levels.h" |
| 37 | 38 | #include "h2645data.h" |
| 38 | 39 | #include "vaapi_encode.h" |
| @@ -67,6 +68,7 @@ typedef struct VAAPIEncodeH264Picture { · 28 unmodified lines | ||
| 67 | 68 | |
| 68 | 69 | typedef struct VAAPIEncodeH264Context { |
| 69 | 70 | VAAPIEncodeContext common; |
| 71 | + FFHWBaseEncodeH264 units; | |
| 70 | 72 | |
| 71 | 73 | // User options. |
| 72 | 74 | int qp; |
| @@ -85,18 +87,13 @@ typedef struct VAAPIEncodeH264Context { · 12 unmodified lines | ||
| 85 | 87 | int fixed_qp_p; |
| 86 | 88 | int fixed_qp_b; |
| 87 | 89 | |
| 88 | − int dpb_frames; | |
| 89 | − | |
| 90 | 90 | // Writer structures. |
| 91 | 91 | CodedBitstreamContext *cbc; |
| 92 | 92 | CodedBitstreamFragment current_access_unit; |
| 93 | 93 | |
| 94 | 94 | H264RawAUD raw_aud; |
| 95 | − H264RawSPS raw_sps; | |
| 96 | − H264RawPPS raw_pps; | |
| 97 | 95 | H264RawSlice raw_slice; |
| 98 | 96 | |
| 99 | − H264RawSEIBufferingPeriod sei_buffering_period; | |
| 100 | 97 | H264RawSEIPicTiming sei_pic_timing; |
| 101 | 98 | H264RawSEIRecoveryPoint sei_recovery_point; |
| 102 | 99 | SEIRawUserDataUnregistered sei_identifier; |
| @@ -168,11 +165,11 @@ static int vaapi_encode_h264_write_sequence_header(AVCodecContext *avctx, · 65 unmodified lines | ||
| 168 | 165 | priv->aud_needed = 0; |
| 169 | 166 | } |
| 170 | 167 | |
| 171 | − err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_sps); | |
| 168 | + err = vaapi_encode_h264_add_nal(avctx, au, &priv->units.raw_sps); | |
| 172 | 169 | if (err < 0) |
| 173 | 170 | goto fail; |
| 174 | 171 | |
| 175 | − err = vaapi_encode_h264_add_nal(avctx, au, &priv->raw_pps); | |
| 172 | + err = vaapi_encode_h264_add_nal(avctx, au, &priv->units.raw_pps); | |
| 176 | 173 | if (err < 0) |
| 177 | 174 | goto fail; |
| 178 | 175 | |
| @@ -236,7 +233,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, · 57 unmodified lines | ||
| 236 | 233 | if (base->type == FF_HW_PICTURE_TYPE_IDR) { |
| 237 | 234 | err = ff_cbs_sei_add_message(priv->cbc, au, 1, |
| 238 | 235 | SEI_TYPE_BUFFERING_PERIOD, |
| 239 | − &priv->sei_buffering_period, NULL); | |
| 236 | + &priv->units.sei_buffering_period, NULL); | |
| 240 | 237 | if (err < 0) |
| 241 | 238 | goto fail; |
| 242 | 239 | } |
| @@ -298,240 +295,26 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 55 unmodified lines | ||
| 298 | 295 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 299 | 296 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 300 | 297 | VAAPIEncodeH264Context *priv = avctx->priv_data; |
| 301 | − H264RawSPS *sps = &priv->raw_sps; | |
| 302 | − H264RawPPS *pps = &priv->raw_pps; | |
| 298 | + H264RawSPS *sps = &priv->units.raw_sps; | |
| 299 | + H264RawPPS *pps = &priv->units.raw_pps; | |
| 303 | 300 | VAEncSequenceParameterBufferH264 *vseq = ctx->codec_sequence_params; |
| 304 | 301 | VAEncPictureParameterBufferH264 *vpic = ctx->codec_picture_params; |
| 305 | − const AVPixFmtDescriptor *desc; | |
| 306 | − int bit_depth; | |
| 307 | − | |
| 308 | − memset(sps, 0, sizeof(*sps)); | |
| 309 | − memset(pps, 0, sizeof(*pps)); | |
| 310 | − | |
| 311 | − desc = av_pix_fmt_desc_get(base_ctx->input_frames->sw_format); | |
| 312 | − av_assert0(desc); | |
| 313 | − if (desc->nb_components == 1 || desc->log2_chroma_w != 1 || desc->log2_chroma_h != 1) { | |
| 314 | − av_log(avctx, AV_LOG_ERROR, "Chroma format of input pixel format " | |
| 315 | − "%s is not supported.\n", desc->name); | |
| 316 | − return AVERROR(EINVAL); | |
| 317 | − } | |
| 318 | − bit_depth = desc->comp[0].depth; | |
| 319 | − | |
| 320 | − sps->nal_unit_header.nal_ref_idc = 3; | |
| 321 | − sps->nal_unit_header.nal_unit_type = H264_NAL_SPS; | |
| 322 | − | |
| 323 | − sps->profile_idc = avctx->profile & 0xff; | |
| 324 | − | |
| 325 | − if (avctx->profile == AV_PROFILE_H264_CONSTRAINED_BASELINE || | |
| 326 | − avctx->profile == AV_PROFILE_H264_MAIN) | |
| 327 | − sps->constraint_set1_flag = 1; | |
| 328 | − | |
| 329 | − if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) | |
| 330 | − sps->constraint_set3_flag = base_ctx->gop_size == 1; | |
| 331 | − | |
| 332 | − if (avctx->profile == AV_PROFILE_H264_MAIN || | |
| 333 | − avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) { | |
| 334 | − sps->constraint_set4_flag = 1; | |
| 335 | − sps->constraint_set5_flag = base_ctx->b_per_p == 0; | |
| 336 | − } | |
| 337 | − | |
| 338 | − if (base_ctx->gop_size == 1) | |
| 339 | − priv->dpb_frames = 0; | |
| 340 | − else | |
| 341 | − priv->dpb_frames = 1 + base_ctx->max_b_depth; | |
| 342 | − | |
| 343 | − if (avctx->level != AV_LEVEL_UNKNOWN) { | |
| 344 | − sps->level_idc = avctx->level; | |
| 345 | − } else { | |
| 346 | − const H264LevelDescriptor *level; | |
| 347 | − int framerate; | |
| 348 | − | |
| 349 | − if (avctx->framerate.num > 0 && avctx->framerate.den > 0) | |
| 350 | − framerate = avctx->framerate.num / avctx->framerate.den; | |
| 351 | − else | |
| 352 | − framerate = 0; | |
| 353 | − | |
| 354 | − level = ff_h264_guess_level(sps->profile_idc, | |
| 355 | − avctx->bit_rate, | |
| 356 | − framerate, | |
| 357 | − priv->mb_width * 16, | |
| 358 | − priv->mb_height * 16, | |
| 359 | − priv->dpb_frames); | |
| 360 | − if (level) { | |
| 361 | − av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); | |
| 362 | − if (level->constraint_set3_flag) | |
| 363 | − sps->constraint_set3_flag = 1; | |
| 364 | − sps->level_idc = level->level_idc; | |
| 365 | − } else { | |
| 366 | − av_log(avctx, AV_LOG_WARNING, "Stream will not conform " | |
| 367 | − "to any level: using level 6.2.\n"); | |
| 368 | − sps->level_idc = 62; | |
| 369 | − } | |
| 370 | − } | |
| 371 | − | |
| 372 | − sps->seq_parameter_set_id = 0; | |
| 373 | − sps->chroma_format_idc = 1; | |
| 374 | − sps->bit_depth_luma_minus8 = bit_depth - 8; | |
| 375 | − sps->bit_depth_chroma_minus8 = bit_depth - 8; | |
| 376 | − | |
| 377 | − sps->log2_max_frame_num_minus4 = 4; | |
| 378 | − sps->pic_order_cnt_type = base_ctx->max_b_depth ? 0 : 2; | |
| 379 | − if (sps->pic_order_cnt_type == 0) { | |
| 380 | − sps->log2_max_pic_order_cnt_lsb_minus4 = 4; | |
| 381 | − } | |
| 382 | − | |
| 383 | − sps->max_num_ref_frames = priv->dpb_frames; | |
| 384 | − | |
| 385 | − sps->pic_width_in_mbs_minus1 = priv->mb_width - 1; | |
| 386 | − sps->pic_height_in_map_units_minus1 = priv->mb_height - 1; | |
| 387 | − | |
| 388 | − sps->frame_mbs_only_flag = 1; | |
| 389 | − sps->direct_8x8_inference_flag = 1; | |
| 390 | − | |
| 391 | − if (avctx->width != 16 * priv->mb_width || | |
| 392 | − avctx->height != 16 * priv->mb_height) { | |
| 393 | − sps->frame_cropping_flag = 1; | |
| 394 | − | |
| 395 | − sps->frame_crop_left_offset = 0; | |
| 396 | − sps->frame_crop_right_offset = | |
| 397 | − (16 * priv->mb_width - avctx->width) / 2; | |
| 398 | − sps->frame_crop_top_offset = 0; | |
| 399 | − sps->frame_crop_bottom_offset = | |
| 400 | − (16 * priv->mb_height - avctx->height) / 2; | |
| 401 | − } else { | |
| 402 | − sps->frame_cropping_flag = 0; | |
| 403 | − } | |
| 404 | − | |
| 405 | − sps->vui_parameters_present_flag = 1; | |
| 406 | − | |
| 407 | − if (avctx->sample_aspect_ratio.num != 0 && | |
| 408 | − avctx->sample_aspect_ratio.den != 0) { | |
| 409 | − int num, den, i; | |
| 410 | − av_reduce(&num, &den, avctx->sample_aspect_ratio.num, | |
| 411 | − avctx->sample_aspect_ratio.den, 65535); | |
| 412 | − for (i = 0; i < FF_ARRAY_ELEMS(ff_h2645_pixel_aspect); i++) { | |
| 413 | − if (num == ff_h2645_pixel_aspect[i].num && | |
| 414 | − den == ff_h2645_pixel_aspect[i].den) { | |
| 415 | − sps->vui.aspect_ratio_idc = i; | |
| 416 | − break; | |
| 417 | − } | |
| 418 | − } | |
| 419 | − if (i >= FF_ARRAY_ELEMS(ff_h2645_pixel_aspect)) { | |
| 420 | − sps->vui.aspect_ratio_idc = 255; | |
| 421 | − sps->vui.sar_width = num; | |
| 422 | − sps->vui.sar_height = den; | |
| 423 | − } | |
| 424 | − sps->vui.aspect_ratio_info_present_flag = 1; | |
| 425 | − } | |
| 426 | − | |
| 427 | − // Unspecified video format, from table E-2. | |
| 428 | − sps->vui.video_format = 5; | |
| 429 | − sps->vui.video_full_range_flag = | |
| 430 | − avctx->color_range == AVCOL_RANGE_JPEG; | |
| 431 | − sps->vui.colour_primaries = avctx->color_primaries; | |
| 432 | − sps->vui.transfer_characteristics = avctx->color_trc; | |
| 433 | − sps->vui.matrix_coefficients = avctx->colorspace; | |
| 434 | − if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED || | |
| 435 | − avctx->color_trc != AVCOL_TRC_UNSPECIFIED || | |
| 436 | − avctx->colorspace != AVCOL_SPC_UNSPECIFIED) | |
| 437 | − sps->vui.colour_description_present_flag = 1; | |
| 438 | − if (avctx->color_range != AVCOL_RANGE_UNSPECIFIED || | |
| 439 | − sps->vui.colour_description_present_flag) | |
| 440 | − sps->vui.video_signal_type_present_flag = 1; | |
| 441 | − | |
| 442 | − if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) { | |
| 443 | − sps->vui.chroma_loc_info_present_flag = 1; | |
| 444 | − sps->vui.chroma_sample_loc_type_top_field = | |
| 445 | − sps->vui.chroma_sample_loc_type_bottom_field = | |
| 446 | − avctx->chroma_sample_location - 1; | |
| 447 | − } | |
| 448 | − | |
| 449 | − sps->vui.timing_info_present_flag = 1; | |
| 450 | − if (avctx->framerate.num > 0 && avctx->framerate.den > 0) { | |
| 451 | − sps->vui.num_units_in_tick = avctx->framerate.den; | |
| 452 | − sps->vui.time_scale = 2 * avctx->framerate.num; | |
| 453 | − sps->vui.fixed_frame_rate_flag = 1; | |
| 454 | − } else { | |
| 455 | − sps->vui.num_units_in_tick = avctx->time_base.num; | |
| 456 | − sps->vui.time_scale = 2 * avctx->time_base.den; | |
| 457 | − sps->vui.fixed_frame_rate_flag = 0; | |
| 458 | − } | |
| 459 | − | |
| 460 | − if (priv->sei & SEI_TIMING) { | |
| 461 | − H264RawHRD *hrd = &sps->vui.nal_hrd_parameters; | |
| 462 | − H264RawSEIBufferingPeriod *bp = &priv->sei_buffering_period; | |
| 463 | − | |
| 464 | − sps->vui.nal_hrd_parameters_present_flag = 1; | |
| 465 | − | |
| 466 | − hrd->cpb_cnt_minus1 = 0; | |
| 467 | − | |
| 468 | − // Try to scale these to a sensible range so that the | |
| 469 | − // golomb encode of the value is not overlong. | |
| 470 | − hrd->bit_rate_scale = | |
| 471 | − av_clip_uintp2(av_log2(ctx->va_bit_rate) - 15 - 6, 4); | |
| 472 | − hrd->bit_rate_value_minus1[0] = | |
| 473 | − (ctx->va_bit_rate >> hrd->bit_rate_scale + 6) - 1; | |
| 474 | − | |
| 475 | − hrd->cpb_size_scale = | |
| 476 | − av_clip_uintp2(av_log2(ctx->hrd_params.buffer_size) - 15 - 4, 4); | |
| 477 | − hrd->cpb_size_value_minus1[0] = | |
| 478 | − (ctx->hrd_params.buffer_size >> hrd->cpb_size_scale + 4) - 1; | |
| 479 | − | |
| 480 | − // CBR mode as defined for the HRD cannot be achieved without filler | |
| 481 | − // data, so this flag cannot be set even with VAAPI CBR modes. | |
| 482 | − hrd->cbr_flag[0] = 0; | |
| 483 | 302 | |
| 484 | − hrd->initial_cpb_removal_delay_length_minus1 = 23; | |
| 485 | − hrd->cpb_removal_delay_length_minus1 = 23; | |
| 486 | − hrd->dpb_output_delay_length_minus1 = 7; | |
| 487 | − hrd->time_offset_length = 0; | |
| 488 | − | |
| 489 | − bp->seq_parameter_set_id = sps->seq_parameter_set_id; | |
| 490 | − | |
| 491 | − // This calculation can easily overflow 32 bits. | |
| 492 | − bp->nal.initial_cpb_removal_delay[0] = 90000 * | |
| 493 | − (uint64_t)ctx->hrd_params.initial_buffer_fullness / | |
| 494 | − ctx->hrd_params.buffer_size; | |
| 495 | − bp->nal.initial_cpb_removal_delay_offset[0] = 0; | |
| 496 | − } else { | |
| 497 | − sps->vui.nal_hrd_parameters_present_flag = 0; | |
| 498 | − sps->vui.low_delay_hrd_flag = 1 - sps->vui.fixed_frame_rate_flag; | |
| 499 | − } | |
| 500 | − | |
| 501 | − sps->vui.bitstream_restriction_flag = 1; | |
| 502 | − sps->vui.motion_vectors_over_pic_boundaries_flag = 1; | |
| 503 | − sps->vui.log2_max_mv_length_horizontal = 15; | |
| 504 | − sps->vui.log2_max_mv_length_vertical = 15; | |
| 505 | − sps->vui.max_num_reorder_frames = base_ctx->max_b_depth; | |
| 506 | − sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1; | |
| 507 | − | |
| 508 | − pps->nal_unit_header.nal_ref_idc = 3; | |
| 509 | − pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; | |
| 510 | − | |
| 511 | − pps->pic_parameter_set_id = 0; | |
| 512 | − pps->seq_parameter_set_id = 0; | |
| 513 | − | |
| 514 | − pps->entropy_coding_mode_flag = | |
| 515 | − !(sps->profile_idc == AV_PROFILE_H264_BASELINE || | |
| 516 | − sps->profile_idc == AV_PROFILE_H264_EXTENDED || | |
| 517 | − sps->profile_idc == AV_PROFILE_H264_CAVLC_444); | |
| 518 | − if (!priv->coder && pps->entropy_coding_mode_flag) | |
| 519 | − pps->entropy_coding_mode_flag = 0; | |
| 520 | − | |
| 521 | − pps->num_ref_idx_l0_default_active_minus1 = 0; | |
| 522 | − pps->num_ref_idx_l1_default_active_minus1 = 0; | |
| 523 | − | |
| 524 | − pps->pic_init_qp_minus26 = priv->fixed_qp_idr - 26; | |
| 525 | − | |
| 526 | − if (sps->profile_idc == AV_PROFILE_H264_BASELINE || | |
| 527 | − sps->profile_idc == AV_PROFILE_H264_EXTENDED || | |
| 528 | − sps->profile_idc == AV_PROFILE_H264_MAIN) { | |
| 529 | − pps->more_rbsp_data = 0; | |
| 530 | − } else { | |
| 531 | − pps->more_rbsp_data = 1; | |
| 303 | + FFHWBaseEncodeH264Opts unit_opts = { | |
| 304 | + .flags = (priv->sei & SEI_TIMING) ? FF_HW_H264_SEI_TIMING : 0, | |
| 305 | + .mb_width = priv->mb_width, | |
| 306 | + .mb_height = priv->mb_height, | |
| 307 | + .cabac = priv->coder, | |
| 308 | + .hrd_buffer_size = ctx->hrd_params.buffer_size, | |
| 309 | + .fixed_qp_idr = priv->fixed_qp_idr, | |
| 310 | + .initial_buffer_fullness = ctx->hrd_params.initial_buffer_fullness, | |
| 311 | + .bit_rate = ctx->va_bit_rate, | |
| 312 | + }; | |
| 532 | 313 | |
| 533 | − pps->transform_8x8_mode_flag = 1; | |
| 534 | − } | |
| 314 | + int err = ff_hw_base_encode_init_params_h264(base_ctx, avctx, | |
| 315 | + &priv->units, &unit_opts); | |
| 316 | + if (err < 0) | |
| 317 | + return err; | |
| 535 | 318 | |
| 536 | 319 | *vseq = (VAEncSequenceParameterBufferH264) { |
| 537 | 320 | .seq_parameter_set_id = sps->seq_parameter_set_id, |
| @@ -660,7 +443,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 122 unmodified lines | ||
| 660 | 443 | } |
| 661 | 444 | } |
| 662 | 445 | hpic->pic_order_cnt = pic->display_order - hpic->last_idr_frame; |
| 663 | − if (priv->raw_sps.pic_order_cnt_type == 2) { | |
| 446 | + if (priv->units.raw_sps.pic_order_cnt_type == 2) { | |
| 664 | 447 | hpic->pic_order_cnt *= 2; |
| 665 | 448 | } |
| 666 | 449 | |
| @@ -870,8 +653,8 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 203 unmodified lines | ||
| 870 | 653 | VAAPIEncodePicture *vaapi_pic = pic->priv; |
| 871 | 654 | VAAPIEncodeH264Picture *hpic = pic->codec_priv; |
| 872 | 655 | FFHWBaseEncodePicture *prev = pic->prev; |
| 873 | − H264RawSPS *sps = &priv->raw_sps; | |
| 874 | − H264RawPPS *pps = &priv->raw_pps; | |
| 656 | + H264RawSPS *sps = &priv->units.raw_sps; | |
| 657 | + H264RawPPS *pps = &priv->units.raw_pps; | |
| 875 | 658 | H264RawSliceHeader *sh = &priv->raw_slice.header; |
| 876 | 659 | VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params; |
| 877 | 660 | VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; |
| @@ -923,7 +706,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 45 unmodified lines | ||
| 923 | 706 | ++keep; |
| 924 | 707 | } |
| 925 | 708 | } |
| 926 | − av_assert0(keep <= priv->dpb_frames); | |
| 709 | + av_assert0(keep <= priv->units.dpb_frames); | |
| 927 | 710 | |
| 928 | 711 | if (discard == 0) { |
| 929 | 712 | sh->adaptive_ref_pic_marking_mode_flag = 0; |