Move receive_packet function to base. This requires adding *alloc, *issue, *output, *free as hardware callbacks. HWBaseEncodePicture is introduced as the base layer structure. The related parameters in VAAPIEncodeContext are also extracted to HWBaseEncodeContext. Then DPB management logic can be fully extracted to base layer as-is.
Unified · Split
| @@ -165,7 +165,7 @@ OBJS-$(CONFIG_STARTCODE) += startcode.o · 164 unmodified lines | |||
| 165 | OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o | 165 | OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o |
| 166 | OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o | 166 | OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o |
| 167 | OBJS-$(CONFIG_TPELDSP) += tpeldsp.o | 167 | OBJS-$(CONFIG_TPELDSP) += tpeldsp.o |
| 168 | OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o | 168 | OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o |
| 169 | OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o | 169 | OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o |
| 170 | OBJS-$(CONFIG_VC1DSP) += vc1dsp.o | 170 | OBJS-$(CONFIG_VC1DSP) += vc1dsp.o |
| 171 | OBJS-$(CONFIG_VIDEODSP) += videodsp.o | 171 | OBJS-$(CONFIG_VIDEODSP) += videodsp.o |
| @@ -0,0 +1,594 @@ | |||
| 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 "libavutil/avassert.h" | ||
| 20 | #include "libavutil/common.h" | ||
| 21 | #include "libavutil/internal.h" | ||
| 22 | #include "libavutil/log.h" | ||
| 23 | #include "libavutil/mem.h" | ||
| 24 | #include "libavutil/pixdesc.h" | ||
| 25 | |||
| 26 | #include "encode.h" | ||
| 27 | #include "avcodec.h" | ||
| 28 | #include "hw_base_encode.h" | ||
| 29 | |||
| 30 | static void hw_base_encode_add_ref(FFHWBaseEncodePicture *pic, | ||
| 31 | FFHWBaseEncodePicture *target, | ||
| 32 | int is_ref, int in_dpb, int prev) | ||
| 33 | { | ||
| 34 | int refs = 0; | ||
| 35 | |||
| 36 | if (is_ref) { | ||
| 37 | av_assert0(pic != target); | ||
| 38 | av_assert0(pic->nb_refs[0] < MAX_PICTURE_REFERENCES && | ||
| 39 | pic->nb_refs[1] < MAX_PICTURE_REFERENCES); | ||
| 40 | if (target->display_order < pic->display_order) | ||
| 41 | pic->refs[0][pic->nb_refs[0]++] = target; | ||
| 42 | else | ||
| 43 | pic->refs[1][pic->nb_refs[1]++] = target; | ||
| 44 | ++refs; | ||
| 45 | } | ||
| 46 | |||
| 47 | if (in_dpb) { | ||
| 48 | av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE); | ||
| 49 | pic->dpb[pic->nb_dpb_pics++] = target; | ||
| 50 | ++refs; | ||
| 51 | } | ||
| 52 | |||
| 53 | if (prev) { | ||
| 54 | av_assert0(!pic->prev); | ||
| 55 | pic->prev = target; | ||
| 56 | ++refs; | ||
| 57 | } | ||
| 58 | |||
| 59 | target->ref_count[0] += refs; | ||
| 60 | target->ref_count[1] += refs; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void hw_base_encode_remove_refs(FFHWBaseEncodePicture *pic, int level) | ||
| 64 | { | ||
| 65 | int i; | ||
| 66 | |||
| 67 | if (pic->ref_removed[level]) | ||
| 68 | return; | ||
| 69 | |||
| 70 | for (i = 0; i < pic->nb_refs[0]; i++) { | ||
| 71 | av_assert0(pic->refs[0][i]); | ||
| 72 | --pic->refs[0][i]->ref_count[level]; | ||
| 73 | av_assert0(pic->refs[0][i]->ref_count[level] >= 0); | ||
| 74 | } | ||
| 75 | |||
| 76 | for (i = 0; i < pic->nb_refs[1]; i++) { | ||
| 77 | av_assert0(pic->refs[1][i]); | ||
| 78 | --pic->refs[1][i]->ref_count[level]; | ||
| 79 | av_assert0(pic->refs[1][i]->ref_count[level] >= 0); | ||
| 80 | } | ||
| 81 | |||
| 82 | for (i = 0; i < pic->nb_dpb_pics; i++) { | ||
| 83 | av_assert0(pic->dpb[i]); | ||
| 84 | --pic->dpb[i]->ref_count[level]; | ||
| 85 | av_assert0(pic->dpb[i]->ref_count[level] >= 0); | ||
| 86 | } | ||
| 87 | |||
| 88 | av_assert0(pic->prev || pic->type == FF_HW_PICTURE_TYPE_IDR); | ||
| 89 | if (pic->prev) { | ||
| 90 | --pic->prev->ref_count[level]; | ||
| 91 | av_assert0(pic->prev->ref_count[level] >= 0); | ||
| 92 | } | ||
| 93 | |||
| 94 | pic->ref_removed[level] = 1; | ||
| 95 | } | ||
| 96 | |||
| 97 | static void hw_base_encode_set_b_pictures(AVCodecContext *avctx, | ||
| 98 | FFHWBaseEncodePicture *start, | ||
| 99 | FFHWBaseEncodePicture *end, | ||
| 100 | FFHWBaseEncodePicture *prev, | ||
| 101 | int current_depth, | ||
| 102 | FFHWBaseEncodePicture **last) | ||
| 103 | { | ||
| 104 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 105 | FFHWBaseEncodePicture *pic, *next, *ref; | ||
| 106 | int i, len; | ||
| 107 | |||
| 108 | av_assert0(start && end && start != end && start->next != end); | ||
| 109 | |||
| 110 | // If we are at the maximum depth then encode all pictures as | ||
| 111 | // non-referenced B-pictures. Also do this if there is exactly one | ||
| 112 | // picture left, since there will be nothing to reference it. | ||
| 113 | if (current_depth == ctx->max_b_depth || start->next->next == end) { | ||
| 114 | for (pic = start->next; pic; pic = pic->next) { | ||
| 115 | if (pic == end) | ||
| 116 | break; | ||
| 117 | pic->type = FF_HW_PICTURE_TYPE_B; | ||
| 118 | pic->b_depth = current_depth; | ||
| 119 | |||
| 120 | hw_base_encode_add_ref(pic, start, 1, 1, 0); | ||
| 121 | hw_base_encode_add_ref(pic, end, 1, 1, 0); | ||
| 122 | hw_base_encode_add_ref(pic, prev, 0, 0, 1); | ||
| 123 | |||
| 124 | for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) | ||
| 125 | hw_base_encode_add_ref(pic, ref, 0, 1, 0); | ||
| 126 | } | ||
| 127 | *last = prev; | ||
| 128 | |||
| 129 | } else { | ||
| 130 | // Split the current list at the midpoint with a referenced | ||
| 131 | // B-picture, then descend into each side separately. | ||
| 132 | len = 0; | ||
| 133 | for (pic = start->next; pic != end; pic = pic->next) | ||
| 134 | ++len; | ||
| 135 | for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++); | ||
| 136 | |||
| 137 | pic->type = FF_HW_PICTURE_TYPE_B; | ||
| 138 | pic->b_depth = current_depth; | ||
| 139 | |||
| 140 | pic->is_reference = 1; | ||
| 141 | |||
| 142 | hw_base_encode_add_ref(pic, pic, 0, 1, 0); | ||
| 143 | hw_base_encode_add_ref(pic, start, 1, 1, 0); | ||
| 144 | hw_base_encode_add_ref(pic, end, 1, 1, 0); | ||
| 145 | hw_base_encode_add_ref(pic, prev, 0, 0, 1); | ||
| 146 | |||
| 147 | for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) | ||
| 148 | hw_base_encode_add_ref(pic, ref, 0, 1, 0); | ||
| 149 | |||
| 150 | if (i > 1) | ||
| 151 | hw_base_encode_set_b_pictures(avctx, start, pic, pic, | ||
| 152 | current_depth + 1, &next); | ||
| 153 | else | ||
| 154 | next = pic; | ||
| 155 | |||
| 156 | hw_base_encode_set_b_pictures(avctx, pic, end, next, | ||
| 157 | current_depth + 1, last); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | static void hw_base_encode_add_next_prev(AVCodecContext *avctx, | ||
| 162 | FFHWBaseEncodePicture *pic) | ||
| 163 | { | ||
| 164 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 165 | int i; | ||
| 166 | |||
| 167 | if (!pic) | ||
| 168 | return; | ||
| 169 | |||
| 170 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | ||
| 171 | for (i = 0; i < ctx->nb_next_prev; i++) { | ||
| 172 | --ctx->next_prev[i]->ref_count[0]; | ||
| 173 | ctx->next_prev[i] = NULL; | ||
| 174 | } | ||
| 175 | ctx->next_prev[0] = pic; | ||
| 176 | ++pic->ref_count[0]; | ||
| 177 | ctx->nb_next_prev = 1; | ||
| 178 | |||
| 179 | return; | ||
| 180 | } | ||
| 181 | |||
| 182 | if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) { | ||
| 183 | ctx->next_prev[ctx->nb_next_prev++] = pic; | ||
| 184 | ++pic->ref_count[0]; | ||
| 185 | } else { | ||
| 186 | --ctx->next_prev[0]->ref_count[0]; | ||
| 187 | for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++) | ||
| 188 | ctx->next_prev[i] = ctx->next_prev[i + 1]; | ||
| 189 | ctx->next_prev[i] = pic; | ||
| 190 | ++pic->ref_count[0]; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | static int hw_base_encode_pick_next(AVCodecContext *avctx, | ||
| 195 | FFHWBaseEncodePicture **pic_out) | ||
| 196 | { | ||
| 197 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 198 | FFHWBaseEncodePicture *pic = NULL, *prev = NULL, *next, *start; | ||
| 199 | int i, b_counter, closed_gop_end; | ||
| 200 | |||
| 201 | // If there are any B-frames already queued, the next one to encode | ||
| 202 | // is the earliest not-yet-issued frame for which all references are | ||
| 203 | // available. | ||
| 204 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 205 | if (pic->encode_issued) | ||
| 206 | continue; | ||
| 207 | if (pic->type != FF_HW_PICTURE_TYPE_B) | ||
| 208 | continue; | ||
| 209 | for (i = 0; i < pic->nb_refs[0]; i++) { | ||
| 210 | if (!pic->refs[0][i]->encode_issued) | ||
| 211 | break; | ||
| 212 | } | ||
| 213 | if (i != pic->nb_refs[0]) | ||
| 214 | continue; | ||
| 215 | |||
| 216 | for (i = 0; i < pic->nb_refs[1]; i++) { | ||
| 217 | if (!pic->refs[1][i]->encode_issued) | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | if (i == pic->nb_refs[1]) | ||
| 221 | break; | ||
| 222 | } | ||
| 223 | |||
| 224 | if (pic) { | ||
| 225 | av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to " | ||
| 226 | "encode next.\n", pic->b_depth); | ||
| 227 | *pic_out = pic; | ||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | // Find the B-per-Pth available picture to become the next picture | ||
| 232 | // on the top layer. | ||
| 233 | start = NULL; | ||
| 234 | b_counter = 0; | ||
| 235 | closed_gop_end = ctx->closed_gop || | ||
| 236 | ctx->idr_counter == ctx->gop_per_idr; | ||
| 237 | for (pic = ctx->pic_start; pic; pic = next) { | ||
| 238 | next = pic->next; | ||
| 239 | if (pic->encode_issued) { | ||
| 240 | start = pic; | ||
| 241 | continue; | ||
| 242 | } | ||
| 243 | // If the next available picture is force-IDR, encode it to start | ||
| 244 | // a new GOP immediately. | ||
| 245 | if (pic->force_idr) | ||
| 246 | break; | ||
| 247 | if (b_counter == ctx->b_per_p) | ||
| 248 | break; | ||
| 249 | // If this picture ends a closed GOP or starts a new GOP then it | ||
| 250 | // needs to be in the top layer. | ||
| 251 | if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size) | ||
| 252 | break; | ||
| 253 | // If the picture after this one is force-IDR, we need to encode | ||
| 254 | // this one in the top layer. | ||
| 255 | if (next && next->force_idr) | ||
| 256 | break; | ||
| 257 | ++b_counter; | ||
| 258 | } | ||
| 259 | |||
| 260 | // At the end of the stream the last picture must be in the top layer. | ||
| 261 | if (!pic && ctx->end_of_stream) { | ||
| 262 | --b_counter; | ||
| 263 | pic = ctx->pic_end; | ||
| 264 | if (pic->encode_complete) | ||
| 265 | return AVERROR_EOF; | ||
| 266 | else if (pic->encode_issued) | ||
| 267 | return AVERROR(EAGAIN); | ||
| 268 | } | ||
| 269 | |||
| 270 | if (!pic) { | ||
| 271 | av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - " | ||
| 272 | "need more input for reference pictures.\n"); | ||
| 273 | return AVERROR(EAGAIN); | ||
| 274 | } | ||
| 275 | if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) { | ||
| 276 | av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - " | ||
| 277 | "need more input for timestamps.\n"); | ||
| 278 | return AVERROR(EAGAIN); | ||
| 279 | } | ||
| 280 | |||
| 281 | if (pic->force_idr) { | ||
| 282 | av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to " | ||
| 283 | "encode next.\n"); | ||
| 284 | pic->type = FF_HW_PICTURE_TYPE_IDR; | ||
| 285 | ctx->idr_counter = 1; | ||
| 286 | ctx->gop_counter = 1; | ||
| 287 | |||
| 288 | } else if (ctx->gop_counter + b_counter >= ctx->gop_size) { | ||
| 289 | if (ctx->idr_counter == ctx->gop_per_idr) { | ||
| 290 | av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to " | ||
| 291 | "encode next.\n"); | ||
| 292 | pic->type = FF_HW_PICTURE_TYPE_IDR; | ||
| 293 | ctx->idr_counter = 1; | ||
| 294 | } else { | ||
| 295 | av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to " | ||
| 296 | "encode next.\n"); | ||
| 297 | pic->type = FF_HW_PICTURE_TYPE_I; | ||
| 298 | ++ctx->idr_counter; | ||
| 299 | } | ||
| 300 | ctx->gop_counter = 1; | ||
| 301 | |||
| 302 | } else { | ||
| 303 | if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) { | ||
| 304 | av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to " | ||
| 305 | "encode next.\n"); | ||
| 306 | } else { | ||
| 307 | av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to " | ||
| 308 | "encode next.\n"); | ||
| 309 | } | ||
| 310 | pic->type = FF_HW_PICTURE_TYPE_P; | ||
| 311 | av_assert0(start); | ||
| 312 | ctx->gop_counter += 1 + b_counter; | ||
| 313 | } | ||
| 314 | pic->is_reference = 1; | ||
| 315 | *pic_out = pic; | ||
| 316 | |||
| 317 | hw_base_encode_add_ref(pic, pic, 0, 1, 0); | ||
| 318 | if (pic->type != FF_HW_PICTURE_TYPE_IDR) { | ||
| 319 | // TODO: apply both previous and forward multi reference for all vaapi encoders. | ||
| 320 | // And L0/L1 reference frame number can be set dynamically through query | ||
| 321 | // VAConfigAttribEncMaxRefFrames attribute. | ||
| 322 | if (avctx->codec_id == AV_CODEC_ID_AV1) { | ||
| 323 | for (i = 0; i < ctx->nb_next_prev; i++) | ||
| 324 | hw_base_encode_add_ref(pic, ctx->next_prev[i], | ||
| 325 | pic->type == FF_HW_PICTURE_TYPE_P, | ||
| 326 | b_counter > 0, 0); | ||
| 327 | } else | ||
| 328 | hw_base_encode_add_ref(pic, start, | ||
| 329 | pic->type == FF_HW_PICTURE_TYPE_P, | ||
| 330 | b_counter > 0, 0); | ||
| 331 | |||
| 332 | hw_base_encode_add_ref(pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1); | ||
| 333 | } | ||
| 334 | |||
| 335 | if (b_counter > 0) { | ||
| 336 | hw_base_encode_set_b_pictures(avctx, start, pic, pic, 1, | ||
| 337 | &prev); | ||
| 338 | } else { | ||
| 339 | prev = pic; | ||
| 340 | } | ||
| 341 | hw_base_encode_add_next_prev(avctx, prev); | ||
| 342 | |||
| 343 | return 0; | ||
| 344 | } | ||
| 345 | |||
| 346 | static int hw_base_encode_clear_old(AVCodecContext *avctx) | ||
| 347 | { | ||
| 348 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 349 | FFHWBaseEncodePicture *pic, *prev, *next; | ||
| 350 | |||
| 351 | av_assert0(ctx->pic_start); | ||
| 352 | |||
| 353 | // Remove direct references once each picture is complete. | ||
| 354 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 355 | if (pic->encode_complete && pic->next) | ||
| 356 | hw_base_encode_remove_refs(pic, 0); | ||
| 357 | } | ||
| 358 | |||
| 359 | // Remove indirect references once a picture has no direct references. | ||
| 360 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 361 | if (pic->encode_complete && pic->ref_count[0] == 0) | ||
| 362 | hw_base_encode_remove_refs(pic, 1); | ||
| 363 | } | ||
| 364 | |||
| 365 | // Clear out all complete pictures with no remaining references. | ||
| 366 | prev = NULL; | ||
| 367 | for (pic = ctx->pic_start; pic; pic = next) { | ||
| 368 | next = pic->next; | ||
| 369 | if (pic->encode_complete && pic->ref_count[1] == 0) { | ||
| 370 | av_assert0(pic->ref_removed[0] && pic->ref_removed[1]); | ||
| 371 | if (prev) | ||
| 372 | prev->next = next; | ||
| 373 | else | ||
| 374 | ctx->pic_start = next; | ||
| 375 | ctx->op->free(avctx, pic); | ||
| 376 | } else { | ||
| 377 | prev = pic; | ||
| 378 | } | ||
| 379 | } | ||
| 380 | |||
| 381 | return 0; | ||
| 382 | } | ||
| 383 | |||
| 384 | static int hw_base_encode_check_frame(AVCodecContext *avctx, | ||
| 385 | const AVFrame *frame) | ||
| 386 | { | ||
| 387 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 388 | |||
| 389 | if ((frame->crop_top || frame->crop_bottom || | ||
| 390 | frame->crop_left || frame->crop_right) && !ctx->crop_warned) { | ||
| 391 | av_log(avctx, AV_LOG_WARNING, "Cropping information on input " | ||
| 392 | "frames ignored due to lack of API support.\n"); | ||
| 393 | ctx->crop_warned = 1; | ||
| 394 | } | ||
| 395 | |||
| 396 | if (!ctx->roi_allowed) { | ||
| 397 | AVFrameSideData *sd = | ||
| 398 | av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST); | ||
| 399 | |||
| 400 | if (sd && !ctx->roi_warned) { | ||
| 401 | av_log(avctx, AV_LOG_WARNING, "ROI side data on input " | ||
| 402 | "frames ignored due to lack of driver support.\n"); | ||
| 403 | ctx->roi_warned = 1; | ||
| 404 | } | ||
| 405 | } | ||
| 406 | |||
| 407 | return 0; | ||
| 408 | } | ||
| 409 | |||
| 410 | static int hw_base_encode_send_frame(AVCodecContext *avctx, AVFrame *frame) | ||
| 411 | { | ||
| 412 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 413 | FFHWBaseEncodePicture *pic; | ||
| 414 | int err; | ||
| 415 | |||
| 416 | if (frame) { | ||
| 417 | av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n", | ||
| 418 | frame->width, frame->height, frame->pts); | ||
| 419 | |||
| 420 | err = hw_base_encode_check_frame(avctx, frame); | ||
| 421 | if (err < 0) | ||
| 422 | return err; | ||
| 423 | |||
| 424 | pic = ctx->op->alloc(avctx, frame); | ||
| 425 | if (!pic) | ||
| 426 | return AVERROR(ENOMEM); | ||
| 427 | |||
| 428 | pic->input_image = av_frame_alloc(); | ||
| 429 | if (!pic->input_image) { | ||
| 430 | err = AVERROR(ENOMEM); | ||
| 431 | goto fail; | ||
| 432 | } | ||
| 433 | |||
| 434 | pic->recon_image = av_frame_alloc(); | ||
| 435 | if (!pic->recon_image) { | ||
| 436 | err = AVERROR(ENOMEM); | ||
| 437 | goto fail; | ||
| 438 | } | ||
| 439 | |||
| 440 | if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I) | ||
| 441 | pic->force_idr = 1; | ||
| 442 | |||
| 443 | pic->pts = frame->pts; | ||
| 444 | pic->duration = frame->duration; | ||
| 445 | |||
| 446 | if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { | ||
| 447 | err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref); | ||
| 448 | if (err < 0) | ||
| 449 | goto fail; | ||
| 450 | |||
| 451 | pic->opaque = frame->opaque; | ||
| 452 | } | ||
| 453 | |||
| 454 | av_frame_move_ref(pic->input_image, frame); | ||
| 455 | |||
| 456 | if (ctx->input_order == 0) | ||
| 457 | ctx->first_pts = pic->pts; | ||
| 458 | if (ctx->input_order == ctx->decode_delay) | ||
| 459 | ctx->dts_pts_diff = pic->pts - ctx->first_pts; | ||
| 460 | if (ctx->output_delay > 0) | ||
| 461 | ctx->ts_ring[ctx->input_order % | ||
| 462 | (3 * ctx->output_delay + ctx->async_depth)] = pic->pts; | ||
| 463 | |||
| 464 | pic->display_order = ctx->input_order; | ||
| 465 | ++ctx->input_order; | ||
| 466 | |||
| 467 | if (ctx->pic_start) { | ||
| 468 | ctx->pic_end->next = pic; | ||
| 469 | ctx->pic_end = pic; | ||
| 470 | } else { | ||
| 471 | ctx->pic_start = pic; | ||
| 472 | ctx->pic_end = pic; | ||
| 473 | } | ||
| 474 | |||
| 475 | } else { | ||
| 476 | ctx->end_of_stream = 1; | ||
| 477 | |||
| 478 | // Fix timestamps if we hit end-of-stream before the initial decode | ||
| 479 | // delay has elapsed. | ||
| 480 | if (ctx->input_order < ctx->decode_delay) | ||
| 481 | ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts; | ||
| 482 | } | ||
| 483 | |||
| 484 | return 0; | ||
| 485 | |||
| 486 | fail: | ||
| 487 | ctx->op->free(avctx, pic); | ||
| 488 | return err; | ||
| 489 | } | ||
| 490 | |||
| 491 | int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt) | ||
| 492 | { | ||
| 493 | FFHWBaseEncodeContext *ctx = avctx->priv_data; | ||
| 494 | FFHWBaseEncodePicture *pic = NULL; | ||
| 495 | AVFrame *frame = ctx->frame; | ||
| 496 | int err; | ||
| 497 | |||
| 498 | av_assert0(ctx->op && ctx->op->alloc && ctx->op->issue && | ||
| 499 | ctx->op->output && ctx->op->free); | ||
| 500 | |||
| 501 | start: | ||
| 502 | /** if no B frame before repeat P frame, sent repeat P frame out. */ | ||
| 503 | if (ctx->tail_pkt->size) { | ||
| 504 | for (FFHWBaseEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) { | ||
| 505 | if (tmp->type == FF_HW_PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts) | ||
| 506 | break; | ||
| 507 | else if (!tmp->next) { | ||
| 508 | av_packet_move_ref(pkt, ctx->tail_pkt); | ||
| 509 | goto end; | ||
| 510 | } | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 514 | err = ff_encode_get_frame(avctx, frame); | ||
| 515 | if (err < 0 && err != AVERROR_EOF) | ||
| 516 | return err; | ||
| 517 | |||
| 518 | if (err == AVERROR_EOF) | ||
| 519 | frame = NULL; | ||
| 520 | |||
| 521 | err = hw_base_encode_send_frame(avctx, frame); | ||
| 522 | if (err < 0) | ||
| 523 | return err; | ||
| 524 | |||
| 525 | if (!ctx->pic_start) { | ||
| 526 | if (ctx->end_of_stream) | ||
| 527 | return AVERROR_EOF; | ||
| 528 | else | ||
| 529 | return AVERROR(EAGAIN); | ||
| 530 | } | ||
| 531 | |||
| 532 | if (ctx->async_encode) { | ||
| 533 | if (av_fifo_can_write(ctx->encode_fifo)) { | ||
| 534 | err = hw_base_encode_pick_next(avctx, &pic); | ||
| 535 | if (!err) { | ||
| 536 | av_assert0(pic); | ||
| 537 | pic->encode_order = ctx->encode_order + | ||
| 538 | av_fifo_can_read(ctx->encode_fifo); | ||
| 539 | err = ctx->op->issue(avctx, pic); | ||
| 540 | if (err < 0) { | ||
| 541 | av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err); | ||
| 542 | return err; | ||
| 543 | } | ||
| 544 | pic->encode_issued = 1; | ||
| 545 | av_fifo_write(ctx->encode_fifo, &pic, 1); | ||
| 546 | } | ||
| 547 | } | ||
| 548 | |||
| 549 | if (!av_fifo_can_read(ctx->encode_fifo)) | ||
| 550 | return err; | ||
| 551 | |||
| 552 | // More frames can be buffered | ||
| 553 | if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream) | ||
| 554 | return AVERROR(EAGAIN); | ||
| 555 | |||
| 556 | av_fifo_read(ctx->encode_fifo, &pic, 1); | ||
| 557 | ctx->encode_order = pic->encode_order + 1; | ||
| 558 | } else { | ||
| 559 | err = hw_base_encode_pick_next(avctx, &pic); | ||
| 560 | if (err < 0) | ||
| 561 | return err; | ||
| 562 | av_assert0(pic); | ||
| 563 | |||
| 564 | pic->encode_order = ctx->encode_order++; | ||
| 565 | |||
| 566 | err = ctx->op->issue(avctx, pic); | ||
| 567 | if (err < 0) { | ||
| 568 | av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err); | ||
| 569 | return err; | ||
| 570 | } | ||
| 571 | |||
| 572 | pic->encode_issued = 1; | ||
| 573 | } | ||
| 574 | |||
| 575 | err = ctx->op->output(avctx, pic, pkt); | ||
| 576 | if (err < 0) { | ||
| 577 | av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err); | ||
| 578 | return err; | ||
| 579 | } | ||
| 580 | |||
| 581 | ctx->output_order = pic->encode_order; | ||
| 582 | hw_base_encode_clear_old(avctx); | ||
| 583 | |||
| 584 | /** loop to get an available pkt in encoder flushing. */ | ||
| 585 | if (ctx->end_of_stream && !pkt->size) | ||
| 586 | goto start; | ||
| 587 | |||
| 588 | end: | ||
| 589 | if (pkt->size) | ||
| 590 | av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", " | ||
| 591 | "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size); | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| @@ -19,6 +19,8 @@ · 18 unmodified lines | |||
| 19 | #ifndef AVCODEC_HW_BASE_ENCODE_H | 19 | #ifndef AVCODEC_HW_BASE_ENCODE_H |
| 20 | #define AVCODEC_HW_BASE_ENCODE_H | 20 | #define AVCODEC_HW_BASE_ENCODE_H |
| 21 | 21 | ||
| 22 | #include "libavutil/fifo.h" | ||
| 23 | |||
| 22 | #define MAX_DPB_SIZE 16 | 24 | #define MAX_DPB_SIZE 16 |
| 23 | #define MAX_PICTURE_REFERENCES 2 | 25 | #define MAX_PICTURE_REFERENCES 2 |
| 24 | #define MAX_REORDER_DELAY 16 | 26 | #define MAX_REORDER_DELAY 16 |
| @@ -54,13 +56,135 @@ enum { · 29 unmodified lines | |||
| 54 | FF_HW_FLAG_NON_IDR_KEY_PICTURES = 1 << 5, | 56 | FF_HW_FLAG_NON_IDR_KEY_PICTURES = 1 << 5, |
| 55 | }; | 57 | }; |
| 56 | 58 | ||
| 59 | typedef struct FFHWBaseEncodePicture { | ||
| 60 | struct FFHWBaseEncodePicture *next; | ||
| 61 | |||
| 62 | int64_t display_order; | ||
| 63 | int64_t encode_order; | ||
| 64 | int64_t pts; | ||
| 65 | int64_t duration; | ||
| 66 | int force_idr; | ||
| 67 | |||
| 68 | void *opaque; | ||
| 69 | AVBufferRef *opaque_ref; | ||
| 70 | |||
| 71 | int type; | ||
| 72 | int b_depth; | ||
| 73 | int encode_issued; | ||
| 74 | int encode_complete; | ||
| 75 | |||
| 76 | AVFrame *input_image; | ||
| 77 | AVFrame *recon_image; | ||
| 78 | |||
| 79 | void *priv_data; | ||
| 80 | |||
| 81 | // Whether this picture is a reference picture. | ||
| 82 | int is_reference; | ||
| 83 | |||
| 84 | // The contents of the DPB after this picture has been decoded. | ||
| 85 | // This will contain the picture itself if it is a reference picture, | ||
| 86 | // but not if it isn't. | ||
| 87 | int nb_dpb_pics; | ||
| 88 | struct FFHWBaseEncodePicture *dpb[MAX_DPB_SIZE]; | ||
| 89 | // The reference pictures used in decoding this picture. If they are | ||
| 90 | // used by later pictures they will also appear in the DPB. ref[0][] for | ||
| 91 | // previous reference frames. ref[1][] for future reference frames. | ||
| 92 | int nb_refs[MAX_REFERENCE_LIST_NUM]; | ||
| 93 | struct FFHWBaseEncodePicture *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]; | ||
| 94 | // The previous reference picture in encode order. Must be in at least | ||
| 95 | // one of the reference list and DPB list. | ||
| 96 | struct FFHWBaseEncodePicture *prev; | ||
| 97 | // Reference count for other pictures referring to this one through | ||
| 98 | // the above pointers, directly from incomplete pictures and indirectly | ||
| 99 | // through completed pictures. | ||
| 100 | int ref_count[2]; | ||
| 101 | int ref_removed[2]; | ||
| 102 | } FFHWBaseEncodePicture; | ||
| 103 | |||
| 104 | typedef struct FFHWEncodePictureOperation { | ||
| 105 | // Alloc memory for the picture structure and initialize the API-specific internals | ||
| 106 | // based of the given frame. | ||
| 107 | FFHWBaseEncodePicture * (*alloc)(AVCodecContext *avctx, const AVFrame *frame); | ||
| 108 | // Issue the picture structure, which will send the frame surface to HW Encode API. | ||
| 109 | int (*issue)(AVCodecContext *avctx, const FFHWBaseEncodePicture *base_pic); | ||
| 110 | // Get the output AVPacket. | ||
| 111 | int (*output)(AVCodecContext *avctx, const FFHWBaseEncodePicture *base_pic, AVPacket *pkt); | ||
| 112 | // Free the picture structure. | ||
| 113 | int (*free)(AVCodecContext *avctx, FFHWBaseEncodePicture *base_pic); | ||
| 114 | } FFHWEncodePictureOperation; | ||
| 115 | |||
| 57 | typedef struct FFHWBaseEncodeContext { | 116 | typedef struct FFHWBaseEncodeContext { |
| 58 | const AVClass *class; | 117 | const AVClass *class; |
| 59 | 118 | ||
| 119 | // Hardware-specific hooks. | ||
| 120 | const struct FFHWEncodePictureOperation *op; | ||
| 121 | |||
| 122 | // Current encoding window, in display (input) order. | ||
| 123 | FFHWBaseEncodePicture *pic_start, *pic_end; | ||
| 124 | // The next picture to use as the previous reference picture in | ||
| 125 | // encoding order. Order from small to large in encoding order. | ||
| 126 | FFHWBaseEncodePicture *next_prev[MAX_PICTURE_REFERENCES]; | ||
| 127 | int nb_next_prev; | ||
| 128 | |||
| 129 | // Next input order index (display order). | ||
| 130 | int64_t input_order; | ||
| 131 | // Number of frames that output is behind input. | ||
| 132 | int64_t output_delay; | ||
| 133 | // Next encode order index. | ||
| 134 | int64_t encode_order; | ||
| 135 | // Number of frames decode output will need to be delayed. | ||
| 136 | int64_t decode_delay; | ||
| 137 | // Next output order index (in encode order). | ||
| 138 | int64_t output_order; | ||
| 139 | |||
| 140 | // Timestamp handling. | ||
| 141 | int64_t first_pts; | ||
| 142 | int64_t dts_pts_diff; | ||
| 143 | int64_t ts_ring[MAX_REORDER_DELAY * 3 + | ||
| 144 | MAX_ASYNC_DEPTH]; | ||
| 145 | |||
| 146 | // Frame type decision. | ||
| 147 | int gop_size; | ||
| 148 | int closed_gop; | ||
| 149 | int gop_per_idr; | ||
| 150 | int p_per_i; | ||
| 151 | int max_b_depth; | ||
| 152 | int b_per_p; | ||
| 153 | int force_idr; | ||
| 154 | int idr_counter; | ||
| 155 | int gop_counter; | ||
| 156 | int end_of_stream; | ||
| 157 | int p_to_gpb; | ||
| 158 | |||
| 159 | // Whether the driver supports ROI at all. | ||
| 160 | int roi_allowed; | ||
| 161 | |||
| 162 | // The encoder does not support cropping information, so warn about | ||
| 163 | // it the first time we encounter any nonzero crop fields. | ||
| 164 | int crop_warned; | ||
| 165 | // If the driver does not support ROI then warn the first time we | ||
| 166 | // encounter a frame with ROI side data. | ||
| 167 | int roi_warned; | ||
| 168 | |||
| 169 | // The frame to be filled with data. | ||
| 170 | AVFrame *frame; | ||
| 171 | |||
| 172 | // Whether the HW supports sync buffer function. | ||
| 173 | // If supported, encode_fifo/async_depth will be used together. | ||
| 174 | // Used for output buffer synchronization. | ||
| 175 | int async_encode; | ||
| 176 | |||
| 177 | // Store buffered pic. | ||
| 178 | AVFifo *encode_fifo; | ||
| 60 | // Max number of frame buffered in encoder. | 179 | // Max number of frame buffered in encoder. |
| 61 | int async_depth; | 180 | int async_depth; |
| 181 | |||
| 182 | /** Tail data of a pic, now only used for av1 repeat frame header. */ | ||
| 183 | AVPacket *tail_pkt; | ||
| 62 | } FFHWBaseEncodeContext; | 184 | } FFHWBaseEncodeContext; |
| 63 | 185 | ||
| 186 | int ff_hw_base_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt); | ||
| 187 | |||
| 64 | #define HW_BASE_ENCODE_COMMON_OPTIONS \ | 188 | #define HW_BASE_ENCODE_COMMON_OPTIONS \ |
| 65 | { "async_depth", "Maximum processing parallelism. " \ | 189 | { "async_depth", "Maximum processing parallelism. " \ |
| 66 | "Increase this to improve single channel performance.", \ | 190 | "Increase this to improve single channel performance.", \ |
| @@ -138,22 +138,26 @@ static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, · 137 unmodified lines | |||
| 138 | static int vaapi_encode_wait(AVCodecContext *avctx, | 138 | static int vaapi_encode_wait(AVCodecContext *avctx, |
| 139 | VAAPIEncodePicture *pic) | 139 | VAAPIEncodePicture *pic) |
| 140 | { | 140 | { |
| 141 | #if VA_CHECK_VERSION(1, 9, 0) | ||
| 142 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 143 | #endif | ||
| 141 | VAAPIEncodeContext *ctx = avctx->priv_data; | 144 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 145 | FFHWBaseEncodePicture *base_pic = &pic->base; | ||
| 142 | VAStatus vas; | 146 | VAStatus vas; |
| 143 | 147 | ||
| 144 | av_assert0(pic->encode_issued); | 148 | av_assert0(base_pic->encode_issued); |
| 145 | 149 | ||
| 146 | if (pic->encode_complete) { | 150 | if (base_pic->encode_complete) { |
| 147 | // Already waited for this picture. | 151 | // Already waited for this picture. |
| 148 | return 0; | 152 | return 0; |
| 149 | } | 153 | } |
| 150 | 154 | ||
| 151 | av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" " | 155 | av_log(avctx, AV_LOG_DEBUG, "Sync to pic %"PRId64"/%"PRId64" " |
| 152 | "(input surface %#x).\n", pic->display_order, | 156 | "(input surface %#x).\n", base_pic->display_order, |
| 153 | pic->encode_order, pic->input_surface); | 157 | base_pic->encode_order, pic->input_surface); |
| 154 | 158 | ||
| 155 | #if VA_CHECK_VERSION(1, 9, 0) | 159 | #if VA_CHECK_VERSION(1, 9, 0) |
| 156 | if (ctx->has_sync_buffer_func) { | 160 | if (base_ctx->async_encode) { |
| 157 | vas = vaSyncBuffer(ctx->hwctx->display, | 161 | vas = vaSyncBuffer(ctx->hwctx->display, |
| 158 | pic->output_buffer, | 162 | pic->output_buffer, |
| 159 | VA_TIMEOUT_INFINITE); | 163 | VA_TIMEOUT_INFINITE); |
| @@ -174,9 +178,9 @@ static int vaapi_encode_wait(AVCodecContext *avctx, · 14 unmodified lines | |||
| 174 | } | 178 | } |
| 175 | 179 | ||
| 176 | // Input is definitely finished with now. | 180 | // Input is definitely finished with now. |
| 177 | av_frame_free(&pic->input_image); | 181 | av_frame_free(&base_pic->input_image); |
| 178 | 182 | ||
| 179 | pic->encode_complete = 1; | 183 | base_pic->encode_complete = 1; |
| 180 | return 0; | 184 | return 0; |
| 181 | } | 185 | } |
| 182 | 186 | ||
| @@ -263,9 +267,11 @@ static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, · 80 unmodified lines | |||
| 263 | } | 267 | } |
| 264 | 268 | ||
| 265 | static int vaapi_encode_issue(AVCodecContext *avctx, | 269 | static int vaapi_encode_issue(AVCodecContext *avctx, |
| 266 | VAAPIEncodePicture *pic) | 270 | const FFHWBaseEncodePicture *base_pic) |
| 267 | { | 271 | { |
| 268 | VAAPIEncodeContext *ctx = avctx->priv_data; | 272 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 273 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 274 | VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic; | ||
| 269 | VAAPIEncodeSlice *slice; | 275 | VAAPIEncodeSlice *slice; |
| 270 | VAStatus vas; | 276 | VAStatus vas; |
| 271 | int err, i; | 277 | int err, i; |
| @@ -274,52 +280,46 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines | |||
| 274 | av_unused AVFrameSideData *sd; | 280 | av_unused AVFrameSideData *sd; |
| 275 | 281 | ||
| 276 | av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" " | 282 | av_log(avctx, AV_LOG_DEBUG, "Issuing encode for pic %"PRId64"/%"PRId64" " |
| 277 | "as type %s.\n", pic->display_order, pic->encode_order, | 283 | "as type %s.\n", base_pic->display_order, base_pic->encode_order, |
| 278 | ff_hw_base_encode_get_pictype_name(pic->type)); | 284 | ff_hw_base_encode_get_pictype_name(base_pic->type)); |
| 279 | if (pic->nb_refs[0] == 0 && pic->nb_refs[1] == 0) { | 285 | if (base_pic->nb_refs[0] == 0 && base_pic->nb_refs[1] == 0) { |
| 280 | av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n"); | 286 | av_log(avctx, AV_LOG_DEBUG, "No reference pictures.\n"); |
| 281 | } else { | 287 | } else { |
| 282 | av_log(avctx, AV_LOG_DEBUG, "L0 refers to"); | 288 | av_log(avctx, AV_LOG_DEBUG, "L0 refers to"); |
| 283 | for (i = 0; i < pic->nb_refs[0]; i++) { | 289 | for (i = 0; i < base_pic->nb_refs[0]; i++) { |
| 284 | av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, | 290 | av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, |
| 285 | pic->refs[0][i]->display_order, pic->refs[0][i]->encode_order); | 291 | base_pic->refs[0][i]->display_order, base_pic->refs[0][i]->encode_order); |
| 286 | } | 292 | } |
| 287 | av_log(avctx, AV_LOG_DEBUG, ".\n"); | 293 | av_log(avctx, AV_LOG_DEBUG, ".\n"); |
| 288 | 294 | ||
| 289 | if (pic->nb_refs[1]) { | 295 | if (base_pic->nb_refs[1]) { |
| 290 | av_log(avctx, AV_LOG_DEBUG, "L1 refers to"); | 296 | av_log(avctx, AV_LOG_DEBUG, "L1 refers to"); |
| 291 | for (i = 0; i < pic->nb_refs[1]; i++) { | 297 | for (i = 0; i < base_pic->nb_refs[1]; i++) { |
| 292 | av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, | 298 | av_log(avctx, AV_LOG_DEBUG, " %"PRId64"/%"PRId64, |
| 293 | pic->refs[1][i]->display_order, pic->refs[1][i]->encode_order); | 299 | base_pic->refs[1][i]->display_order, base_pic->refs[1][i]->encode_order); |
| 294 | } | 300 | } |
| 295 | av_log(avctx, AV_LOG_DEBUG, ".\n"); | 301 | av_log(avctx, AV_LOG_DEBUG, ".\n"); |
| 296 | } | 302 | } |
| 297 | } | 303 | } |
| 298 | 304 | ||
| 299 | av_assert0(!pic->encode_issued); | 305 | av_assert0(!base_pic->encode_issued); |
| 300 | for (i = 0; i < pic->nb_refs[0]; i++) { | 306 | for (i = 0; i < base_pic->nb_refs[0]; i++) { |
| 301 | av_assert0(pic->refs[0][i]); | 307 | av_assert0(base_pic->refs[0][i]); |
| 302 | av_assert0(pic->refs[0][i]->encode_issued); | 308 | av_assert0(base_pic->refs[0][i]->encode_issued); |
| 303 | } | 309 | } |
| 304 | for (i = 0; i < pic->nb_refs[1]; i++) { | 310 | for (i = 0; i < base_pic->nb_refs[1]; i++) { |
| 305 | av_assert0(pic->refs[1][i]); | 311 | av_assert0(base_pic->refs[1][i]); |
| 306 | av_assert0(pic->refs[1][i]->encode_issued); | 312 | av_assert0(base_pic->refs[1][i]->encode_issued); |
| 307 | } | 313 | } |
| 308 | 314 | ||
| 309 | av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface); | 315 | av_log(avctx, AV_LOG_DEBUG, "Input surface is %#x.\n", pic->input_surface); |
| 310 | 316 | ||
| 311 | pic->recon_image = av_frame_alloc(); | 317 | err = av_hwframe_get_buffer(ctx->recon_frames_ref, base_pic->recon_image, 0); |
| 312 | if (!pic->recon_image) { | ||
| 313 | err = AVERROR(ENOMEM); | ||
| 314 | goto fail; | ||
| 315 | } | ||
| 316 | |||
| 317 | err = av_hwframe_get_buffer(ctx->recon_frames_ref, pic->recon_image, 0); | ||
| 318 | if (err < 0) { | 318 | if (err < 0) { |
| 319 | err = AVERROR(ENOMEM); | 319 | err = AVERROR(ENOMEM); |
| 320 | goto fail; | 320 | goto fail; |
| 321 | } | 321 | } |
| 322 | pic->recon_surface = (VASurfaceID)(uintptr_t)pic->recon_image->data[3]; | 322 | pic->recon_surface = (VASurfaceID)(uintptr_t)base_pic->recon_image->data[3]; |
| 323 | av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface); | 323 | av_log(avctx, AV_LOG_DEBUG, "Recon surface is %#x.\n", pic->recon_surface); |
| 324 | 324 | ||
| 325 | pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool); | 325 | pic->output_buffer_ref = ff_refstruct_pool_get(ctx->output_buffer_pool); |
| @@ -343,7 +343,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 17 unmodified lines | |||
| 343 | 343 | ||
| 344 | pic->nb_param_buffers = 0; | 344 | pic->nb_param_buffers = 0; |
| 345 | 345 | ||
| 346 | if (pic->type == FF_HW_PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) { | 346 | if (base_pic->type == FF_HW_PICTURE_TYPE_IDR && ctx->codec->init_sequence_params) { |
| 347 | err = vaapi_encode_make_param_buffer(avctx, pic, | 347 | err = vaapi_encode_make_param_buffer(avctx, pic, |
| 348 | VAEncSequenceParameterBufferType, | 348 | VAEncSequenceParameterBufferType, |
| 349 | ctx->codec_sequence_params, | 349 | ctx->codec_sequence_params, |
| @@ -352,7 +352,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 2 unmodified lines | |||
| 352 | goto fail; | 352 | goto fail; |
| 353 | } | 353 | } |
| 354 | 354 | ||
| 355 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | 355 | if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) { |
| 356 | for (i = 0; i < ctx->nb_global_params; i++) { | 356 | for (i = 0; i < ctx->nb_global_params; i++) { |
| 357 | err = vaapi_encode_make_misc_param_buffer(avctx, pic, | 357 | err = vaapi_encode_make_misc_param_buffer(avctx, pic, |
| 358 | ctx->global_params_type[i], | 358 | ctx->global_params_type[i], |
| @@ -389,7 +389,7 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 30 unmodified lines | |||
| 389 | } | 389 | } |
| 390 | #endif | 390 | #endif |
| 391 | 391 | ||
| 392 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | 392 | if (base_pic->type == FF_HW_PICTURE_TYPE_IDR) { |
| 393 | if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && | 393 | if (ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE && |
| 394 | ctx->codec->write_sequence_header) { | 394 | ctx->codec->write_sequence_header) { |
| 395 | bit_len = 8 * sizeof(data); | 395 | bit_len = 8 * sizeof(data); |
| @@ -529,9 +529,9 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 133 unmodified lines | |||
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | #if VA_CHECK_VERSION(1, 0, 0) | 531 | #if VA_CHECK_VERSION(1, 0, 0) |
| 532 | sd = av_frame_get_side_data(pic->input_image, | 532 | sd = av_frame_get_side_data(base_pic->input_image, |
| 533 | AV_FRAME_DATA_REGIONS_OF_INTEREST); | 533 | AV_FRAME_DATA_REGIONS_OF_INTEREST); |
| 534 | if (sd && ctx->roi_allowed) { | 534 | if (sd && base_ctx->roi_allowed) { |
| 535 | const AVRegionOfInterest *roi; | 535 | const AVRegionOfInterest *roi; |
| 536 | uint32_t roi_size; | 536 | uint32_t roi_size; |
| 537 | VAEncMiscParameterBufferROI param_roi; | 537 | VAEncMiscParameterBufferROI param_roi; |
| @@ -542,11 +542,11 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 4 unmodified lines | |||
| 542 | av_assert0(roi_size && sd->size % roi_size == 0); | 542 | av_assert0(roi_size && sd->size % roi_size == 0); |
| 543 | nb_roi = sd->size / roi_size; | 543 | nb_roi = sd->size / roi_size; |
| 544 | if (nb_roi > ctx->roi_max_regions) { | 544 | if (nb_roi > ctx->roi_max_regions) { |
| 545 | if (!ctx->roi_warned) { | 545 | if (!base_ctx->roi_warned) { |
| 546 | av_log(avctx, AV_LOG_WARNING, "More ROIs set than " | 546 | av_log(avctx, AV_LOG_WARNING, "More ROIs set than " |
| 547 | "supported by driver (%d > %d).\n", | 547 | "supported by driver (%d > %d).\n", |
| 548 | nb_roi, ctx->roi_max_regions); | 548 | nb_roi, ctx->roi_max_regions); |
| 549 | ctx->roi_warned = 1; | 549 | base_ctx->roi_warned = 1; |
| 550 | } | 550 | } |
| 551 | nb_roi = ctx->roi_max_regions; | 551 | nb_roi = ctx->roi_max_regions; |
| 552 | } | 552 | } |
| @@ -639,8 +639,6 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 86 unmodified lines | |||
| 639 | } | 639 | } |
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | pic->encode_issued = 1; | ||
| 643 | |||
| 644 | return 0; | 642 | return 0; |
| 645 | 643 | ||
| 646 | fail_with_picture: | 644 | fail_with_picture: |
| @@ -657,14 +655,13 @@ fail_at_end: · 10 unmodified lines | |||
| 657 | av_freep(&pic->param_buffers); | 655 | av_freep(&pic->param_buffers); |
| 658 | av_freep(&pic->slices); | 656 | av_freep(&pic->slices); |
| 659 | av_freep(&pic->roi); | 657 | av_freep(&pic->roi); |
| 660 | av_frame_free(&pic->recon_image); | ||
| 661 | ff_refstruct_unref(&pic->output_buffer_ref); | 658 | ff_refstruct_unref(&pic->output_buffer_ref); |
| 662 | pic->output_buffer = VA_INVALID_ID; | 659 | pic->output_buffer = VA_INVALID_ID; |
| 663 | return err; | 660 | return err; |
| 664 | } | 661 | } |
| 665 | 662 | ||
| 666 | static int vaapi_encode_set_output_property(AVCodecContext *avctx, | 663 | static int vaapi_encode_set_output_property(AVCodecContext *avctx, |
| 667 | VAAPIEncodePicture *pic, | 664 | FFHWBaseEncodePicture *pic, |
| 668 | AVPacket *pkt) | 665 | AVPacket *pkt) |
| 669 | { | 666 | { |
| 670 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | 667 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| @@ -689,16 +686,16 @@ static int vaapi_encode_set_output_property(AVCodecContext *avctx, · 18 unmodified lines | |||
| 689 | return 0; | 686 | return 0; |
| 690 | } | 687 | } |
| 691 | 688 | ||
| 692 | if (ctx->output_delay == 0) { | 689 | if (base_ctx->output_delay == 0) { |
| 693 | pkt->dts = pkt->pts; | 690 | pkt->dts = pkt->pts; |
| 694 | } else if (pic->encode_order < ctx->decode_delay) { | 691 | } else if (pic->encode_order < base_ctx->decode_delay) { |
| 695 | if (ctx->ts_ring[pic->encode_order] < INT64_MIN + ctx->dts_pts_diff) | 692 | if (base_ctx->ts_ring[pic->encode_order] < INT64_MIN + base_ctx->dts_pts_diff) |
| 696 | pkt->dts = INT64_MIN; | 693 | pkt->dts = INT64_MIN; |
| 697 | else | 694 | else |
| 698 | pkt->dts = ctx->ts_ring[pic->encode_order] - ctx->dts_pts_diff; | 695 | pkt->dts = base_ctx->ts_ring[pic->encode_order] - base_ctx->dts_pts_diff; |
| 699 | } else { | 696 | } else { |
| 700 | pkt->dts = ctx->ts_ring[(pic->encode_order - ctx->decode_delay) % | 697 | pkt->dts = base_ctx->ts_ring[(pic->encode_order - base_ctx->decode_delay) % |
| 701 | (3 * ctx->output_delay + base_ctx->async_depth)]; | 698 | (3 * base_ctx->output_delay + base_ctx->async_depth)]; |
| 702 | } | 699 | } |
| 703 | 700 | ||
| 704 | return 0; | 701 | return 0; |
| @@ -817,9 +814,11 @@ end: · 112 unmodified lines | |||
| 817 | } | 814 | } |
| 818 | 815 | ||
| 819 | static int vaapi_encode_output(AVCodecContext *avctx, | 816 | static int vaapi_encode_output(AVCodecContext *avctx, |
| 820 | VAAPIEncodePicture *pic, AVPacket *pkt) | 817 | const FFHWBaseEncodePicture *base_pic, AVPacket *pkt) |
| 821 | { | 818 | { |
| 822 | VAAPIEncodeContext *ctx = avctx->priv_data; | 819 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 820 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 821 | VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic; | ||
| 823 | AVPacket *pkt_ptr = pkt; | 822 | AVPacket *pkt_ptr = pkt; |
| 824 | int err; | 823 | int err; |
| 825 | 824 | ||
| @@ -832,17 +831,17 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 6 unmodified lines | |||
| 832 | ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref); | 831 | ctx->coded_buffer_ref = ff_refstruct_ref(pic->output_buffer_ref); |
| 833 | 832 | ||
| 834 | if (pic->tail_size) { | 833 | if (pic->tail_size) { |
| 835 | if (ctx->tail_pkt->size) { | 834 | if (base_ctx->tail_pkt->size) { |
| 836 | err = AVERROR_BUG; | 835 | err = AVERROR_BUG; |
| 837 | goto end; | 836 | goto end; |
| 838 | } | 837 | } |
| 839 | 838 | ||
| 840 | err = ff_get_encode_buffer(avctx, ctx->tail_pkt, pic->tail_size, 0); | 839 | err = ff_get_encode_buffer(avctx, base_ctx->tail_pkt, pic->tail_size, 0); |
| 841 | if (err < 0) | 840 | if (err < 0) |
| 842 | goto end; | 841 | goto end; |
| 843 | 842 | ||
| 844 | memcpy(ctx->tail_pkt->data, pic->tail_data, pic->tail_size); | 843 | memcpy(base_ctx->tail_pkt->data, pic->tail_data, pic->tail_size); |
| 845 | pkt_ptr = ctx->tail_pkt; | 844 | pkt_ptr = base_ctx->tail_pkt; |
| 846 | } | 845 | } |
| 847 | } else { | 846 | } else { |
| 848 | err = vaapi_encode_get_coded_data(avctx, pic, pkt); | 847 | err = vaapi_encode_get_coded_data(avctx, pic, pkt); |
| @@ -851,9 +850,9 @@ static int vaapi_encode_output(AVCodecContext *avctx, · 2 unmodified lines | |||
| 851 | } | 850 | } |
| 852 | 851 | ||
| 853 | av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n", | 852 | av_log(avctx, AV_LOG_DEBUG, "Output read for pic %"PRId64"/%"PRId64".\n", |
| 854 | pic->display_order, pic->encode_order); | 853 | base_pic->display_order, base_pic->encode_order); |
| 855 | 854 | ||
| 856 | vaapi_encode_set_output_property(avctx, pic, pkt_ptr); | 855 | vaapi_encode_set_output_property(avctx, (FFHWBaseEncodePicture*)pic, pkt_ptr); |
| 857 | 856 | ||
| 858 | end: | 857 | end: |
| 859 | ff_refstruct_unref(&pic->output_buffer_ref); | 858 | ff_refstruct_unref(&pic->output_buffer_ref); |
| @@ -864,12 +863,14 @@ end: · 4 unmodified lines | |||
| 864 | static int vaapi_encode_discard(AVCodecContext *avctx, | 863 | static int vaapi_encode_discard(AVCodecContext *avctx, |
| 865 | VAAPIEncodePicture *pic) | 864 | VAAPIEncodePicture *pic) |
| 866 | { | 865 | { |
| 866 | FFHWBaseEncodePicture *base_pic = &pic->base; | ||
| 867 | |||
| 867 | vaapi_encode_wait(avctx, pic); | 868 | vaapi_encode_wait(avctx, pic); |
| 868 | 869 | ||
| 869 | if (pic->output_buffer_ref) { | 870 | if (pic->output_buffer_ref) { |
| 870 | av_log(avctx, AV_LOG_DEBUG, "Discard output for pic " | 871 | av_log(avctx, AV_LOG_DEBUG, "Discard output for pic " |
| 871 | "%"PRId64"/%"PRId64".\n", | 872 | "%"PRId64"/%"PRId64".\n", |
| 872 | pic->display_order, pic->encode_order); | 873 | base_pic->display_order, base_pic->encode_order); |
| 873 | 874 | ||
| 874 | ff_refstruct_unref(&pic->output_buffer_ref); | 875 | ff_refstruct_unref(&pic->output_buffer_ref); |
| 875 | pic->output_buffer = VA_INVALID_ID; | 876 | pic->output_buffer = VA_INVALID_ID; |
| @@ -878,8 +879,8 @@ static int vaapi_encode_discard(AVCodecContext *avctx, · 2 unmodified lines | |||
| 878 | return 0; | 879 | return 0; |
| 879 | } | 880 | } |
| 880 | 881 | ||
| 881 | static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, | 882 | static FFHWBaseEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, |
| 882 | const AVFrame *frame) | 883 | const AVFrame *frame) |
| 883 | { | 884 | { |
| 884 | VAAPIEncodeContext *ctx = avctx->priv_data; | 885 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 885 | VAAPIEncodePicture *pic; | 886 | VAAPIEncodePicture *pic; |
| @@ -889,8 +890,8 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines | |||
| 889 | return NULL; | 890 | return NULL; |
| 890 | 891 | ||
| 891 | if (ctx->codec->picture_priv_data_size > 0) { | 892 | if (ctx->codec->picture_priv_data_size > 0) { |
| 892 | pic->priv_data = av_mallocz(ctx->codec->picture_priv_data_size); | 893 | pic->base.priv_data = av_mallocz(ctx->codec->picture_priv_data_size); |
| 893 | if (!pic->priv_data) { | 894 | if (!pic->base.priv_data) { |
| 894 | av_freep(&pic); | 895 | av_freep(&pic); |
| 895 | return NULL; | 896 | return NULL; |
| 896 | } | 897 | } |
| @@ -900,15 +901,16 @@ static VAAPIEncodePicture *vaapi_encode_alloc(AVCodecContext *avctx, · 3 unmodified lines | |||
| 900 | pic->recon_surface = VA_INVALID_ID; | 901 | pic->recon_surface = VA_INVALID_ID; |
| 901 | pic->output_buffer = VA_INVALID_ID; | 902 | pic->output_buffer = VA_INVALID_ID; |
| 902 | 903 | ||
| 903 | return pic; | 904 | return &pic->base; |
| 904 | } | 905 | } |
| 905 | 906 | ||
| 906 | static int vaapi_encode_free(AVCodecContext *avctx, | 907 | static int vaapi_encode_free(AVCodecContext *avctx, |
| 907 | VAAPIEncodePicture *pic) | 908 | FFHWBaseEncodePicture *base_pic) |
| 908 | { | 909 | { |
| 910 | VAAPIEncodePicture *pic = (VAAPIEncodePicture*)base_pic; | ||
| 909 | int i; | 911 | int i; |
| 910 | 912 | ||
| 911 | if (pic->encode_issued) | 913 | if (base_pic->encode_issued) |
| 912 | vaapi_encode_discard(avctx, pic); | 914 | vaapi_encode_discard(avctx, pic); |
| 913 | 915 | ||
| 914 | if (pic->slices) { | 916 | if (pic->slices) { |
| @@ -916,17 +918,17 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 1 unmodified line | |||
| 916 | av_freep(&pic->slices[i].codec_slice_params); | 918 | av_freep(&pic->slices[i].codec_slice_params); |
| 917 | } | 919 | } |
| 918 | 920 | ||
| 919 | av_frame_free(&pic->input_image); | 921 | av_frame_free(&base_pic->input_image); |
| 920 | av_frame_free(&pic->recon_image); | 922 | av_frame_free(&base_pic->recon_image); |
| 921 | 923 | ||
| 922 | av_buffer_unref(&pic->opaque_ref); | 924 | av_buffer_unref(&base_pic->opaque_ref); |
| 923 | 925 | ||
| 924 | av_freep(&pic->param_buffers); | 926 | av_freep(&pic->param_buffers); |
| 925 | av_freep(&pic->slices); | 927 | av_freep(&pic->slices); |
| 926 | // Output buffer should already be destroyed. | 928 | // Output buffer should already be destroyed. |
| 927 | av_assert0(pic->output_buffer == VA_INVALID_ID); | 929 | av_assert0(pic->output_buffer == VA_INVALID_ID); |
| 928 | 930 | ||
| 929 | av_freep(&pic->priv_data); | 931 | av_freep(&base_pic->priv_data); |
| 930 | av_freep(&pic->codec_picture_params); | 932 | av_freep(&pic->codec_picture_params); |
| 931 | av_freep(&pic->roi); | 933 | av_freep(&pic->roi); |
| 932 | 934 | ||
| @@ -935,564 +937,6 @@ static int vaapi_encode_free(AVCodecContext *avctx, · 2 unmodified lines | |||
| 935 | return 0; | 937 | return 0; |
| 936 | } | 938 | } |
| 937 | 939 | ||
| 938 | static void vaapi_encode_add_ref(AVCodecContext *avctx, | ||
| 939 | VAAPIEncodePicture *pic, | ||
| 940 | VAAPIEncodePicture *target, | ||
| 941 | int is_ref, int in_dpb, int prev) | ||
| 942 | { | ||
| 943 | int refs = 0; | ||
| 944 | |||
| 945 | if (is_ref) { | ||
| 946 | av_assert0(pic != target); | ||
| 947 | av_assert0(pic->nb_refs[0] < MAX_PICTURE_REFERENCES && | ||
| 948 | pic->nb_refs[1] < MAX_PICTURE_REFERENCES); | ||
| 949 | if (target->display_order < pic->display_order) | ||
| 950 | pic->refs[0][pic->nb_refs[0]++] = target; | ||
| 951 | else | ||
| 952 | pic->refs[1][pic->nb_refs[1]++] = target; | ||
| 953 | ++refs; | ||
| 954 | } | ||
| 955 | |||
| 956 | if (in_dpb) { | ||
| 957 | av_assert0(pic->nb_dpb_pics < MAX_DPB_SIZE); | ||
| 958 | pic->dpb[pic->nb_dpb_pics++] = target; | ||
| 959 | ++refs; | ||
| 960 | } | ||
| 961 | |||
| 962 | if (prev) { | ||
| 963 | av_assert0(!pic->prev); | ||
| 964 | pic->prev = target; | ||
| 965 | ++refs; | ||
| 966 | } | ||
| 967 | |||
| 968 | target->ref_count[0] += refs; | ||
| 969 | target->ref_count[1] += refs; | ||
| 970 | } | ||
| 971 | |||
| 972 | static void vaapi_encode_remove_refs(AVCodecContext *avctx, | ||
| 973 | VAAPIEncodePicture *pic, | ||
| 974 | int level) | ||
| 975 | { | ||
| 976 | int i; | ||
| 977 | |||
| 978 | if (pic->ref_removed[level]) | ||
| 979 | return; | ||
| 980 | |||
| 981 | for (i = 0; i < pic->nb_refs[0]; i++) { | ||
| 982 | av_assert0(pic->refs[0][i]); | ||
| 983 | --pic->refs[0][i]->ref_count[level]; | ||
| 984 | av_assert0(pic->refs[0][i]->ref_count[level] >= 0); | ||
| 985 | } | ||
| 986 | |||
| 987 | for (i = 0; i < pic->nb_refs[1]; i++) { | ||
| 988 | av_assert0(pic->refs[1][i]); | ||
| 989 | --pic->refs[1][i]->ref_count[level]; | ||
| 990 | av_assert0(pic->refs[1][i]->ref_count[level] >= 0); | ||
| 991 | } | ||
| 992 | |||
| 993 | for (i = 0; i < pic->nb_dpb_pics; i++) { | ||
| 994 | av_assert0(pic->dpb[i]); | ||
| 995 | --pic->dpb[i]->ref_count[level]; | ||
| 996 | av_assert0(pic->dpb[i]->ref_count[level] >= 0); | ||
| 997 | } | ||
| 998 | |||
| 999 | av_assert0(pic->prev || pic->type == FF_HW_PICTURE_TYPE_IDR); | ||
| 1000 | if (pic->prev) { | ||
| 1001 | --pic->prev->ref_count[level]; | ||
| 1002 | av_assert0(pic->prev->ref_count[level] >= 0); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | pic->ref_removed[level] = 1; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | static void vaapi_encode_set_b_pictures(AVCodecContext *avctx, | ||
| 1009 | VAAPIEncodePicture *start, | ||
| 1010 | VAAPIEncodePicture *end, | ||
| 1011 | VAAPIEncodePicture *prev, | ||
| 1012 | int current_depth, | ||
| 1013 | VAAPIEncodePicture **last) | ||
| 1014 | { | ||
| 1015 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1016 | VAAPIEncodePicture *pic, *next, *ref; | ||
| 1017 | int i, len; | ||
| 1018 | |||
| 1019 | av_assert0(start && end && start != end && start->next != end); | ||
| 1020 | |||
| 1021 | // If we are at the maximum depth then encode all pictures as | ||
| 1022 | // non-referenced B-pictures. Also do this if there is exactly one | ||
| 1023 | // picture left, since there will be nothing to reference it. | ||
| 1024 | if (current_depth == ctx->max_b_depth || start->next->next == end) { | ||
| 1025 | for (pic = start->next; pic; pic = pic->next) { | ||
| 1026 | if (pic == end) | ||
| 1027 | break; | ||
| 1028 | pic->type = FF_HW_PICTURE_TYPE_B; | ||
| 1029 | pic->b_depth = current_depth; | ||
| 1030 | |||
| 1031 | vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0); | ||
| 1032 | vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0); | ||
| 1033 | vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1); | ||
| 1034 | |||
| 1035 | for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) | ||
| 1036 | vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0); | ||
| 1037 | } | ||
| 1038 | *last = prev; | ||
| 1039 | |||
| 1040 | } else { | ||
| 1041 | // Split the current list at the midpoint with a referenced | ||
| 1042 | // B-picture, then descend into each side separately. | ||
| 1043 | len = 0; | ||
| 1044 | for (pic = start->next; pic != end; pic = pic->next) | ||
| 1045 | ++len; | ||
| 1046 | for (pic = start->next, i = 1; 2 * i < len; pic = pic->next, i++); | ||
| 1047 | |||
| 1048 | pic->type = FF_HW_PICTURE_TYPE_B; | ||
| 1049 | pic->b_depth = current_depth; | ||
| 1050 | |||
| 1051 | pic->is_reference = 1; | ||
| 1052 | |||
| 1053 | vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0); | ||
| 1054 | vaapi_encode_add_ref(avctx, pic, start, 1, 1, 0); | ||
| 1055 | vaapi_encode_add_ref(avctx, pic, end, 1, 1, 0); | ||
| 1056 | vaapi_encode_add_ref(avctx, pic, prev, 0, 0, 1); | ||
| 1057 | |||
| 1058 | for (ref = end->refs[1][0]; ref; ref = ref->refs[1][0]) | ||
| 1059 | vaapi_encode_add_ref(avctx, pic, ref, 0, 1, 0); | ||
| 1060 | |||
| 1061 | if (i > 1) | ||
| 1062 | vaapi_encode_set_b_pictures(avctx, start, pic, pic, | ||
| 1063 | current_depth + 1, &next); | ||
| 1064 | else | ||
| 1065 | next = pic; | ||
| 1066 | |||
| 1067 | vaapi_encode_set_b_pictures(avctx, pic, end, next, | ||
| 1068 | current_depth + 1, last); | ||
| 1069 | } | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static void vaapi_encode_add_next_prev(AVCodecContext *avctx, | ||
| 1073 | VAAPIEncodePicture *pic) | ||
| 1074 | { | ||
| 1075 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1076 | int i; | ||
| 1077 | |||
| 1078 | if (!pic) | ||
| 1079 | return; | ||
| 1080 | |||
| 1081 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | ||
| 1082 | for (i = 0; i < ctx->nb_next_prev; i++) { | ||
| 1083 | --ctx->next_prev[i]->ref_count[0]; | ||
| 1084 | ctx->next_prev[i] = NULL; | ||
| 1085 | } | ||
| 1086 | ctx->next_prev[0] = pic; | ||
| 1087 | ++pic->ref_count[0]; | ||
| 1088 | ctx->nb_next_prev = 1; | ||
| 1089 | |||
| 1090 | return; | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | if (ctx->nb_next_prev < MAX_PICTURE_REFERENCES) { | ||
| 1094 | ctx->next_prev[ctx->nb_next_prev++] = pic; | ||
| 1095 | ++pic->ref_count[0]; | ||
| 1096 | } else { | ||
| 1097 | --ctx->next_prev[0]->ref_count[0]; | ||
| 1098 | for (i = 0; i < MAX_PICTURE_REFERENCES - 1; i++) | ||
| 1099 | ctx->next_prev[i] = ctx->next_prev[i + 1]; | ||
| 1100 | ctx->next_prev[i] = pic; | ||
| 1101 | ++pic->ref_count[0]; | ||
| 1102 | } | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | static int vaapi_encode_pick_next(AVCodecContext *avctx, | ||
| 1106 | VAAPIEncodePicture **pic_out) | ||
| 1107 | { | ||
| 1108 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1109 | VAAPIEncodePicture *pic = NULL, *prev = NULL, *next, *start; | ||
| 1110 | int i, b_counter, closed_gop_end; | ||
| 1111 | |||
| 1112 | // If there are any B-frames already queued, the next one to encode | ||
| 1113 | // is the earliest not-yet-issued frame for which all references are | ||
| 1114 | // available. | ||
| 1115 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 1116 | if (pic->encode_issued) | ||
| 1117 | continue; | ||
| 1118 | if (pic->type != FF_HW_PICTURE_TYPE_B) | ||
| 1119 | continue; | ||
| 1120 | for (i = 0; i < pic->nb_refs[0]; i++) { | ||
| 1121 | if (!pic->refs[0][i]->encode_issued) | ||
| 1122 | break; | ||
| 1123 | } | ||
| 1124 | if (i != pic->nb_refs[0]) | ||
| 1125 | continue; | ||
| 1126 | |||
| 1127 | for (i = 0; i < pic->nb_refs[1]; i++) { | ||
| 1128 | if (!pic->refs[1][i]->encode_issued) | ||
| 1129 | break; | ||
| 1130 | } | ||
| 1131 | if (i == pic->nb_refs[1]) | ||
| 1132 | break; | ||
| 1133 | } | ||
| 1134 | |||
| 1135 | if (pic) { | ||
| 1136 | av_log(avctx, AV_LOG_DEBUG, "Pick B-picture at depth %d to " | ||
| 1137 | "encode next.\n", pic->b_depth); | ||
| 1138 | *pic_out = pic; | ||
| 1139 | return 0; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | // Find the B-per-Pth available picture to become the next picture | ||
| 1143 | // on the top layer. | ||
| 1144 | start = NULL; | ||
| 1145 | b_counter = 0; | ||
| 1146 | closed_gop_end = ctx->closed_gop || | ||
| 1147 | ctx->idr_counter == ctx->gop_per_idr; | ||
| 1148 | for (pic = ctx->pic_start; pic; pic = next) { | ||
| 1149 | next = pic->next; | ||
| 1150 | if (pic->encode_issued) { | ||
| 1151 | start = pic; | ||
| 1152 | continue; | ||
| 1153 | } | ||
| 1154 | // If the next available picture is force-IDR, encode it to start | ||
| 1155 | // a new GOP immediately. | ||
| 1156 | if (pic->force_idr) | ||
| 1157 | break; | ||
| 1158 | if (b_counter == ctx->b_per_p) | ||
| 1159 | break; | ||
| 1160 | // If this picture ends a closed GOP or starts a new GOP then it | ||
| 1161 | // needs to be in the top layer. | ||
| 1162 | if (ctx->gop_counter + b_counter + closed_gop_end >= ctx->gop_size) | ||
| 1163 | break; | ||
| 1164 | // If the picture after this one is force-IDR, we need to encode | ||
| 1165 | // this one in the top layer. | ||
| 1166 | if (next && next->force_idr) | ||
| 1167 | break; | ||
| 1168 | ++b_counter; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | // At the end of the stream the last picture must be in the top layer. | ||
| 1172 | if (!pic && ctx->end_of_stream) { | ||
| 1173 | --b_counter; | ||
| 1174 | pic = ctx->pic_end; | ||
| 1175 | if (pic->encode_complete) | ||
| 1176 | return AVERROR_EOF; | ||
| 1177 | else if (pic->encode_issued) | ||
| 1178 | return AVERROR(EAGAIN); | ||
| 1179 | } | ||
| 1180 | |||
| 1181 | if (!pic) { | ||
| 1182 | av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - " | ||
| 1183 | "need more input for reference pictures.\n"); | ||
| 1184 | return AVERROR(EAGAIN); | ||
| 1185 | } | ||
| 1186 | if (ctx->input_order <= ctx->decode_delay && !ctx->end_of_stream) { | ||
| 1187 | av_log(avctx, AV_LOG_DEBUG, "Pick nothing to encode next - " | ||
| 1188 | "need more input for timestamps.\n"); | ||
| 1189 | return AVERROR(EAGAIN); | ||
| 1190 | } | ||
| 1191 | |||
| 1192 | if (pic->force_idr) { | ||
| 1193 | av_log(avctx, AV_LOG_DEBUG, "Pick forced IDR-picture to " | ||
| 1194 | "encode next.\n"); | ||
| 1195 | pic->type = FF_HW_PICTURE_TYPE_IDR; | ||
| 1196 | ctx->idr_counter = 1; | ||
| 1197 | ctx->gop_counter = 1; | ||
| 1198 | |||
| 1199 | } else if (ctx->gop_counter + b_counter >= ctx->gop_size) { | ||
| 1200 | if (ctx->idr_counter == ctx->gop_per_idr) { | ||
| 1201 | av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP IDR-picture to " | ||
| 1202 | "encode next.\n"); | ||
| 1203 | pic->type = FF_HW_PICTURE_TYPE_IDR; | ||
| 1204 | ctx->idr_counter = 1; | ||
| 1205 | } else { | ||
| 1206 | av_log(avctx, AV_LOG_DEBUG, "Pick new-GOP I-picture to " | ||
| 1207 | "encode next.\n"); | ||
| 1208 | pic->type = FF_HW_PICTURE_TYPE_I; | ||
| 1209 | ++ctx->idr_counter; | ||
| 1210 | } | ||
| 1211 | ctx->gop_counter = 1; | ||
| 1212 | |||
| 1213 | } else { | ||
| 1214 | if (ctx->gop_counter + b_counter + closed_gop_end == ctx->gop_size) { | ||
| 1215 | av_log(avctx, AV_LOG_DEBUG, "Pick group-end P-picture to " | ||
| 1216 | "encode next.\n"); | ||
| 1217 | } else { | ||
| 1218 | av_log(avctx, AV_LOG_DEBUG, "Pick normal P-picture to " | ||
| 1219 | "encode next.\n"); | ||
| 1220 | } | ||
| 1221 | pic->type = FF_HW_PICTURE_TYPE_P; | ||
| 1222 | av_assert0(start); | ||
| 1223 | ctx->gop_counter += 1 + b_counter; | ||
| 1224 | } | ||
| 1225 | pic->is_reference = 1; | ||
| 1226 | *pic_out = pic; | ||
| 1227 | |||
| 1228 | vaapi_encode_add_ref(avctx, pic, pic, 0, 1, 0); | ||
| 1229 | if (pic->type != FF_HW_PICTURE_TYPE_IDR) { | ||
| 1230 | // TODO: apply both previous and forward multi reference for all vaapi encoders. | ||
| 1231 | // And L0/L1 reference frame number can be set dynamically through query | ||
| 1232 | // VAConfigAttribEncMaxRefFrames attribute. | ||
| 1233 | if (avctx->codec_id == AV_CODEC_ID_AV1) { | ||
| 1234 | for (i = 0; i < ctx->nb_next_prev; i++) | ||
| 1235 | vaapi_encode_add_ref(avctx, pic, ctx->next_prev[i], | ||
| 1236 | pic->type == FF_HW_PICTURE_TYPE_P, | ||
| 1237 | b_counter > 0, 0); | ||
| 1238 | } else | ||
| 1239 | vaapi_encode_add_ref(avctx, pic, start, | ||
| 1240 | pic->type == FF_HW_PICTURE_TYPE_P, | ||
| 1241 | b_counter > 0, 0); | ||
| 1242 | |||
| 1243 | vaapi_encode_add_ref(avctx, pic, ctx->next_prev[ctx->nb_next_prev - 1], 0, 0, 1); | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | if (b_counter > 0) { | ||
| 1247 | vaapi_encode_set_b_pictures(avctx, start, pic, pic, 1, | ||
| 1248 | &prev); | ||
| 1249 | } else { | ||
| 1250 | prev = pic; | ||
| 1251 | } | ||
| 1252 | vaapi_encode_add_next_prev(avctx, prev); | ||
| 1253 | |||
| 1254 | return 0; | ||
| 1255 | } | ||
| 1256 | |||
| 1257 | static int vaapi_encode_clear_old(AVCodecContext *avctx) | ||
| 1258 | { | ||
| 1259 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1260 | VAAPIEncodePicture *pic, *prev, *next; | ||
| 1261 | |||
| 1262 | av_assert0(ctx->pic_start); | ||
| 1263 | |||
| 1264 | // Remove direct references once each picture is complete. | ||
| 1265 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 1266 | if (pic->encode_complete && pic->next) | ||
| 1267 | vaapi_encode_remove_refs(avctx, pic, 0); | ||
| 1268 | } | ||
| 1269 | |||
| 1270 | // Remove indirect references once a picture has no direct references. | ||
| 1271 | for (pic = ctx->pic_start; pic; pic = pic->next) { | ||
| 1272 | if (pic->encode_complete && pic->ref_count[0] == 0) | ||
| 1273 | vaapi_encode_remove_refs(avctx, pic, 1); | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | // Clear out all complete pictures with no remaining references. | ||
| 1277 | prev = NULL; | ||
| 1278 | for (pic = ctx->pic_start; pic; pic = next) { | ||
| 1279 | next = pic->next; | ||
| 1280 | if (pic->encode_complete && pic->ref_count[1] == 0) { | ||
| 1281 | av_assert0(pic->ref_removed[0] && pic->ref_removed[1]); | ||
| 1282 | if (prev) | ||
| 1283 | prev->next = next; | ||
| 1284 | else | ||
| 1285 | ctx->pic_start = next; | ||
| 1286 | vaapi_encode_free(avctx, pic); | ||
| 1287 | } else { | ||
| 1288 | prev = pic; | ||
| 1289 | } | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | return 0; | ||
| 1293 | } | ||
| 1294 | |||
| 1295 | static int vaapi_encode_check_frame(AVCodecContext *avctx, | ||
| 1296 | const AVFrame *frame) | ||
| 1297 | { | ||
| 1298 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1299 | |||
| 1300 | if ((frame->crop_top || frame->crop_bottom || | ||
| 1301 | frame->crop_left || frame->crop_right) && !ctx->crop_warned) { | ||
| 1302 | av_log(avctx, AV_LOG_WARNING, "Cropping information on input " | ||
| 1303 | "frames ignored due to lack of API support.\n"); | ||
| 1304 | ctx->crop_warned = 1; | ||
| 1305 | } | ||
| 1306 | |||
| 1307 | if (!ctx->roi_allowed) { | ||
| 1308 | AVFrameSideData *sd = | ||
| 1309 | av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST); | ||
| 1310 | |||
| 1311 | if (sd && !ctx->roi_warned) { | ||
| 1312 | av_log(avctx, AV_LOG_WARNING, "ROI side data on input " | ||
| 1313 | "frames ignored due to lack of driver support.\n"); | ||
| 1314 | ctx->roi_warned = 1; | ||
| 1315 | } | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | return 0; | ||
| 1319 | } | ||
| 1320 | |||
| 1321 | static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame) | ||
| 1322 | { | ||
| 1323 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 1324 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1325 | VAAPIEncodePicture *pic; | ||
| 1326 | int err; | ||
| 1327 | |||
| 1328 | if (frame) { | ||
| 1329 | av_log(avctx, AV_LOG_DEBUG, "Input frame: %ux%u (%"PRId64").\n", | ||
| 1330 | frame->width, frame->height, frame->pts); | ||
| 1331 | |||
| 1332 | err = vaapi_encode_check_frame(avctx, frame); | ||
| 1333 | if (err < 0) | ||
| 1334 | return err; | ||
| 1335 | |||
| 1336 | pic = vaapi_encode_alloc(avctx, frame); | ||
| 1337 | if (!pic) | ||
| 1338 | return AVERROR(ENOMEM); | ||
| 1339 | |||
| 1340 | pic->input_image = av_frame_alloc(); | ||
| 1341 | if (!pic->input_image) { | ||
| 1342 | err = AVERROR(ENOMEM); | ||
| 1343 | goto fail; | ||
| 1344 | } | ||
| 1345 | |||
| 1346 | if (ctx->input_order == 0 || frame->pict_type == AV_PICTURE_TYPE_I) | ||
| 1347 | pic->force_idr = 1; | ||
| 1348 | |||
| 1349 | pic->pts = frame->pts; | ||
| 1350 | pic->duration = frame->duration; | ||
| 1351 | |||
| 1352 | if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { | ||
| 1353 | err = av_buffer_replace(&pic->opaque_ref, frame->opaque_ref); | ||
| 1354 | if (err < 0) | ||
| 1355 | goto fail; | ||
| 1356 | |||
| 1357 | pic->opaque = frame->opaque; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | av_frame_move_ref(pic->input_image, frame); | ||
| 1361 | |||
| 1362 | if (ctx->input_order == 0) | ||
| 1363 | ctx->first_pts = pic->pts; | ||
| 1364 | if (ctx->input_order == ctx->decode_delay) | ||
| 1365 | ctx->dts_pts_diff = pic->pts - ctx->first_pts; | ||
| 1366 | if (ctx->output_delay > 0) | ||
| 1367 | ctx->ts_ring[ctx->input_order % | ||
| 1368 | (3 * ctx->output_delay + base_ctx->async_depth)] = pic->pts; | ||
| 1369 | |||
| 1370 | pic->display_order = ctx->input_order; | ||
| 1371 | ++ctx->input_order; | ||
| 1372 | |||
| 1373 | if (ctx->pic_start) { | ||
| 1374 | ctx->pic_end->next = pic; | ||
| 1375 | ctx->pic_end = pic; | ||
| 1376 | } else { | ||
| 1377 | ctx->pic_start = pic; | ||
| 1378 | ctx->pic_end = pic; | ||
| 1379 | } | ||
| 1380 | |||
| 1381 | } else { | ||
| 1382 | ctx->end_of_stream = 1; | ||
| 1383 | |||
| 1384 | // Fix timestamps if we hit end-of-stream before the initial decode | ||
| 1385 | // delay has elapsed. | ||
| 1386 | if (ctx->input_order < ctx->decode_delay) | ||
| 1387 | ctx->dts_pts_diff = ctx->pic_end->pts - ctx->first_pts; | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | return 0; | ||
| 1391 | |||
| 1392 | fail: | ||
| 1393 | vaapi_encode_free(avctx, pic); | ||
| 1394 | return err; | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt) | ||
| 1398 | { | ||
| 1399 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 1400 | VAAPIEncodePicture *pic = NULL; | ||
| 1401 | AVFrame *frame = ctx->frame; | ||
| 1402 | int err; | ||
| 1403 | |||
| 1404 | start: | ||
| 1405 | /** if no B frame before repeat P frame, sent repeat P frame out. */ | ||
| 1406 | if (ctx->tail_pkt->size) { | ||
| 1407 | for (VAAPIEncodePicture *tmp = ctx->pic_start; tmp; tmp = tmp->next) { | ||
| 1408 | if (tmp->type == FF_HW_PICTURE_TYPE_B && tmp->pts < ctx->tail_pkt->pts) | ||
| 1409 | break; | ||
| 1410 | else if (!tmp->next) { | ||
| 1411 | av_packet_move_ref(pkt, ctx->tail_pkt); | ||
| 1412 | goto end; | ||
| 1413 | } | ||
| 1414 | } | ||
| 1415 | } | ||
| 1416 | |||
| 1417 | err = ff_encode_get_frame(avctx, frame); | ||
| 1418 | if (err < 0 && err != AVERROR_EOF) | ||
| 1419 | return err; | ||
| 1420 | |||
| 1421 | if (err == AVERROR_EOF) | ||
| 1422 | frame = NULL; | ||
| 1423 | |||
| 1424 | err = vaapi_encode_send_frame(avctx, frame); | ||
| 1425 | if (err < 0) | ||
| 1426 | return err; | ||
| 1427 | |||
| 1428 | if (!ctx->pic_start) { | ||
| 1429 | if (ctx->end_of_stream) | ||
| 1430 | return AVERROR_EOF; | ||
| 1431 | else | ||
| 1432 | return AVERROR(EAGAIN); | ||
| 1433 | } | ||
| 1434 | |||
| 1435 | if (ctx->has_sync_buffer_func) { | ||
| 1436 | if (av_fifo_can_write(ctx->encode_fifo)) { | ||
| 1437 | err = vaapi_encode_pick_next(avctx, &pic); | ||
| 1438 | if (!err) { | ||
| 1439 | av_assert0(pic); | ||
| 1440 | pic->encode_order = ctx->encode_order + | ||
| 1441 | av_fifo_can_read(ctx->encode_fifo); | ||
| 1442 | err = vaapi_encode_issue(avctx, pic); | ||
| 1443 | if (err < 0) { | ||
| 1444 | av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err); | ||
| 1445 | return err; | ||
| 1446 | } | ||
| 1447 | av_fifo_write(ctx->encode_fifo, &pic, 1); | ||
| 1448 | } | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | if (!av_fifo_can_read(ctx->encode_fifo)) | ||
| 1452 | return err; | ||
| 1453 | |||
| 1454 | // More frames can be buffered | ||
| 1455 | if (av_fifo_can_write(ctx->encode_fifo) && !ctx->end_of_stream) | ||
| 1456 | return AVERROR(EAGAIN); | ||
| 1457 | |||
| 1458 | av_fifo_read(ctx->encode_fifo, &pic, 1); | ||
| 1459 | ctx->encode_order = pic->encode_order + 1; | ||
| 1460 | } else { | ||
| 1461 | err = vaapi_encode_pick_next(avctx, &pic); | ||
| 1462 | if (err < 0) | ||
| 1463 | return err; | ||
| 1464 | av_assert0(pic); | ||
| 1465 | |||
| 1466 | pic->encode_order = ctx->encode_order++; | ||
| 1467 | |||
| 1468 | err = vaapi_encode_issue(avctx, pic); | ||
| 1469 | if (err < 0) { | ||
| 1470 | av_log(avctx, AV_LOG_ERROR, "Encode failed: %d.\n", err); | ||
| 1471 | return err; | ||
| 1472 | } | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | err = vaapi_encode_output(avctx, pic, pkt); | ||
| 1476 | if (err < 0) { | ||
| 1477 | av_log(avctx, AV_LOG_ERROR, "Output failed: %d.\n", err); | ||
| 1478 | return err; | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | ctx->output_order = pic->encode_order; | ||
| 1482 | vaapi_encode_clear_old(avctx); | ||
| 1483 | |||
| 1484 | /** loop to get an available pkt in encoder flushing. */ | ||
| 1485 | if (ctx->end_of_stream && !pkt->size) | ||
| 1486 | goto start; | ||
| 1487 | |||
| 1488 | end: | ||
| 1489 | if (pkt->size) | ||
| 1490 | av_log(avctx, AV_LOG_DEBUG, "Output packet: pts %"PRId64", dts %"PRId64", " | ||
| 1491 | "size %d bytes.\n", pkt->pts, pkt->dts, pkt->size); | ||
| 1492 | |||
| 1493 | return 0; | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type, | 940 | static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type, |
| 1497 | void *buffer, size_t size) | 941 | void *buffer, size_t size) |
| 1498 | { | 942 | { |
| @@ -2188,7 +1632,8 @@ static av_cold int vaapi_encode_init_max_frame_size(AVCodecContext *avctx) · 689 unmodified lines | |||
| 2188 | 1632 | ||
| 2189 | static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) | 1633 | static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) |
| 2190 | { | 1634 | { |
| 2191 | VAAPIEncodeContext *ctx = avctx->priv_data; | 1635 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 1636 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 2192 | VAStatus vas; | 1637 | VAStatus vas; |
| 2193 | VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames }; | 1638 | VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames }; |
| 2194 | uint32_t ref_l0, ref_l1; | 1639 | uint32_t ref_l0, ref_l1; |
| @@ -2211,7 +1656,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 16 unmodified lines | |||
| 2211 | ref_l1 = attr.value >> 16 & 0xffff; | 1656 | ref_l1 = attr.value >> 16 & 0xffff; |
| 2212 | } | 1657 | } |
| 2213 | 1658 | ||
| 2214 | ctx->p_to_gpb = 0; | 1659 | base_ctx->p_to_gpb = 0; |
| 2215 | prediction_pre_only = 0; | 1660 | prediction_pre_only = 0; |
| 2216 | 1661 | ||
| 2217 | #if VA_CHECK_VERSION(1, 9, 0) | 1662 | #if VA_CHECK_VERSION(1, 9, 0) |
| @@ -2247,7 +1692,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 29 unmodified lines | |||
| 2247 | 1692 | ||
| 2248 | if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) { | 1693 | if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) { |
| 2249 | if (ref_l0 > 0 && ref_l1 > 0) { | 1694 | if (ref_l0 > 0 && ref_l1 > 0) { |
| 2250 | ctx->p_to_gpb = 1; | 1695 | base_ctx->p_to_gpb = 1; |
| 2251 | av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, " | 1696 | av_log(avctx, AV_LOG_VERBOSE, "Driver does not support P-frames, " |
| 2252 | "replacing them with B-frames.\n"); | 1697 | "replacing them with B-frames.\n"); |
| 2253 | } | 1698 | } |
| @@ -2259,7 +1704,7 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 5 unmodified lines | |||
| 2259 | if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY || | 1704 | if (ctx->codec->flags & FF_HW_FLAG_INTRA_ONLY || |
| 2260 | avctx->gop_size <= 1) { | 1705 | avctx->gop_size <= 1) { |
| 2261 | av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n"); | 1706 | av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n"); |
| 2262 | ctx->gop_size = 1; | 1707 | base_ctx->gop_size = 1; |
| 2263 | } else if (ref_l0 < 1) { | 1708 | } else if (ref_l0 < 1) { |
| 2264 | av_log(avctx, AV_LOG_ERROR, "Driver does not support any " | 1709 | av_log(avctx, AV_LOG_ERROR, "Driver does not support any " |
| 2265 | "reference frames.\n"); | 1710 | "reference frames.\n"); |
| @@ -2267,41 +1712,41 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 1 unmodified line | |||
| 2267 | } else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) || | 1712 | } else if (!(ctx->codec->flags & FF_HW_FLAG_B_PICTURES) || |
| 2268 | ref_l1 < 1 || avctx->max_b_frames < 1 || | 1713 | ref_l1 < 1 || avctx->max_b_frames < 1 || |
| 2269 | prediction_pre_only) { | 1714 | prediction_pre_only) { |
| 2270 | if (ctx->p_to_gpb) | 1715 | if (base_ctx->p_to_gpb) |
| 2271 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames " | 1716 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames " |
| 2272 | "(supported references: %d / %d).\n", | 1717 | "(supported references: %d / %d).\n", |
| 2273 | ref_l0, ref_l1); | 1718 | ref_l0, ref_l1); |
| 2274 | else | 1719 | else |
| 2275 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames " | 1720 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames " |
| 2276 | "(supported references: %d / %d).\n", ref_l0, ref_l1); | 1721 | "(supported references: %d / %d).\n", ref_l0, ref_l1); |
| 2277 | ctx->gop_size = avctx->gop_size; | 1722 | base_ctx->gop_size = avctx->gop_size; |
| 2278 | ctx->p_per_i = INT_MAX; | 1723 | base_ctx->p_per_i = INT_MAX; |
| 2279 | ctx->b_per_p = 0; | 1724 | base_ctx->b_per_p = 0; |
| 2280 | } else { | 1725 | } else { |
| 2281 | if (ctx->p_to_gpb) | 1726 | if (base_ctx->p_to_gpb) |
| 2282 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames " | 1727 | av_log(avctx, AV_LOG_VERBOSE, "Using intra and B-frames " |
| 2283 | "(supported references: %d / %d).\n", | 1728 | "(supported references: %d / %d).\n", |
| 2284 | ref_l0, ref_l1); | 1729 | ref_l0, ref_l1); |
| 2285 | else | 1730 | else |
| 2286 | av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " | 1731 | av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " |
| 2287 | "(supported references: %d / %d).\n", ref_l0, ref_l1); | 1732 | "(supported references: %d / %d).\n", ref_l0, ref_l1); |
| 2288 | ctx->gop_size = avctx->gop_size; | 1733 | base_ctx->gop_size = avctx->gop_size; |
| 2289 | ctx->p_per_i = INT_MAX; | 1734 | base_ctx->p_per_i = INT_MAX; |
| 2290 | ctx->b_per_p = avctx->max_b_frames; | 1735 | base_ctx->b_per_p = avctx->max_b_frames; |
| 2291 | if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) { | 1736 | if (ctx->codec->flags & FF_HW_FLAG_B_PICTURE_REFERENCES) { |
| 2292 | ctx->max_b_depth = FFMIN(ctx->desired_b_depth, | 1737 | base_ctx->max_b_depth = FFMIN(ctx->desired_b_depth, |
| 2293 | av_log2(ctx->b_per_p) + 1); | 1738 | av_log2(base_ctx->b_per_p) + 1); |
| 2294 | } else { | 1739 | } else { |
| 2295 | ctx->max_b_depth = 1; | 1740 | base_ctx->max_b_depth = 1; |
| 2296 | } | 1741 | } |
| 2297 | } | 1742 | } |
| 2298 | 1743 | ||
| 2299 | if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) { | 1744 | if (ctx->codec->flags & FF_HW_FLAG_NON_IDR_KEY_PICTURES) { |
| 2300 | ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP); | 1745 | base_ctx->closed_gop = !!(avctx->flags & AV_CODEC_FLAG_CLOSED_GOP); |
| 2301 | ctx->gop_per_idr = ctx->idr_interval + 1; | 1746 | base_ctx->gop_per_idr = ctx->idr_interval + 1; |
| 2302 | } else { | 1747 | } else { |
| 2303 | ctx->closed_gop = 1; | 1748 | base_ctx->closed_gop = 1; |
| 2304 | ctx->gop_per_idr = 1; | 1749 | base_ctx->gop_per_idr = 1; |
| 2305 | } | 1750 | } |
| 2306 | 1751 | ||
| 2307 | return 0; | 1752 | return 0; |
| @@ -2614,7 +2059,8 @@ static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) · 306 unmodified lines | |||
| 2614 | static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx) | 2059 | static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx) |
| 2615 | { | 2060 | { |
| 2616 | #if VA_CHECK_VERSION(1, 0, 0) | 2061 | #if VA_CHECK_VERSION(1, 0, 0) |
| 2617 | VAAPIEncodeContext *ctx = avctx->priv_data; | 2062 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 2063 | VAAPIEncodeContext *ctx = avctx->priv_data; | ||
| 2618 | VAStatus vas; | 2064 | VAStatus vas; |
| 2619 | VAConfigAttrib attr = { VAConfigAttribEncROI }; | 2065 | VAConfigAttrib attr = { VAConfigAttribEncROI }; |
| 2620 | 2066 | ||
| @@ -2629,14 +2075,14 @@ static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx) · 8 unmodified lines | |||
| 2629 | } | 2075 | } |
| 2630 | 2076 | ||
| 2631 | if (attr.value == VA_ATTRIB_NOT_SUPPORTED) { | 2077 | if (attr.value == VA_ATTRIB_NOT_SUPPORTED) { |
| 2632 | ctx->roi_allowed = 0; | 2078 | base_ctx->roi_allowed = 0; |
| 2633 | } else { | 2079 | } else { |
| 2634 | VAConfigAttribValEncROI roi = { | 2080 | VAConfigAttribValEncROI roi = { |
| 2635 | .value = attr.value, | 2081 | .value = attr.value, |
| 2636 | }; | 2082 | }; |
| 2637 | 2083 | ||
| 2638 | ctx->roi_max_regions = roi.bits.num_roi_regions; | 2084 | ctx->roi_max_regions = roi.bits.num_roi_regions; |
| 2639 | ctx->roi_allowed = ctx->roi_max_regions > 0 && | 2085 | base_ctx->roi_allowed = ctx->roi_max_regions > 0 && |
| 2640 | (ctx->va_rc_mode == VA_RC_CQP || | 2086 | (ctx->va_rc_mode == VA_RC_CQP || |
| 2641 | roi.bits.roi_rc_qp_delta_support); | 2087 | roi.bits.roi_rc_qp_delta_support); |
| 2642 | } | 2088 | } |
| @@ -2771,6 +2217,16 @@ static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) · 128 unmodified lines | |||
| 2771 | return err; | 2217 | return err; |
| 2772 | } | 2218 | } |
| 2773 | 2219 | ||
| 2220 | static const FFHWEncodePictureOperation vaapi_op = { | ||
| 2221 | .alloc = &vaapi_encode_alloc, | ||
| 2222 | |||
| 2223 | .issue = &vaapi_encode_issue, | ||
| 2224 | |||
| 2225 | .output = &vaapi_encode_output, | ||
| 2226 | |||
| 2227 | .free = &vaapi_encode_free, | ||
| 2228 | }; | ||
| 2229 | |||
| 2774 | av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) | 2230 | av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) |
| 2775 | { | 2231 | { |
| 2776 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | 2232 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| @@ -2782,10 +2238,12 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 5 unmodified lines | |||
| 2782 | ctx->va_config = VA_INVALID_ID; | 2238 | ctx->va_config = VA_INVALID_ID; |
| 2783 | ctx->va_context = VA_INVALID_ID; | 2239 | ctx->va_context = VA_INVALID_ID; |
| 2784 | 2240 | ||
| 2241 | base_ctx->op = &vaapi_op; | ||
| 2242 | |||
| 2785 | /* If you add something that can fail above this av_frame_alloc(), | 2243 | /* If you add something that can fail above this av_frame_alloc(), |
| 2786 | * modify ff_vaapi_encode_close() accordingly. */ | 2244 | * modify ff_vaapi_encode_close() accordingly. */ |
| 2787 | ctx->frame = av_frame_alloc(); | 2245 | base_ctx->frame = av_frame_alloc(); |
| 2788 | if (!ctx->frame) { | 2246 | if (!base_ctx->frame) { |
| 2789 | return AVERROR(ENOMEM); | 2247 | return AVERROR(ENOMEM); |
| 2790 | } | 2248 | } |
| 2791 | 2249 | ||
| @@ -2810,8 +2268,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 18 unmodified lines | |||
| 2810 | ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; | 2268 | ctx->device = (AVHWDeviceContext*)ctx->device_ref->data; |
| 2811 | ctx->hwctx = ctx->device->hwctx; | 2269 | ctx->hwctx = ctx->device->hwctx; |
| 2812 | 2270 | ||
| 2813 | ctx->tail_pkt = av_packet_alloc(); | 2271 | base_ctx->tail_pkt = av_packet_alloc(); |
| 2814 | if (!ctx->tail_pkt) { | 2272 | if (!base_ctx->tail_pkt) { |
| 2815 | err = AVERROR(ENOMEM); | 2273 | err = AVERROR(ENOMEM); |
| 2816 | goto fail; | 2274 | goto fail; |
| 2817 | } | 2275 | } |
| @@ -2910,8 +2368,8 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 92 unmodified lines | |||
| 2910 | goto fail; | 2368 | goto fail; |
| 2911 | } | 2369 | } |
| 2912 | 2370 | ||
| 2913 | ctx->output_delay = ctx->b_per_p; | 2371 | base_ctx->output_delay = base_ctx->b_per_p; |
| 2914 | ctx->decode_delay = ctx->max_b_depth; | 2372 | base_ctx->decode_delay = base_ctx->max_b_depth; |
| 2915 | 2373 | ||
| 2916 | if (ctx->codec->sequence_params_size > 0) { | 2374 | if (ctx->codec->sequence_params_size > 0) { |
| 2917 | ctx->codec_sequence_params = | 2375 | ctx->codec_sequence_params = |
| @@ -2966,11 +2424,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) · 48 unmodified lines | |||
| 2966 | // check vaSyncBuffer function | 2424 | // check vaSyncBuffer function |
| 2967 | vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0); | 2425 | vas = vaSyncBuffer(ctx->hwctx->display, VA_INVALID_ID, 0); |
| 2968 | if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) { | 2426 | if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) { |
| 2969 | ctx->has_sync_buffer_func = 1; | 2427 | base_ctx->async_encode = 1; |
| 2970 | ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth, | 2428 | base_ctx->encode_fifo = av_fifo_alloc2(base_ctx->async_depth, |
| 2971 | sizeof(VAAPIEncodePicture *), | 2429 | sizeof(VAAPIEncodePicture*), |
| 2972 | 0); | 2430 | 0); |
| 2973 | if (!ctx->encode_fifo) | 2431 | if (!base_ctx->encode_fifo) |
| 2974 | return AVERROR(ENOMEM); | 2432 | return AVERROR(ENOMEM); |
| 2975 | } | 2433 | } |
| 2976 | #endif | 2434 | #endif |
| @@ -2983,15 +2441,16 @@ fail: · 6 unmodified lines | |||
| 2983 | 2441 | ||
| 2984 | av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) | 2442 | av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) |
| 2985 | { | 2443 | { |
| 2986 | VAAPIEncodeContext *ctx = avctx->priv_data; | 2444 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 2987 | VAAPIEncodePicture *pic, *next; | 2445 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 2446 | FFHWBaseEncodePicture *pic, *next; | ||
| 2988 | 2447 | ||
| 2989 | /* We check ctx->frame to know whether ff_vaapi_encode_init() | 2448 | /* We check ctx->frame to know whether ff_vaapi_encode_init() |
| 2990 | * has been called and va_config/va_context initialized. */ | 2449 | * has been called and va_config/va_context initialized. */ |
| 2991 | if (!ctx->frame) | 2450 | if (!base_ctx->frame) |
| 2992 | return 0; | 2451 | return 0; |
| 2993 | 2452 | ||
| 2994 | for (pic = ctx->pic_start; pic; pic = next) { | 2453 | for (pic = base_ctx->pic_start; pic; pic = next) { |
| 2995 | next = pic->next; | 2454 | next = pic->next; |
| 2996 | vaapi_encode_free(avctx, pic); | 2455 | vaapi_encode_free(avctx, pic); |
| 2997 | } | 2456 | } |
| @@ -3008,12 +2467,12 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) · 10 unmodified lines | |||
| 3008 | ctx->va_config = VA_INVALID_ID; | 2467 | ctx->va_config = VA_INVALID_ID; |
| 3009 | } | 2468 | } |
| 3010 | 2469 | ||
| 3011 | av_frame_free(&ctx->frame); | 2470 | av_frame_free(&base_ctx->frame); |
| 3012 | av_packet_free(&ctx->tail_pkt); | 2471 | av_packet_free(&base_ctx->tail_pkt); |
| 3013 | 2472 | ||
| 3014 | av_freep(&ctx->codec_sequence_params); | 2473 | av_freep(&ctx->codec_sequence_params); |
| 3015 | av_freep(&ctx->codec_picture_params); | 2474 | av_freep(&ctx->codec_picture_params); |
| 3016 | av_fifo_freep2(&ctx->encode_fifo); | 2475 | av_fifo_freep2(&base_ctx->encode_fifo); |
| 3017 | 2476 | ||
| 3018 | av_buffer_unref(&ctx->recon_frames_ref); | 2477 | av_buffer_unref(&ctx->recon_frames_ref); |
| 3019 | av_buffer_unref(&ctx->input_frames_ref); | 2478 | av_buffer_unref(&ctx->input_frames_ref); |
| @@ -29,7 +29,6 @@ · 28 unmodified lines | |||
| 29 | 29 | ||
| 30 | #include "libavutil/hwcontext.h" | 30 | #include "libavutil/hwcontext.h" |
| 31 | #include "libavutil/hwcontext_vaapi.h" | 31 | #include "libavutil/hwcontext_vaapi.h" |
| 32 | #include "libavutil/fifo.h" | ||
| 33 | 32 | ||
| 34 | #include "avcodec.h" | 33 | #include "avcodec.h" |
| 35 | #include "hwconfig.h" | 34 | #include "hwconfig.h" |
| @@ -64,16 +63,7 @@ typedef struct VAAPIEncodeSlice { · 28 unmodified lines | |||
| 64 | } VAAPIEncodeSlice; | 63 | } VAAPIEncodeSlice; |
| 65 | 64 | ||
| 66 | typedef struct VAAPIEncodePicture { | 65 | typedef struct VAAPIEncodePicture { |
| 67 | struct VAAPIEncodePicture *next; | 66 | FFHWBaseEncodePicture base; |
| 68 | |||
| 69 | int64_t display_order; | ||
| 70 | int64_t encode_order; | ||
| 71 | int64_t pts; | ||
| 72 | int64_t duration; | ||
| 73 | int force_idr; | ||
| 74 | |||
| 75 | void *opaque; | ||
| 76 | AVBufferRef *opaque_ref; | ||
| 77 | 67 | ||
| 78 | #if VA_CHECK_VERSION(1, 0, 0) | 68 | #if VA_CHECK_VERSION(1, 0, 0) |
| 79 | // ROI regions. | 69 | // ROI regions. |
| @@ -82,15 +72,7 @@ typedef struct VAAPIEncodePicture { · 2 unmodified lines | |||
| 82 | void *roi; | 72 | void *roi; |
| 83 | #endif | 73 | #endif |
| 84 | 74 | ||
| 85 | int type; | ||
| 86 | int b_depth; | ||
| 87 | int encode_issued; | ||
| 88 | int encode_complete; | ||
| 89 | |||
| 90 | AVFrame *input_image; | ||
| 91 | VASurfaceID input_surface; | 75 | VASurfaceID input_surface; |
| 92 | |||
| 93 | AVFrame *recon_image; | ||
| 94 | VASurfaceID recon_surface; | 76 | VASurfaceID recon_surface; |
| 95 | 77 | ||
| 96 | int nb_param_buffers; | 78 | int nb_param_buffers; |
| @@ -100,31 +82,8 @@ typedef struct VAAPIEncodePicture { · 3 unmodified lines | |||
| 100 | VABufferID *output_buffer_ref; | 82 | VABufferID *output_buffer_ref; |
| 101 | VABufferID output_buffer; | 83 | VABufferID output_buffer; |
| 102 | 84 | ||
| 103 | void *priv_data; | ||
| 104 | void *codec_picture_params; | 85 | void *codec_picture_params; |
| 105 | 86 | ||
| 106 | // Whether this picture is a reference picture. | ||
| 107 | int is_reference; | ||
| 108 | |||
| 109 | // The contents of the DPB after this picture has been decoded. | ||
| 110 | // This will contain the picture itself if it is a reference picture, | ||
| 111 | // but not if it isn't. | ||
| 112 | int nb_dpb_pics; | ||
| 113 | struct VAAPIEncodePicture *dpb[MAX_DPB_SIZE]; | ||
| 114 | // The reference pictures used in decoding this picture. If they are | ||
| 115 | // used by later pictures they will also appear in the DPB. ref[0][] for | ||
| 116 | // previous reference frames. ref[1][] for future reference frames. | ||
| 117 | int nb_refs[MAX_REFERENCE_LIST_NUM]; | ||
| 118 | struct VAAPIEncodePicture *refs[MAX_REFERENCE_LIST_NUM][MAX_PICTURE_REFERENCES]; | ||
| 119 | // The previous reference picture in encode order. Must be in at least | ||
| 120 | // one of the reference list and DPB list. | ||
| 121 | struct VAAPIEncodePicture *prev; | ||
| 122 | // Reference count for other pictures referring to this one through | ||
| 123 | // the above pointers, directly from incomplete pictures and indirectly | ||
| 124 | // through completed pictures. | ||
| 125 | int ref_count[2]; | ||
| 126 | int ref_removed[2]; | ||
| 127 | |||
| 128 | int nb_slices; | 87 | int nb_slices; |
| 129 | VAAPIEncodeSlice *slices; | 88 | VAAPIEncodeSlice *slices; |
| 130 | 89 | ||
| @@ -298,30 +257,6 @@ typedef struct VAAPIEncodeContext { · 167 unmodified lines | |||
| 298 | // structure (VAEncPictureParameterBuffer*). | 257 | // structure (VAEncPictureParameterBuffer*). |
| 299 | void *codec_picture_params; | 258 | void *codec_picture_params; |
| 300 | 259 | ||
| 301 | // Current encoding window, in display (input) order. | ||
| 302 | VAAPIEncodePicture *pic_start, *pic_end; | ||
| 303 | // The next picture to use as the previous reference picture in | ||
| 304 | // encoding order. Order from small to large in encoding order. | ||
| 305 | VAAPIEncodePicture *next_prev[MAX_PICTURE_REFERENCES]; | ||
| 306 | int nb_next_prev; | ||
| 307 | |||
| 308 | // Next input order index (display order). | ||
| 309 | int64_t input_order; | ||
| 310 | // Number of frames that output is behind input. | ||
| 311 | int64_t output_delay; | ||
| 312 | // Next encode order index. | ||
| 313 | int64_t encode_order; | ||
| 314 | // Number of frames decode output will need to be delayed. | ||
| 315 | int64_t decode_delay; | ||
| 316 | // Next output order index (in encode order). | ||
| 317 | int64_t output_order; | ||
| 318 | |||
| 319 | // Timestamp handling. | ||
| 320 | int64_t first_pts; | ||
| 321 | int64_t dts_pts_diff; | ||
| 322 | int64_t ts_ring[MAX_REORDER_DELAY * 3 + | ||
| 323 | MAX_ASYNC_DEPTH]; | ||
| 324 | |||
| 325 | // Slice structure. | 260 | // Slice structure. |
| 326 | int slice_block_rows; | 261 | int slice_block_rows; |
| 327 | int slice_block_cols; | 262 | int slice_block_cols; |
| @@ -340,41 +275,12 @@ typedef struct VAAPIEncodeContext { · 12 unmodified lines | |||
| 340 | // Location of the i-th tile row boundary. | 275 | // Location of the i-th tile row boundary. |
| 341 | int row_bd[MAX_TILE_ROWS + 1]; | 276 | int row_bd[MAX_TILE_ROWS + 1]; |
| 342 | 277 | ||
| 343 | // Frame type decision. | ||
| 344 | int gop_size; | ||
| 345 | int closed_gop; | ||
| 346 | int gop_per_idr; | ||
| 347 | int p_per_i; | ||
| 348 | int max_b_depth; | ||
| 349 | int b_per_p; | ||
| 350 | int force_idr; | ||
| 351 | int idr_counter; | ||
| 352 | int gop_counter; | ||
| 353 | int end_of_stream; | ||
| 354 | int p_to_gpb; | ||
| 355 | |||
| 356 | // Whether the driver supports ROI at all. | ||
| 357 | int roi_allowed; | ||
| 358 | // Maximum number of regions supported by the driver. | 278 | // Maximum number of regions supported by the driver. |
| 359 | int roi_max_regions; | 279 | int roi_max_regions; |
| 360 | // Quantisation range for offset calculations. Set by codec-specific | 280 | // Quantisation range for offset calculations. Set by codec-specific |
| 361 | // code, as it may change based on parameters. | 281 | // code, as it may change based on parameters. |
| 362 | int roi_quant_range; | 282 | int roi_quant_range; |
| 363 | 283 | ||
| 364 | // The encoder does not support cropping information, so warn about | ||
| 365 | // it the first time we encounter any nonzero crop fields. | ||
| 366 | int crop_warned; | ||
| 367 | // If the driver does not support ROI then warn the first time we | ||
| 368 | // encounter a frame with ROI side data. | ||
| 369 | int roi_warned; | ||
| 370 | |||
| 371 | AVFrame *frame; | ||
| 372 | |||
| 373 | // Whether the driver support vaSyncBuffer | ||
| 374 | int has_sync_buffer_func; | ||
| 375 | // Store buffered pic | ||
| 376 | AVFifo *encode_fifo; | ||
| 377 | |||
| 378 | /** Head data for current output pkt, used only for AV1. */ | 284 | /** Head data for current output pkt, used only for AV1. */ |
| 379 | //void *header_data; | 285 | //void *header_data; |
| 380 | //size_t header_data_size; | 286 | //size_t header_data_size; |
| @@ -384,9 +290,6 @@ typedef struct VAAPIEncodeContext { · 3 unmodified lines | |||
| 384 | * This is a RefStruct reference. | 290 | * This is a RefStruct reference. |
| 385 | */ | 291 | */ |
| 386 | VABufferID *coded_buffer_ref; | 292 | VABufferID *coded_buffer_ref; |
| 387 | |||
| 388 | /** Tail data of a pic, now only used for av1 repeat frame header. */ | ||
| 389 | AVPacket *tail_pkt; | ||
| 390 | } VAAPIEncodeContext; | 293 | } VAAPIEncodeContext; |
| 391 | 294 | ||
| 392 | typedef struct VAAPIEncodeType { | 295 | typedef struct VAAPIEncodeType { |
| @@ -468,9 +371,6 @@ typedef struct VAAPIEncodeType { · 75 unmodified lines | |||
| 468 | char *data, size_t *data_len); | 371 | char *data, size_t *data_len); |
| 469 | } VAAPIEncodeType; | 372 | } VAAPIEncodeType; |
| 470 | 373 | ||
| 471 | |||
| 472 | int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt); | ||
| 473 | |||
| 474 | int ff_vaapi_encode_init(AVCodecContext *avctx); | 374 | int ff_vaapi_encode_init(AVCodecContext *avctx); |
| 475 | int ff_vaapi_encode_close(AVCodecContext *avctx); | 375 | int ff_vaapi_encode_close(AVCodecContext *avctx); |
| 476 | 376 | ||
| @@ -360,6 +360,7 @@ static int vaapi_encode_av1_write_sequence_header(AVCodecContext *avctx, · 359 unmodified lines | |||
| 360 | 360 | ||
| 361 | static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx) | 361 | static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx) |
| 362 | { | 362 | { |
| 363 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 363 | VAAPIEncodeContext *ctx = avctx->priv_data; | 364 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 364 | VAAPIEncodeAV1Context *priv = avctx->priv_data; | 365 | VAAPIEncodeAV1Context *priv = avctx->priv_data; |
| 365 | AV1RawOBU *sh_obu = &priv->sh; | 366 | AV1RawOBU *sh_obu = &priv->sh; |
| @@ -441,8 +442,8 @@ static int vaapi_encode_av1_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines | |||
| 441 | vseq->seq_level_idx = sh->seq_level_idx[0]; | 442 | vseq->seq_level_idx = sh->seq_level_idx[0]; |
| 442 | vseq->seq_tier = sh->seq_tier[0]; | 443 | vseq->seq_tier = sh->seq_tier[0]; |
| 443 | vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1; | 444 | vseq->order_hint_bits_minus_1 = sh->order_hint_bits_minus_1; |
| 444 | vseq->intra_period = ctx->gop_size; | 445 | vseq->intra_period = base_ctx->gop_size; |
| 445 | vseq->ip_period = ctx->b_per_p + 1; | 446 | vseq->ip_period = base_ctx->b_per_p + 1; |
| 446 | 447 | ||
| 447 | vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint; | 448 | vseq->seq_fields.bits.enable_order_hint = sh->enable_order_hint; |
| 448 | 449 | ||
| @@ -465,16 +466,17 @@ end: · 16 unmodified lines | |||
| 465 | } | 466 | } |
| 466 | 467 | ||
| 467 | static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, | 468 | static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, |
| 468 | VAAPIEncodePicture *pic) | 469 | VAAPIEncodePicture *vaapi_pic) |
| 469 | { | 470 | { |
| 470 | VAAPIEncodeContext *ctx = avctx->priv_data; | 471 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 471 | VAAPIEncodeAV1Context *priv = avctx->priv_data; | 472 | VAAPIEncodeAV1Context *priv = avctx->priv_data; |
| 473 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 472 | VAAPIEncodeAV1Picture *hpic = pic->priv_data; | 474 | VAAPIEncodeAV1Picture *hpic = pic->priv_data; |
| 473 | AV1RawOBU *fh_obu = &priv->fh; | 475 | AV1RawOBU *fh_obu = &priv->fh; |
| 474 | AV1RawFrameHeader *fh = &fh_obu->obu.frame.header; | 476 | AV1RawFrameHeader *fh = &fh_obu->obu.frame.header; |
| 475 | VAEncPictureParameterBufferAV1 *vpic = pic->codec_picture_params; | 477 | VAEncPictureParameterBufferAV1 *vpic = vaapi_pic->codec_picture_params; |
| 476 | CodedBitstreamFragment *obu = &priv->current_obu; | 478 | CodedBitstreamFragment *obu = &priv->current_obu; |
| 477 | VAAPIEncodePicture *ref; | 479 | FFHWBaseEncodePicture *ref; |
| 478 | VAAPIEncodeAV1Picture *href; | 480 | VAAPIEncodeAV1Picture *href; |
| 479 | int slot, i; | 481 | int slot, i; |
| 480 | int ret; | 482 | int ret; |
| @@ -482,8 +484,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 1 unmodified line | |||
| 482 | { 1, 0, 0, 0, -1, 0, -1, -1 }; | 484 | { 1, 0, 0, 0, -1, 0, -1, -1 }; |
| 483 | 485 | ||
| 484 | memset(fh_obu, 0, sizeof(*fh_obu)); | 486 | memset(fh_obu, 0, sizeof(*fh_obu)); |
| 485 | pic->nb_slices = priv->tile_groups; | 487 | vaapi_pic->nb_slices = priv->tile_groups; |
| 486 | pic->non_independent_frame = pic->encode_order < pic->display_order; | 488 | vaapi_pic->non_independent_frame = pic->encode_order < pic->display_order; |
| 487 | fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER; | 489 | fh_obu->header.obu_type = AV1_OBU_FRAME_HEADER; |
| 488 | fh_obu->header.obu_has_size_field = 1; | 490 | fh_obu->header.obu_has_size_field = 1; |
| 489 | 491 | ||
| @@ -601,8 +603,8 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 111 unmodified lines | |||
| 601 | vpic->frame_width_minus_1 = fh->frame_width_minus_1; | 603 | vpic->frame_width_minus_1 = fh->frame_width_minus_1; |
| 602 | vpic->frame_height_minus_1 = fh->frame_height_minus_1; | 604 | vpic->frame_height_minus_1 = fh->frame_height_minus_1; |
| 603 | vpic->primary_ref_frame = fh->primary_ref_frame; | 605 | vpic->primary_ref_frame = fh->primary_ref_frame; |
| 604 | vpic->reconstructed_frame = pic->recon_surface; | 606 | vpic->reconstructed_frame = vaapi_pic->recon_surface; |
| 605 | vpic->coded_buf = pic->output_buffer; | 607 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 606 | vpic->tile_cols = fh->tile_cols; | 608 | vpic->tile_cols = fh->tile_cols; |
| 607 | vpic->tile_rows = fh->tile_rows; | 609 | vpic->tile_rows = fh->tile_rows; |
| 608 | vpic->order_hint = fh->order_hint; | 610 | vpic->order_hint = fh->order_hint; |
| @@ -630,12 +632,12 @@ static int vaapi_encode_av1_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines | |||
| 630 | 632 | ||
| 631 | for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { | 633 | for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { |
| 632 | for (int j = 0; j < pic->nb_refs[i]; j++) { | 634 | for (int j = 0; j < pic->nb_refs[i]; j++) { |
| 633 | VAAPIEncodePicture *ref_pic = pic->refs[i][j]; | 635 | FFHWBaseEncodePicture *ref_pic = pic->refs[i][j]; |
| 634 | 636 | ||
| 635 | slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot; | 637 | slot = ((VAAPIEncodeAV1Picture*)ref_pic->priv_data)->slot; |
| 636 | av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); | 638 | av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); |
| 637 | 639 | ||
| 638 | vpic->reference_frames[slot] = ref_pic->recon_surface; | 640 | vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)->recon_surface; |
| 639 | } | 641 | } |
| 640 | } | 642 | } |
| 641 | 643 | ||
| @@ -752,7 +754,7 @@ static int vaapi_encode_av1_init_slice_params(AVCodecContext *avctx, · 110 unmodified lines | |||
| 752 | } | 754 | } |
| 753 | 755 | ||
| 754 | static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, | 756 | static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, |
| 755 | VAAPIEncodePicture *pic, | 757 | VAAPIEncodePicture *vaapi_pic, |
| 756 | char *data, size_t *data_len) | 758 | char *data, size_t *data_len) |
| 757 | { | 759 | { |
| 758 | VAAPIEncodeAV1Context *priv = avctx->priv_data; | 760 | VAAPIEncodeAV1Context *priv = avctx->priv_data; |
| @@ -760,10 +762,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 1 unmodified line | |||
| 760 | CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data; | 762 | CodedBitstreamAV1Context *cbctx = priv->cbc->priv_data; |
| 761 | AV1RawOBU *fh_obu = &priv->fh; | 763 | AV1RawOBU *fh_obu = &priv->fh; |
| 762 | AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header; | 764 | AV1RawFrameHeader *rep_fh = &fh_obu->obu.frame_header; |
| 765 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 763 | VAAPIEncodeAV1Picture *href; | 766 | VAAPIEncodeAV1Picture *href; |
| 764 | int ret = 0; | 767 | int ret = 0; |
| 765 | 768 | ||
| 766 | pic->tail_size = 0; | 769 | vaapi_pic->tail_size = 0; |
| 767 | /** Pack repeat frame header. */ | 770 | /** Pack repeat frame header. */ |
| 768 | if (pic->display_order > pic->encode_order) { | 771 | if (pic->display_order > pic->encode_order) { |
| 769 | memset(fh_obu, 0, sizeof(*fh_obu)); | 772 | memset(fh_obu, 0, sizeof(*fh_obu)); |
| @@ -785,11 +788,11 @@ static int vaapi_encode_av1_write_picture_header(AVCodecContext *avctx, · 15 unmodified lines | |||
| 785 | if (ret < 0) | 788 | if (ret < 0) |
| 786 | goto end; | 789 | goto end; |
| 787 | 790 | ||
| 788 | ret = vaapi_encode_av1_write_obu(avctx, pic->tail_data, &pic->tail_size, obu); | 791 | ret = vaapi_encode_av1_write_obu(avctx, vaapi_pic->tail_data, &vaapi_pic->tail_size, obu); |
| 789 | if (ret < 0) | 792 | if (ret < 0) |
| 790 | goto end; | 793 | goto end; |
| 791 | 794 | ||
| 792 | pic->tail_size /= 8; | 795 | vaapi_pic->tail_size /= 8; |
| 793 | } | 796 | } |
| 794 | 797 | ||
| 795 | memcpy(data, &priv->fh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char)); | 798 | memcpy(data, &priv->fh_data, MAX_PARAM_BUFFER_SIZE * sizeof(char)); |
| @@ -1038,7 +1041,7 @@ const FFCodec ff_av1_vaapi_encoder = { · 242 unmodified lines | |||
| 1038 | .p.id = AV_CODEC_ID_AV1, | 1041 | .p.id = AV_CODEC_ID_AV1, |
| 1039 | .priv_data_size = sizeof(VAAPIEncodeAV1Context), | 1042 | .priv_data_size = sizeof(VAAPIEncodeAV1Context), |
| 1040 | .init = &vaapi_encode_av1_init, | 1043 | .init = &vaapi_encode_av1_init, |
| 1041 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 1044 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 1042 | .close = &vaapi_encode_av1_close, | 1045 | .close = &vaapi_encode_av1_close, |
| 1043 | .p.priv_class = &vaapi_encode_av1_class, | 1046 | .p.priv_class = &vaapi_encode_av1_class, |
| 1044 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 1047 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |
| @@ -233,7 +233,7 @@ static int vaapi_encode_h264_write_extra_header(AVCodecContext *avctx, · 232 unmodified lines | |||
| 233 | goto fail; | 233 | goto fail; |
| 234 | } | 234 | } |
| 235 | if (priv->sei_needed & SEI_TIMING) { | 235 | if (priv->sei_needed & SEI_TIMING) { |
| 236 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | 236 | if (pic->base.type == FF_HW_PICTURE_TYPE_IDR) { |
| 237 | err = ff_cbs_sei_add_message(priv->cbc, au, 1, | 237 | err = ff_cbs_sei_add_message(priv->cbc, au, 1, |
| 238 | SEI_TYPE_BUFFERING_PERIOD, | 238 | SEI_TYPE_BUFFERING_PERIOD, |
| 239 | &priv->sei_buffering_period, NULL); | 239 | &priv->sei_buffering_period, NULL); |
| @@ -295,6 +295,7 @@ fail: · 55 unmodified lines | |||
| 295 | 295 | ||
| 296 | static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) | 296 | static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) |
| 297 | { | 297 | { |
| 298 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 298 | VAAPIEncodeContext *ctx = avctx->priv_data; | 299 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 299 | VAAPIEncodeH264Context *priv = avctx->priv_data; | 300 | VAAPIEncodeH264Context *priv = avctx->priv_data; |
| 300 | H264RawSPS *sps = &priv->raw_sps; | 301 | H264RawSPS *sps = &priv->raw_sps; |
| @@ -326,18 +327,18 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 25 unmodified lines | |||
| 326 | sps->constraint_set1_flag = 1; | 327 | sps->constraint_set1_flag = 1; |
| 327 | 328 | ||
| 328 | if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) | 329 | if (avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) |
| 329 | sps->constraint_set3_flag = ctx->gop_size == 1; | 330 | sps->constraint_set3_flag = base_ctx->gop_size == 1; |
| 330 | 331 | ||
| 331 | if (avctx->profile == AV_PROFILE_H264_MAIN || | 332 | if (avctx->profile == AV_PROFILE_H264_MAIN || |
| 332 | avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) { | 333 | avctx->profile == AV_PROFILE_H264_HIGH || avctx->profile == AV_PROFILE_H264_HIGH_10) { |
| 333 | sps->constraint_set4_flag = 1; | 334 | sps->constraint_set4_flag = 1; |
| 334 | sps->constraint_set5_flag = ctx->b_per_p == 0; | 335 | sps->constraint_set5_flag = base_ctx->b_per_p == 0; |
| 335 | } | 336 | } |
| 336 | 337 | ||
| 337 | if (ctx->gop_size == 1) | 338 | if (base_ctx->gop_size == 1) |
| 338 | priv->dpb_frames = 0; | 339 | priv->dpb_frames = 0; |
| 339 | else | 340 | else |
| 340 | priv->dpb_frames = 1 + ctx->max_b_depth; | 341 | priv->dpb_frames = 1 + base_ctx->max_b_depth; |
| 341 | 342 | ||
| 342 | if (avctx->level != AV_LEVEL_UNKNOWN) { | 343 | if (avctx->level != AV_LEVEL_UNKNOWN) { |
| 343 | sps->level_idc = avctx->level; | 344 | sps->level_idc = avctx->level; |
| @@ -374,7 +375,7 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 30 unmodified lines | |||
| 374 | sps->bit_depth_chroma_minus8 = bit_depth - 8; | 375 | sps->bit_depth_chroma_minus8 = bit_depth - 8; |
| 375 | 376 | ||
| 376 | sps->log2_max_frame_num_minus4 = 4; | 377 | sps->log2_max_frame_num_minus4 = 4; |
| 377 | sps->pic_order_cnt_type = ctx->max_b_depth ? 0 : 2; | 378 | sps->pic_order_cnt_type = base_ctx->max_b_depth ? 0 : 2; |
| 378 | if (sps->pic_order_cnt_type == 0) { | 379 | if (sps->pic_order_cnt_type == 0) { |
| 379 | sps->log2_max_pic_order_cnt_lsb_minus4 = 4; | 380 | sps->log2_max_pic_order_cnt_lsb_minus4 = 4; |
| 380 | } | 381 | } |
| @@ -501,8 +502,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 120 unmodified lines | |||
| 501 | sps->vui.motion_vectors_over_pic_boundaries_flag = 1; | 502 | sps->vui.motion_vectors_over_pic_boundaries_flag = 1; |
| 502 | sps->vui.log2_max_mv_length_horizontal = 15; | 503 | sps->vui.log2_max_mv_length_horizontal = 15; |
| 503 | sps->vui.log2_max_mv_length_vertical = 15; | 504 | sps->vui.log2_max_mv_length_vertical = 15; |
| 504 | sps->vui.max_num_reorder_frames = ctx->max_b_depth; | 505 | sps->vui.max_num_reorder_frames = base_ctx->max_b_depth; |
| 505 | sps->vui.max_dec_frame_buffering = ctx->max_b_depth + 1; | 506 | sps->vui.max_dec_frame_buffering = base_ctx->max_b_depth + 1; |
| 506 | 507 | ||
| 507 | pps->nal_unit_header.nal_ref_idc = 3; | 508 | pps->nal_unit_header.nal_ref_idc = 3; |
| 508 | pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; | 509 | pps->nal_unit_header.nal_unit_type = H264_NAL_PPS; |
| @@ -535,9 +536,9 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 26 unmodified lines | |||
| 535 | *vseq = (VAEncSequenceParameterBufferH264) { | 536 | *vseq = (VAEncSequenceParameterBufferH264) { |
| 536 | .seq_parameter_set_id = sps->seq_parameter_set_id, | 537 | .seq_parameter_set_id = sps->seq_parameter_set_id, |
| 537 | .level_idc = sps->level_idc, | 538 | .level_idc = sps->level_idc, |
| 538 | .intra_period = ctx->gop_size, | 539 | .intra_period = base_ctx->gop_size, |
| 539 | .intra_idr_period = ctx->gop_size, | 540 | .intra_idr_period = base_ctx->gop_size, |
| 540 | .ip_period = ctx->b_per_p + 1, | 541 | .ip_period = base_ctx->b_per_p + 1, |
| 541 | 542 | ||
| 542 | .bits_per_second = ctx->va_bit_rate, | 543 | .bits_per_second = ctx->va_bit_rate, |
| 543 | .max_num_ref_frames = sps->max_num_ref_frames, | 544 | .max_num_ref_frames = sps->max_num_ref_frames, |
| @@ -619,14 +620,15 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines | |||
| 619 | } | 620 | } |
| 620 | 621 | ||
| 621 | static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, | 622 | static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, |
| 622 | VAAPIEncodePicture *pic) | 623 | VAAPIEncodePicture *vaapi_pic) |
| 623 | { | 624 | { |
| 624 | VAAPIEncodeContext *ctx = avctx->priv_data; | 625 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 625 | VAAPIEncodeH264Context *priv = avctx->priv_data; | 626 | VAAPIEncodeH264Context *priv = avctx->priv_data; |
| 627 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 626 | VAAPIEncodeH264Picture *hpic = pic->priv_data; | 628 | VAAPIEncodeH264Picture *hpic = pic->priv_data; |
| 627 | VAAPIEncodePicture *prev = pic->prev; | 629 | FFHWBaseEncodePicture *prev = pic->prev; |
| 628 | VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL; | 630 | VAAPIEncodeH264Picture *hprev = prev ? prev->priv_data : NULL; |
| 629 | VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; | 631 | VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params; |
| 630 | int i, j = 0; | 632 | int i, j = 0; |
| 631 | 633 | ||
| 632 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | 634 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { |
| @@ -662,7 +664,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 29 unmodified lines | |||
| 662 | hpic->pic_order_cnt *= 2; | 664 | hpic->pic_order_cnt *= 2; |
| 663 | } | 665 | } |
| 664 | 666 | ||
| 665 | hpic->dpb_delay = pic->display_order - pic->encode_order + ctx->max_b_depth; | 667 | hpic->dpb_delay = pic->display_order - pic->encode_order + base_ctx->max_b_depth; |
| 666 | hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame; | 668 | hpic->cpb_delay = pic->encode_order - hpic->last_idr_frame; |
| 667 | 669 | ||
| 668 | if (priv->aud) { | 670 | if (priv->aud) { |
| @@ -699,7 +701,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 30 unmodified lines | |||
| 699 | priv->sei_recovery_point = (H264RawSEIRecoveryPoint) { | 701 | priv->sei_recovery_point = (H264RawSEIRecoveryPoint) { |
| 700 | .recovery_frame_cnt = 0, | 702 | .recovery_frame_cnt = 0, |
| 701 | .exact_match_flag = 1, | 703 | .exact_match_flag = 1, |
| 702 | .broken_link_flag = ctx->b_per_p > 0, | 704 | .broken_link_flag = base_ctx->b_per_p > 0, |
| 703 | }; | 705 | }; |
| 704 | 706 | ||
| 705 | priv->sei_needed |= SEI_RECOVERY_POINT; | 707 | priv->sei_needed |= SEI_RECOVERY_POINT; |
| @@ -722,7 +724,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 16 unmodified lines | |||
| 722 | } | 724 | } |
| 723 | 725 | ||
| 724 | vpic->CurrPic = (VAPictureH264) { | 726 | vpic->CurrPic = (VAPictureH264) { |
| 725 | .picture_id = pic->recon_surface, | 727 | .picture_id = vaapi_pic->recon_surface, |
| 726 | .frame_idx = hpic->frame_num, | 728 | .frame_idx = hpic->frame_num, |
| 727 | .flags = 0, | 729 | .flags = 0, |
| 728 | .TopFieldOrderCnt = hpic->pic_order_cnt, | 730 | .TopFieldOrderCnt = hpic->pic_order_cnt, |
| @@ -730,14 +732,14 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 1 unmodified line | |||
| 730 | }; | 732 | }; |
| 731 | for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { | 733 | for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { |
| 732 | for (i = 0; i < pic->nb_refs[k]; i++) { | 734 | for (i = 0; i < pic->nb_refs[k]; i++) { |
| 733 | VAAPIEncodePicture *ref = pic->refs[k][i]; | 735 | FFHWBaseEncodePicture *ref = pic->refs[k][i]; |
| 734 | VAAPIEncodeH264Picture *href; | 736 | VAAPIEncodeH264Picture *href; |
| 735 | 737 | ||
| 736 | av_assert0(ref && ref->encode_order < pic->encode_order); | 738 | av_assert0(ref && ref->encode_order < pic->encode_order); |
| 737 | href = ref->priv_data; | 739 | href = ref->priv_data; |
| 738 | 740 | ||
| 739 | vpic->ReferenceFrames[j++] = (VAPictureH264) { | 741 | vpic->ReferenceFrames[j++] = (VAPictureH264) { |
| 740 | .picture_id = ref->recon_surface, | 742 | .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface, |
| 741 | .frame_idx = href->frame_num, | 743 | .frame_idx = href->frame_num, |
| 742 | .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, | 744 | .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE, |
| 743 | .TopFieldOrderCnt = href->pic_order_cnt, | 745 | .TopFieldOrderCnt = href->pic_order_cnt, |
| @@ -753,7 +755,7 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines | |||
| 753 | }; | 755 | }; |
| 754 | } | 756 | } |
| 755 | 757 | ||
| 756 | vpic->coded_buf = pic->output_buffer; | 758 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 757 | 759 | ||
| 758 | vpic->frame_num = hpic->frame_num; | 760 | vpic->frame_num = hpic->frame_num; |
| 759 | 761 | ||
| @@ -764,12 +766,13 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, · 4 unmodified lines | |||
| 764 | } | 766 | } |
| 765 | 767 | ||
| 766 | static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, | 768 | static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, |
| 767 | VAAPIEncodePicture *pic, | 769 | VAAPIEncodePicture *vaapi_pic, |
| 768 | VAAPIEncodePicture **rpl0, | 770 | VAAPIEncodePicture **rpl0, |
| 769 | VAAPIEncodePicture **rpl1, | 771 | VAAPIEncodePicture **rpl1, |
| 770 | int *rpl_size) | 772 | int *rpl_size) |
| 771 | { | 773 | { |
| 772 | VAAPIEncodePicture *prev; | 774 | FFHWBaseEncodePicture *pic = &vaapi_pic->base; |
| 775 | FFHWBaseEncodePicture *prev; | ||
| 773 | VAAPIEncodeH264Picture *hp, *hn, *hc; | 776 | VAAPIEncodeH264Picture *hp, *hn, *hc; |
| 774 | int i, j, n = 0; | 777 | int i, j, n = 0; |
| 775 | 778 | ||
| @@ -783,17 +786,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 7 unmodified lines | |||
| 783 | 786 | ||
| 784 | if (pic->type == FF_HW_PICTURE_TYPE_P) { | 787 | if (pic->type == FF_HW_PICTURE_TYPE_P) { |
| 785 | for (j = n; j > 0; j--) { | 788 | for (j = n; j > 0; j--) { |
| 786 | hc = rpl0[j - 1]->priv_data; | 789 | hc = rpl0[j - 1]->base.priv_data; |
| 787 | av_assert0(hc->frame_num != hn->frame_num); | 790 | av_assert0(hc->frame_num != hn->frame_num); |
| 788 | if (hc->frame_num > hn->frame_num) | 791 | if (hc->frame_num > hn->frame_num) |
| 789 | break; | 792 | break; |
| 790 | rpl0[j] = rpl0[j - 1]; | 793 | rpl0[j] = rpl0[j - 1]; |
| 791 | } | 794 | } |
| 792 | rpl0[j] = prev->dpb[i]; | 795 | rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i]; |
| 793 | 796 | ||
| 794 | } else if (pic->type == FF_HW_PICTURE_TYPE_B) { | 797 | } else if (pic->type == FF_HW_PICTURE_TYPE_B) { |
| 795 | for (j = n; j > 0; j--) { | 798 | for (j = n; j > 0; j--) { |
| 796 | hc = rpl0[j - 1]->priv_data; | 799 | hc = rpl0[j - 1]->base.priv_data; |
| 797 | av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); | 800 | av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); |
| 798 | if (hc->pic_order_cnt < hp->pic_order_cnt) { | 801 | if (hc->pic_order_cnt < hp->pic_order_cnt) { |
| 799 | if (hn->pic_order_cnt > hp->pic_order_cnt || | 802 | if (hn->pic_order_cnt > hp->pic_order_cnt || |
| @@ -805,10 +808,10 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 5 unmodified lines | |||
| 805 | } | 808 | } |
| 806 | rpl0[j] = rpl0[j - 1]; | 809 | rpl0[j] = rpl0[j - 1]; |
| 807 | } | 810 | } |
| 808 | rpl0[j] = prev->dpb[i]; | 811 | rpl0[j] = (VAAPIEncodePicture *)prev->dpb[i]; |
| 809 | 812 | ||
| 810 | for (j = n; j > 0; j--) { | 813 | for (j = n; j > 0; j--) { |
| 811 | hc = rpl1[j - 1]->priv_data; | 814 | hc = rpl1[j - 1]->base.priv_data; |
| 812 | av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); | 815 | av_assert0(hc->pic_order_cnt != hp->pic_order_cnt); |
| 813 | if (hc->pic_order_cnt > hp->pic_order_cnt) { | 816 | if (hc->pic_order_cnt > hp->pic_order_cnt) { |
| 814 | if (hn->pic_order_cnt < hp->pic_order_cnt || | 817 | if (hn->pic_order_cnt < hp->pic_order_cnt || |
| @@ -820,7 +823,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 5 unmodified lines | |||
| 820 | } | 823 | } |
| 821 | rpl1[j] = rpl1[j - 1]; | 824 | rpl1[j] = rpl1[j - 1]; |
| 822 | } | 825 | } |
| 823 | rpl1[j] = prev->dpb[i]; | 826 | rpl1[j] = (VAAPIEncodePicture *)prev->dpb[i]; |
| 824 | } | 827 | } |
| 825 | 828 | ||
| 826 | ++n; | 829 | ++n; |
| @@ -840,7 +843,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 13 unmodified lines | |||
| 840 | av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:", | 843 | av_log(avctx, AV_LOG_DEBUG, "Default RefPicList0 for fn=%d/poc=%d:", |
| 841 | hp->frame_num, hp->pic_order_cnt); | 844 | hp->frame_num, hp->pic_order_cnt); |
| 842 | for (i = 0; i < n; i++) { | 845 | for (i = 0; i < n; i++) { |
| 843 | hn = rpl0[i]->priv_data; | 846 | hn = rpl0[i]->base.priv_data; |
| 844 | av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", | 847 | av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", |
| 845 | hn->frame_num, hn->pic_order_cnt); | 848 | hn->frame_num, hn->pic_order_cnt); |
| 846 | } | 849 | } |
| @@ -850,7 +853,7 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 3 unmodified lines | |||
| 850 | av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:", | 853 | av_log(avctx, AV_LOG_DEBUG, "Default RefPicList1 for fn=%d/poc=%d:", |
| 851 | hp->frame_num, hp->pic_order_cnt); | 854 | hp->frame_num, hp->pic_order_cnt); |
| 852 | for (i = 0; i < n; i++) { | 855 | for (i = 0; i < n; i++) { |
| 853 | hn = rpl1[i]->priv_data; | 856 | hn = rpl1[i]->base.priv_data; |
| 854 | av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", | 857 | av_log(avctx, AV_LOG_DEBUG, " fn=%d/poc=%d", |
| 855 | hn->frame_num, hn->pic_order_cnt); | 858 | hn->frame_num, hn->pic_order_cnt); |
| 856 | } | 859 | } |
| @@ -861,16 +864,17 @@ static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext *avctx, · 4 unmodified lines | |||
| 861 | } | 864 | } |
| 862 | 865 | ||
| 863 | static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, | 866 | static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, |
| 864 | VAAPIEncodePicture *pic, | 867 | VAAPIEncodePicture *vaapi_pic, |
| 865 | VAAPIEncodeSlice *slice) | 868 | VAAPIEncodeSlice *slice) |
| 866 | { | 869 | { |
| 867 | VAAPIEncodeH264Context *priv = avctx->priv_data; | 870 | VAAPIEncodeH264Context *priv = avctx->priv_data; |
| 871 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 868 | VAAPIEncodeH264Picture *hpic = pic->priv_data; | 872 | VAAPIEncodeH264Picture *hpic = pic->priv_data; |
| 869 | VAAPIEncodePicture *prev = pic->prev; | 873 | FFHWBaseEncodePicture *prev = pic->prev; |
| 870 | H264RawSPS *sps = &priv->raw_sps; | 874 | H264RawSPS *sps = &priv->raw_sps; |
| 871 | H264RawPPS *pps = &priv->raw_pps; | 875 | H264RawPPS *pps = &priv->raw_pps; |
| 872 | H264RawSliceHeader *sh = &priv->raw_slice.header; | 876 | H264RawSliceHeader *sh = &priv->raw_slice.header; |
| 873 | VAEncPictureParameterBufferH264 *vpic = pic->codec_picture_params; | 877 | VAEncPictureParameterBufferH264 *vpic = vaapi_pic->codec_picture_params; |
| 874 | VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; | 878 | VAEncSliceParameterBufferH264 *vslice = slice->codec_slice_params; |
| 875 | int i, j; | 879 | int i, j; |
| 876 | 880 | ||
| @@ -903,7 +907,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 26 unmodified lines | |||
| 903 | sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26); | 907 | sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26); |
| 904 | 908 | ||
| 905 | if (pic->is_reference && pic->type != FF_HW_PICTURE_TYPE_IDR) { | 909 | if (pic->is_reference && pic->type != FF_HW_PICTURE_TYPE_IDR) { |
| 906 | VAAPIEncodePicture *discard_list[MAX_DPB_SIZE]; | 910 | FFHWBaseEncodePicture *discard_list[MAX_DPB_SIZE]; |
| 907 | int discard = 0, keep = 0; | 911 | int discard = 0, keep = 0; |
| 908 | 912 | ||
| 909 | // Discard everything which is in the DPB of the previous frame but | 913 | // Discard everything which is in the DPB of the previous frame but |
| @@ -944,14 +948,14 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 34 unmodified lines | |||
| 944 | VAAPIEncodeH264Picture *href; | 948 | VAAPIEncodeH264Picture *href; |
| 945 | int n; | 949 | int n; |
| 946 | 950 | ||
| 947 | vaapi_encode_h264_default_ref_pic_list(avctx, pic, | 951 | vaapi_encode_h264_default_ref_pic_list(avctx, vaapi_pic, |
| 948 | def_l0, def_l1, &n); | 952 | def_l0, def_l1, &n); |
| 949 | 953 | ||
| 950 | if (pic->type == FF_HW_PICTURE_TYPE_P) { | 954 | if (pic->type == FF_HW_PICTURE_TYPE_P) { |
| 951 | int need_rplm = 0; | 955 | int need_rplm = 0; |
| 952 | for (i = 0; i < pic->nb_refs[0]; i++) { | 956 | for (i = 0; i < pic->nb_refs[0]; i++) { |
| 953 | av_assert0(pic->refs[0][i]); | 957 | av_assert0(pic->refs[0][i]); |
| 954 | if (pic->refs[0][i] != def_l0[i]) | 958 | if (pic->refs[0][i] != (FFHWBaseEncodePicture *)def_l0[i]) |
| 955 | need_rplm = 1; | 959 | need_rplm = 1; |
| 956 | } | 960 | } |
| 957 | 961 | ||
| @@ -982,7 +986,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines | |||
| 982 | av_assert0(pic->refs[0][i]); | 986 | av_assert0(pic->refs[0][i]); |
| 983 | href = pic->refs[0][i]->priv_data; | 987 | href = pic->refs[0][i]->priv_data; |
| 984 | av_assert0(href->pic_order_cnt < hpic->pic_order_cnt); | 988 | av_assert0(href->pic_order_cnt < hpic->pic_order_cnt); |
| 985 | if (pic->refs[0][i] != def_l0[n0]) | 989 | if (pic->refs[0][i] != (FFHWBaseEncodePicture *)def_l0[n0]) |
| 986 | need_rplm_l0 = 1; | 990 | need_rplm_l0 = 1; |
| 987 | ++n0; | 991 | ++n0; |
| 988 | } | 992 | } |
| @@ -991,7 +995,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx, · 2 unmodified lines | |||
| 991 | av_assert0(pic->refs[1][i]); | 995 | av_assert0(pic->refs[1][i]); |
| 992 | href = pic->refs[1][i]->priv_data; | 996 | href = pic->refs[1][i]->priv_data; |
| 993 | av_assert0(href->pic_order_cnt > hpic->pic_order_cnt); | 997 | av_assert0(href->pic_order_cnt > hpic->pic_order_cnt); |
| 994 | if (pic->refs[1][i] != def_l1[n1]) | 998 | if (pic->refs[1][i] != (FFHWBaseEncodePicture *)def_l1[n1]) |
| 995 | need_rplm_l1 = 1; | 999 | need_rplm_l1 = 1; |
| 996 | ++n1; | 1000 | ++n1; |
| 997 | } | 1001 | } |
| @@ -1380,7 +1384,7 @@ const FFCodec ff_h264_vaapi_encoder = { · 382 unmodified lines | |||
| 1380 | .p.id = AV_CODEC_ID_H264, | 1384 | .p.id = AV_CODEC_ID_H264, |
| 1381 | .priv_data_size = sizeof(VAAPIEncodeH264Context), | 1385 | .priv_data_size = sizeof(VAAPIEncodeH264Context), |
| 1382 | .init = &vaapi_encode_h264_init, | 1386 | .init = &vaapi_encode_h264_init, |
| 1383 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 1387 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 1384 | .close = &vaapi_encode_h264_close, | 1388 | .close = &vaapi_encode_h264_close, |
| 1385 | .p.priv_class = &vaapi_encode_h264_class, | 1389 | .p.priv_class = &vaapi_encode_h264_class, |
| 1386 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 1390 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |
| @@ -260,6 +260,7 @@ fail: · 259 unmodified lines | |||
| 260 | 260 | ||
| 261 | static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) | 261 | static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) |
| 262 | { | 262 | { |
| 263 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 263 | VAAPIEncodeContext *ctx = avctx->priv_data; | 264 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 264 | VAAPIEncodeH265Context *priv = avctx->priv_data; | 265 | VAAPIEncodeH265Context *priv = avctx->priv_data; |
| 265 | H265RawVPS *vps = &priv->raw_vps; | 266 | H265RawVPS *vps = &priv->raw_vps; |
| @@ -341,7 +342,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 75 unmodified lines | |||
| 341 | ptl->general_max_420chroma_constraint_flag = chroma_format <= 1; | 342 | ptl->general_max_420chroma_constraint_flag = chroma_format <= 1; |
| 342 | ptl->general_max_monochrome_constraint_flag = chroma_format == 0; | 343 | ptl->general_max_monochrome_constraint_flag = chroma_format == 0; |
| 343 | 344 | ||
| 344 | ptl->general_intra_constraint_flag = ctx->gop_size == 1; | 345 | ptl->general_intra_constraint_flag = base_ctx->gop_size == 1; |
| 345 | ptl->general_one_picture_only_constraint_flag = 0; | 346 | ptl->general_one_picture_only_constraint_flag = 0; |
| 346 | 347 | ||
| 347 | ptl->general_lower_bit_rate_constraint_flag = 1; | 348 | ptl->general_lower_bit_rate_constraint_flag = 1; |
| @@ -354,7 +355,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 6 unmodified lines | |||
| 354 | level = ff_h265_guess_level(ptl, avctx->bit_rate, | 355 | level = ff_h265_guess_level(ptl, avctx->bit_rate, |
| 355 | ctx->surface_width, ctx->surface_height, | 356 | ctx->surface_width, ctx->surface_height, |
| 356 | ctx->nb_slices, ctx->tile_rows, ctx->tile_cols, | 357 | ctx->nb_slices, ctx->tile_rows, ctx->tile_cols, |
| 357 | (ctx->b_per_p > 0) + 1); | 358 | (base_ctx->b_per_p > 0) + 1); |
| 358 | if (level) { | 359 | if (level) { |
| 359 | av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); | 360 | av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name); |
| 360 | ptl->general_level_idc = level->level_idc; | 361 | ptl->general_level_idc = level->level_idc; |
| @@ -368,8 +369,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 7 unmodified lines | |||
| 368 | } | 369 | } |
| 369 | 370 | ||
| 370 | vps->vps_sub_layer_ordering_info_present_flag = 0; | 371 | vps->vps_sub_layer_ordering_info_present_flag = 0; |
| 371 | vps->vps_max_dec_pic_buffering_minus1[0] = ctx->max_b_depth + 1; | 372 | vps->vps_max_dec_pic_buffering_minus1[0] = base_ctx->max_b_depth + 1; |
| 372 | vps->vps_max_num_reorder_pics[0] = ctx->max_b_depth; | 373 | vps->vps_max_num_reorder_pics[0] = base_ctx->max_b_depth; |
| 373 | vps->vps_max_latency_increase_plus1[0] = 0; | 374 | vps->vps_max_latency_increase_plus1[0] = 0; |
| 374 | 375 | ||
| 375 | vps->vps_max_layer_id = 0; | 376 | vps->vps_max_layer_id = 0; |
| @@ -643,9 +644,9 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 267 unmodified lines | |||
| 643 | .general_level_idc = vps->profile_tier_level.general_level_idc, | 644 | .general_level_idc = vps->profile_tier_level.general_level_idc, |
| 644 | .general_tier_flag = vps->profile_tier_level.general_tier_flag, | 645 | .general_tier_flag = vps->profile_tier_level.general_tier_flag, |
| 645 | 646 | ||
| 646 | .intra_period = ctx->gop_size, | 647 | .intra_period = base_ctx->gop_size, |
| 647 | .intra_idr_period = ctx->gop_size, | 648 | .intra_idr_period = base_ctx->gop_size, |
| 648 | .ip_period = ctx->b_per_p + 1, | 649 | .ip_period = base_ctx->b_per_p + 1, |
| 649 | .bits_per_second = ctx->va_bit_rate, | 650 | .bits_per_second = ctx->va_bit_rate, |
| 650 | 651 | ||
| 651 | .pic_width_in_luma_samples = sps->pic_width_in_luma_samples, | 652 | .pic_width_in_luma_samples = sps->pic_width_in_luma_samples, |
| @@ -756,14 +757,15 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) · 104 unmodified lines | |||
| 756 | } | 757 | } |
| 757 | 758 | ||
| 758 | static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, | 759 | static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, |
| 759 | VAAPIEncodePicture *pic) | 760 | VAAPIEncodePicture *vaapi_pic) |
| 760 | { | 761 | { |
| 761 | VAAPIEncodeContext *ctx = avctx->priv_data; | 762 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 762 | VAAPIEncodeH265Context *priv = avctx->priv_data; | 763 | VAAPIEncodeH265Context *priv = avctx->priv_data; |
| 764 | FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 763 | VAAPIEncodeH265Picture *hpic = pic->priv_data; | 765 | VAAPIEncodeH265Picture *hpic = pic->priv_data; |
| 764 | VAAPIEncodePicture *prev = pic->prev; | 766 | FFHWBaseEncodePicture *prev = pic->prev; |
| 765 | VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL; | 767 | VAAPIEncodeH265Picture *hprev = prev ? prev->priv_data : NULL; |
| 766 | VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params; | 768 | VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params; |
| 767 | int i, j = 0; | 769 | int i, j = 0; |
| 768 | 770 | ||
| 769 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { | 771 | if (pic->type == FF_HW_PICTURE_TYPE_IDR) { |
| @@ -788,13 +790,13 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 18 unmodified lines | |||
| 788 | hpic->slice_type = HEVC_SLICE_P; | 790 | hpic->slice_type = HEVC_SLICE_P; |
| 789 | hpic->pic_type = 1; | 791 | hpic->pic_type = 1; |
| 790 | } else { | 792 | } else { |
| 791 | VAAPIEncodePicture *irap_ref; | 793 | FFHWBaseEncodePicture *irap_ref; |
| 792 | av_assert0(pic->refs[0][0] && pic->refs[1][0]); | 794 | av_assert0(pic->refs[0][0] && pic->refs[1][0]); |
| 793 | for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) { | 795 | for (irap_ref = pic; irap_ref; irap_ref = irap_ref->refs[1][0]) { |
| 794 | if (irap_ref->type == FF_HW_PICTURE_TYPE_I) | 796 | if (irap_ref->type == FF_HW_PICTURE_TYPE_I) |
| 795 | break; | 797 | break; |
| 796 | } | 798 | } |
| 797 | if (pic->b_depth == ctx->max_b_depth) { | 799 | if (pic->b_depth == base_ctx->max_b_depth) { |
| 798 | hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N | 800 | hpic->slice_nal_unit = irap_ref ? HEVC_NAL_RASL_N |
| 799 | : HEVC_NAL_TRAIL_N; | 801 | : HEVC_NAL_TRAIL_N; |
| 800 | } else { | 802 | } else { |
| @@ -910,21 +912,21 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 109 unmodified lines | |||
| 910 | } | 912 | } |
| 911 | 913 | ||
| 912 | vpic->decoded_curr_pic = (VAPictureHEVC) { | 914 | vpic->decoded_curr_pic = (VAPictureHEVC) { |
| 913 | .picture_id = pic->recon_surface, | 915 | .picture_id = vaapi_pic->recon_surface, |
| 914 | .pic_order_cnt = hpic->pic_order_cnt, | 916 | .pic_order_cnt = hpic->pic_order_cnt, |
| 915 | .flags = 0, | 917 | .flags = 0, |
| 916 | }; | 918 | }; |
| 917 | 919 | ||
| 918 | for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { | 920 | for (int k = 0; k < MAX_REFERENCE_LIST_NUM; k++) { |
| 919 | for (i = 0; i < pic->nb_refs[k]; i++) { | 921 | for (i = 0; i < pic->nb_refs[k]; i++) { |
| 920 | VAAPIEncodePicture *ref = pic->refs[k][i]; | 922 | FFHWBaseEncodePicture *ref = pic->refs[k][i]; |
| 921 | VAAPIEncodeH265Picture *href; | 923 | VAAPIEncodeH265Picture *href; |
| 922 | 924 | ||
| 923 | av_assert0(ref && ref->encode_order < pic->encode_order); | 925 | av_assert0(ref && ref->encode_order < pic->encode_order); |
| 924 | href = ref->priv_data; | 926 | href = ref->priv_data; |
| 925 | 927 | ||
| 926 | vpic->reference_frames[j++] = (VAPictureHEVC) { | 928 | vpic->reference_frames[j++] = (VAPictureHEVC) { |
| 927 | .picture_id = ref->recon_surface, | 929 | .picture_id = ((VAAPIEncodePicture *)ref)->recon_surface, |
| 928 | .pic_order_cnt = href->pic_order_cnt, | 930 | .pic_order_cnt = href->pic_order_cnt, |
| 929 | .flags = (ref->display_order < pic->display_order ? | 931 | .flags = (ref->display_order < pic->display_order ? |
| 930 | VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) | | 932 | VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) | |
| @@ -941,7 +943,7 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 10 unmodified lines | |||
| 941 | }; | 943 | }; |
| 942 | } | 944 | } |
| 943 | 945 | ||
| 944 | vpic->coded_buf = pic->output_buffer; | 946 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 945 | 947 | ||
| 946 | vpic->nal_unit_type = hpic->slice_nal_unit; | 948 | vpic->nal_unit_type = hpic->slice_nal_unit; |
| 947 | 949 | ||
| @@ -971,16 +973,17 @@ static int vaapi_encode_h265_init_picture_params(AVCodecContext *avctx, · 23 unmodified lines | |||
| 971 | } | 973 | } |
| 972 | 974 | ||
| 973 | static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, | 975 | static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, |
| 974 | VAAPIEncodePicture *pic, | 976 | VAAPIEncodePicture *vaapi_pic, |
| 975 | VAAPIEncodeSlice *slice) | 977 | VAAPIEncodeSlice *slice) |
| 976 | { | 978 | { |
| 977 | VAAPIEncodeContext *ctx = avctx->priv_data; | 979 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 978 | VAAPIEncodeH265Context *priv = avctx->priv_data; | 980 | VAAPIEncodeH265Context *priv = avctx->priv_data; |
| 981 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 979 | VAAPIEncodeH265Picture *hpic = pic->priv_data; | 982 | VAAPIEncodeH265Picture *hpic = pic->priv_data; |
| 980 | const H265RawSPS *sps = &priv->raw_sps; | 983 | const H265RawSPS *sps = &priv->raw_sps; |
| 981 | const H265RawPPS *pps = &priv->raw_pps; | 984 | const H265RawPPS *pps = &priv->raw_pps; |
| 982 | H265RawSliceHeader *sh = &priv->raw_slice.header; | 985 | H265RawSliceHeader *sh = &priv->raw_slice.header; |
| 983 | VAEncPictureParameterBufferHEVC *vpic = pic->codec_picture_params; | 986 | VAEncPictureParameterBufferHEVC *vpic = vaapi_pic->codec_picture_params; |
| 984 | VAEncSliceParameterBufferHEVC *vslice = slice->codec_slice_params; | 987 | VAEncSliceParameterBufferHEVC *vslice = slice->codec_slice_params; |
| 985 | int i; | 988 | int i; |
| 986 | 989 | ||
| @@ -997,7 +1000,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 10 unmodified lines | |||
| 997 | 1000 | ||
| 998 | sh->slice_type = hpic->slice_type; | 1001 | sh->slice_type = hpic->slice_type; |
| 999 | 1002 | ||
| 1000 | if (sh->slice_type == HEVC_SLICE_P && ctx->p_to_gpb) | 1003 | if (sh->slice_type == HEVC_SLICE_P && base_ctx->p_to_gpb) |
| 1001 | sh->slice_type = HEVC_SLICE_B; | 1004 | sh->slice_type = HEVC_SLICE_B; |
| 1002 | 1005 | ||
| 1003 | sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt & | 1006 | sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt & |
| @@ -1141,7 +1144,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 137 unmodified lines | |||
| 1141 | .slice_tc_offset_div2 = sh->slice_tc_offset_div2, | 1144 | .slice_tc_offset_div2 = sh->slice_tc_offset_div2, |
| 1142 | 1145 | ||
| 1143 | .slice_fields.bits = { | 1146 | .slice_fields.bits = { |
| 1144 | .last_slice_of_pic_flag = slice->index == pic->nb_slices - 1, | 1147 | .last_slice_of_pic_flag = slice->index == vaapi_pic->nb_slices - 1, |
| 1145 | .dependent_slice_segment_flag = sh->dependent_slice_segment_flag, | 1148 | .dependent_slice_segment_flag = sh->dependent_slice_segment_flag, |
| 1146 | .colour_plane_id = sh->colour_plane_id, | 1149 | .colour_plane_id = sh->colour_plane_id, |
| 1147 | .slice_temporal_mvp_enabled_flag = | 1150 | .slice_temporal_mvp_enabled_flag = |
| @@ -1172,7 +1175,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 24 unmodified lines | |||
| 1172 | av_assert0(pic->type == FF_HW_PICTURE_TYPE_P || | 1175 | av_assert0(pic->type == FF_HW_PICTURE_TYPE_P || |
| 1173 | pic->type == FF_HW_PICTURE_TYPE_B); | 1176 | pic->type == FF_HW_PICTURE_TYPE_B); |
| 1174 | vslice->ref_pic_list0[0] = vpic->reference_frames[0]; | 1177 | vslice->ref_pic_list0[0] = vpic->reference_frames[0]; |
| 1175 | if (ctx->p_to_gpb && pic->type == FF_HW_PICTURE_TYPE_P) | 1178 | if (base_ctx->p_to_gpb && pic->type == FF_HW_PICTURE_TYPE_P) |
| 1176 | // Reference for GPB B-frame, L0 == L1 | 1179 | // Reference for GPB B-frame, L0 == L1 |
| 1177 | vslice->ref_pic_list1[0] = vpic->reference_frames[0]; | 1180 | vslice->ref_pic_list1[0] = vpic->reference_frames[0]; |
| 1178 | } | 1181 | } |
| @@ -1182,7 +1185,7 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx, · 3 unmodified lines | |||
| 1182 | vslice->ref_pic_list1[0] = vpic->reference_frames[1]; | 1185 | vslice->ref_pic_list1[0] = vpic->reference_frames[1]; |
| 1183 | } | 1186 | } |
| 1184 | 1187 | ||
| 1185 | if (pic->type == FF_HW_PICTURE_TYPE_P && ctx->p_to_gpb) { | 1188 | if (pic->type == FF_HW_PICTURE_TYPE_P && base_ctx->p_to_gpb) { |
| 1186 | vslice->slice_type = HEVC_SLICE_B; | 1189 | vslice->slice_type = HEVC_SLICE_B; |
| 1187 | for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) { | 1190 | for (i = 0; i < FF_ARRAY_ELEMS(vslice->ref_pic_list0); i++) { |
| 1188 | vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id; | 1191 | vslice->ref_pic_list1[i].picture_id = vslice->ref_pic_list0[i].picture_id; |
| @@ -1495,7 +1498,7 @@ const FFCodec ff_hevc_vaapi_encoder = { · 306 unmodified lines | |||
| 1495 | .p.id = AV_CODEC_ID_HEVC, | 1498 | .p.id = AV_CODEC_ID_HEVC, |
| 1496 | .priv_data_size = sizeof(VAAPIEncodeH265Context), | 1499 | .priv_data_size = sizeof(VAAPIEncodeH265Context), |
| 1497 | .init = &vaapi_encode_h265_init, | 1500 | .init = &vaapi_encode_h265_init, |
| 1498 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 1501 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 1499 | .close = &vaapi_encode_h265_close, | 1502 | .close = &vaapi_encode_h265_close, |
| 1500 | .p.priv_class = &vaapi_encode_h265_class, | 1503 | .p.priv_class = &vaapi_encode_h265_class, |
| 1501 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 1504 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |
| @@ -220,12 +220,13 @@ static int vaapi_encode_mjpeg_write_extra_buffer(AVCodecContext *avctx, · 219 unmodified lines | |||
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, | 222 | static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, |
| 223 | VAAPIEncodePicture *pic) | 223 | VAAPIEncodePicture *vaapi_pic) |
| 224 | { | 224 | { |
| 225 | VAAPIEncodeMJPEGContext *priv = avctx->priv_data; | 225 | VAAPIEncodeMJPEGContext *priv = avctx->priv_data; |
| 226 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 226 | JPEGRawFrameHeader *fh = &priv->frame_header; | 227 | JPEGRawFrameHeader *fh = &priv->frame_header; |
| 227 | JPEGRawScanHeader *sh = &priv->scan.header; | 228 | JPEGRawScanHeader *sh = &priv->scan.header; |
| 228 | VAEncPictureParameterBufferJPEG *vpic = pic->codec_picture_params; | 229 | VAEncPictureParameterBufferJPEG *vpic = vaapi_pic->codec_picture_params; |
| 229 | const AVPixFmtDescriptor *desc; | 230 | const AVPixFmtDescriptor *desc; |
| 230 | const uint8_t components_rgb[3] = { 'R', 'G', 'B' }; | 231 | const uint8_t components_rgb[3] = { 'R', 'G', 'B' }; |
| 231 | const uint8_t components_yuv[3] = { 1, 2, 3 }; | 232 | const uint8_t components_yuv[3] = { 1, 2, 3 }; |
| @@ -377,8 +378,8 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 145 unmodified lines | |||
| 377 | 378 | ||
| 378 | 379 | ||
| 379 | *vpic = (VAEncPictureParameterBufferJPEG) { | 380 | *vpic = (VAEncPictureParameterBufferJPEG) { |
| 380 | .reconstructed_picture = pic->recon_surface, | 381 | .reconstructed_picture = vaapi_pic->recon_surface, |
| 381 | .coded_buf = pic->output_buffer, | 382 | .coded_buf = vaapi_pic->output_buffer, |
| 382 | 383 | ||
| 383 | .picture_width = fh->X, | 384 | .picture_width = fh->X, |
| 384 | .picture_height = fh->Y, | 385 | .picture_height = fh->Y, |
| @@ -406,7 +407,7 @@ static int vaapi_encode_mjpeg_init_picture_params(AVCodecContext *avctx, · 21 unmodified lines | |||
| 406 | vpic->quantiser_table_selector[i] = fh->Tq[i]; | 407 | vpic->quantiser_table_selector[i] = fh->Tq[i]; |
| 407 | } | 408 | } |
| 408 | 409 | ||
| 409 | pic->nb_slices = 1; | 410 | vaapi_pic->nb_slices = 1; |
| 410 | 411 | ||
| 411 | return 0; | 412 | return 0; |
| 412 | } | 413 | } |
| @@ -572,7 +573,7 @@ const FFCodec ff_mjpeg_vaapi_encoder = { · 159 unmodified lines | |||
| 572 | .p.id = AV_CODEC_ID_MJPEG, | 573 | .p.id = AV_CODEC_ID_MJPEG, |
| 573 | .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), | 574 | .priv_data_size = sizeof(VAAPIEncodeMJPEGContext), |
| 574 | .init = &vaapi_encode_mjpeg_init, | 575 | .init = &vaapi_encode_mjpeg_init, |
| 575 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 576 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 576 | .close = &vaapi_encode_mjpeg_close, | 577 | .close = &vaapi_encode_mjpeg_close, |
| 577 | .p.priv_class = &vaapi_encode_mjpeg_class, | 578 | .p.priv_class = &vaapi_encode_mjpeg_class, |
| 578 | .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 | | 579 | .p.capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DR1 | |
| @@ -166,6 +166,7 @@ fail: · 165 unmodified lines | |||
| 166 | 166 | ||
| 167 | static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) | 167 | static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) |
| 168 | { | 168 | { |
| 169 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 169 | VAAPIEncodeContext *ctx = avctx->priv_data; | 170 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 170 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; | 171 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; |
| 171 | MPEG2RawSequenceHeader *sh = &priv->sequence_header; | 172 | MPEG2RawSequenceHeader *sh = &priv->sequence_header; |
| @@ -281,7 +282,7 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 109 unmodified lines | |||
| 281 | 282 | ||
| 282 | se->bit_rate_extension = priv->bit_rate >> 18; | 283 | se->bit_rate_extension = priv->bit_rate >> 18; |
| 283 | se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10; | 284 | se->vbv_buffer_size_extension = priv->vbv_buffer_size >> 10; |
| 284 | se->low_delay = ctx->b_per_p == 0; | 285 | se->low_delay = base_ctx->b_per_p == 0; |
| 285 | 286 | ||
| 286 | se->frame_rate_extension_n = ext_n; | 287 | se->frame_rate_extension_n = ext_n; |
| 287 | se->frame_rate_extension_d = ext_d; | 288 | se->frame_rate_extension_d = ext_d; |
| @@ -353,8 +354,8 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 65 unmodified lines | |||
| 353 | 354 | ||
| 354 | 355 | ||
| 355 | *vseq = (VAEncSequenceParameterBufferMPEG2) { | 356 | *vseq = (VAEncSequenceParameterBufferMPEG2) { |
| 356 | .intra_period = ctx->gop_size, | 357 | .intra_period = base_ctx->gop_size, |
| 357 | .ip_period = ctx->b_per_p + 1, | 358 | .ip_period = base_ctx->b_per_p + 1, |
| 358 | 359 | ||
| 359 | .picture_width = avctx->width, | 360 | .picture_width = avctx->width, |
| 360 | .picture_height = avctx->height, | 361 | .picture_height = avctx->height, |
| @@ -417,12 +418,13 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) · 56 unmodified lines | |||
| 417 | } | 418 | } |
| 418 | 419 | ||
| 419 | static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, | 420 | static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, |
| 420 | VAAPIEncodePicture *pic) | 421 | VAAPIEncodePicture *vaapi_pic) |
| 421 | { | 422 | { |
| 422 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; | 423 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; |
| 424 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 423 | MPEG2RawPictureHeader *ph = &priv->picture_header; | 425 | MPEG2RawPictureHeader *ph = &priv->picture_header; |
| 424 | MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding; | 426 | MPEG2RawPictureCodingExtension *pce = &priv->picture_coding_extension.data.picture_coding; |
| 425 | VAEncPictureParameterBufferMPEG2 *vpic = pic->codec_picture_params; | 427 | VAEncPictureParameterBufferMPEG2 *vpic = vaapi_pic->codec_picture_params; |
| 426 | 428 | ||
| 427 | if (pic->type == FF_HW_PICTURE_TYPE_IDR || pic->type == FF_HW_PICTURE_TYPE_I) { | 429 | if (pic->type == FF_HW_PICTURE_TYPE_IDR || pic->type == FF_HW_PICTURE_TYPE_I) { |
| 428 | ph->temporal_reference = 0; | 430 | ph->temporal_reference = 0; |
| @@ -448,8 +450,8 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 19 unmodified lines | |||
| 448 | pce->f_code[1][1] = 15; | 450 | pce->f_code[1][1] = 15; |
| 449 | } | 451 | } |
| 450 | 452 | ||
| 451 | vpic->reconstructed_picture = pic->recon_surface; | 453 | vpic->reconstructed_picture = vaapi_pic->recon_surface; |
| 452 | vpic->coded_buf = pic->output_buffer; | 454 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 453 | 455 | ||
| 454 | switch (pic->type) { | 456 | switch (pic->type) { |
| 455 | case FF_HW_PICTURE_TYPE_IDR: | 457 | case FF_HW_PICTURE_TYPE_IDR: |
| @@ -458,12 +460,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 2 unmodified lines | |||
| 458 | break; | 460 | break; |
| 459 | case FF_HW_PICTURE_TYPE_P: | 461 | case FF_HW_PICTURE_TYPE_P: |
| 460 | vpic->picture_type = VAEncPictureTypePredictive; | 462 | vpic->picture_type = VAEncPictureTypePredictive; |
| 461 | vpic->forward_reference_picture = pic->refs[0][0]->recon_surface; | 463 | vpic->forward_reference_picture = ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface; |
| 462 | break; | 464 | break; |
| 463 | case FF_HW_PICTURE_TYPE_B: | 465 | case FF_HW_PICTURE_TYPE_B: |
| 464 | vpic->picture_type = VAEncPictureTypeBidirectional; | 466 | vpic->picture_type = VAEncPictureTypeBidirectional; |
| 465 | vpic->forward_reference_picture = pic->refs[0][0]->recon_surface; | 467 | vpic->forward_reference_picture = ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface; |
| 466 | vpic->backward_reference_picture = pic->refs[1][0]->recon_surface; | 468 | vpic->backward_reference_picture = ((VAAPIEncodePicture *)pic->refs[1][0])->recon_surface; |
| 467 | break; | 469 | break; |
| 468 | default: | 470 | default: |
| 469 | av_assert0(0 && "invalid picture type"); | 471 | av_assert0(0 && "invalid picture type"); |
| @@ -479,11 +481,12 @@ static int vaapi_encode_mpeg2_init_picture_params(AVCodecContext *avctx, · 9 unmodified lines | |||
| 479 | } | 481 | } |
| 480 | 482 | ||
| 481 | static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx, | 483 | static int vaapi_encode_mpeg2_init_slice_params(AVCodecContext *avctx, |
| 482 | VAAPIEncodePicture *pic, | 484 | VAAPIEncodePicture *vaapi_pic, |
| 483 | VAAPIEncodeSlice *slice) | 485 | VAAPIEncodeSlice *slice) |
| 484 | { | 486 | { |
| 485 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; | 487 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; |
| 486 | VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params; | 488 | VAAPIEncodeMPEG2Context *priv = avctx->priv_data; |
| 489 | VAEncSliceParameterBufferMPEG2 *vslice = slice->codec_slice_params; | ||
| 487 | int qp; | 490 | int qp; |
| 488 | 491 | ||
| 489 | vslice->macroblock_address = slice->block_start; | 492 | vslice->macroblock_address = slice->block_start; |
| @@ -695,7 +698,7 @@ const FFCodec ff_mpeg2_vaapi_encoder = { · 205 unmodified lines | |||
| 695 | .p.id = AV_CODEC_ID_MPEG2VIDEO, | 698 | .p.id = AV_CODEC_ID_MPEG2VIDEO, |
| 696 | .priv_data_size = sizeof(VAAPIEncodeMPEG2Context), | 699 | .priv_data_size = sizeof(VAAPIEncodeMPEG2Context), |
| 697 | .init = &vaapi_encode_mpeg2_init, | 700 | .init = &vaapi_encode_mpeg2_init, |
| 698 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 701 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 699 | .close = &vaapi_encode_mpeg2_close, | 702 | .close = &vaapi_encode_mpeg2_close, |
| 700 | .p.priv_class = &vaapi_encode_mpeg2_class, | 703 | .p.priv_class = &vaapi_encode_mpeg2_class, |
| 701 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 704 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |
| @@ -52,6 +52,7 @@ typedef struct VAAPIEncodeVP8Context { · 51 unmodified lines | |||
| 52 | 52 | ||
| 53 | static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) | 53 | static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) |
| 54 | { | 54 | { |
| 55 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 55 | VAAPIEncodeContext *ctx = avctx->priv_data; | 56 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 56 | VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params; | 57 | VAEncSequenceParameterBufferVP8 *vseq = ctx->codec_sequence_params; |
| 57 | 58 | ||
| @@ -66,22 +67,23 @@ static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) · 8 unmodified lines | |||
| 66 | 67 | ||
| 67 | if (!(ctx->va_rc_mode & VA_RC_CQP)) { | 68 | if (!(ctx->va_rc_mode & VA_RC_CQP)) { |
| 68 | vseq->bits_per_second = ctx->va_bit_rate; | 69 | vseq->bits_per_second = ctx->va_bit_rate; |
| 69 | vseq->intra_period = ctx->gop_size; | 70 | vseq->intra_period = base_ctx->gop_size; |
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | return 0; | 73 | return 0; |
| 73 | } | 74 | } |
| 74 | 75 | ||
| 75 | static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, | 76 | static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, |
| 76 | VAAPIEncodePicture *pic) | 77 | VAAPIEncodePicture *vaapi_pic) |
| 77 | { | 78 | { |
| 79 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 78 | VAAPIEncodeVP8Context *priv = avctx->priv_data; | 80 | VAAPIEncodeVP8Context *priv = avctx->priv_data; |
| 79 | VAEncPictureParameterBufferVP8 *vpic = pic->codec_picture_params; | 81 | VAEncPictureParameterBufferVP8 *vpic = vaapi_pic->codec_picture_params; |
| 80 | int i; | 82 | int i; |
| 81 | 83 | ||
| 82 | vpic->reconstructed_frame = pic->recon_surface; | 84 | vpic->reconstructed_frame = vaapi_pic->recon_surface; |
| 83 | 85 | ||
| 84 | vpic->coded_buf = pic->output_buffer; | 86 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 85 | 87 | ||
| 86 | switch (pic->type) { | 88 | switch (pic->type) { |
| 87 | case FF_HW_PICTURE_TYPE_IDR: | 89 | case FF_HW_PICTURE_TYPE_IDR: |
| @@ -101,7 +103,7 @@ static int vaapi_encode_vp8_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines | |||
| 101 | vpic->ref_last_frame = | 103 | vpic->ref_last_frame = |
| 102 | vpic->ref_gf_frame = | 104 | vpic->ref_gf_frame = |
| 103 | vpic->ref_arf_frame = | 105 | vpic->ref_arf_frame = |
| 104 | pic->refs[0][0]->recon_surface; | 106 | ((VAAPIEncodePicture *)pic->refs[0][0])->recon_surface; |
| 105 | break; | 107 | break; |
| 106 | default: | 108 | default: |
| 107 | av_assert0(0 && "invalid picture type"); | 109 | av_assert0(0 && "invalid picture type"); |
| @@ -145,7 +147,7 @@ static int vaapi_encode_vp8_write_quant_table(AVCodecContext *avctx, · 37 unmodified lines | |||
| 145 | 147 | ||
| 146 | memset(&quant, 0, sizeof(quant)); | 148 | memset(&quant, 0, sizeof(quant)); |
| 147 | 149 | ||
| 148 | if (pic->type == FF_HW_PICTURE_TYPE_P) | 150 | if (pic->base.type == FF_HW_PICTURE_TYPE_P) |
| 149 | q = priv->q_index_p; | 151 | q = priv->q_index_p; |
| 150 | else | 152 | else |
| 151 | q = priv->q_index_i; | 153 | q = priv->q_index_i; |
| @@ -250,7 +252,7 @@ const FFCodec ff_vp8_vaapi_encoder = { · 98 unmodified lines | |||
| 250 | .p.id = AV_CODEC_ID_VP8, | 252 | .p.id = AV_CODEC_ID_VP8, |
| 251 | .priv_data_size = sizeof(VAAPIEncodeVP8Context), | 253 | .priv_data_size = sizeof(VAAPIEncodeVP8Context), |
| 252 | .init = &vaapi_encode_vp8_init, | 254 | .init = &vaapi_encode_vp8_init, |
| 253 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 255 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 254 | .close = &ff_vaapi_encode_close, | 256 | .close = &ff_vaapi_encode_close, |
| 255 | .p.priv_class = &vaapi_encode_vp8_class, | 257 | .p.priv_class = &vaapi_encode_vp8_class, |
| 256 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 258 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |
| @@ -53,6 +53,7 @@ typedef struct VAAPIEncodeVP9Context { · 52 unmodified lines | |||
| 53 | 53 | ||
| 54 | static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) | 54 | static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) |
| 55 | { | 55 | { |
| 56 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; | ||
| 56 | VAAPIEncodeContext *ctx = avctx->priv_data; | 57 | VAAPIEncodeContext *ctx = avctx->priv_data; |
| 57 | VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params; | 58 | VAEncSequenceParameterBufferVP9 *vseq = ctx->codec_sequence_params; |
| 58 | VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params; | 59 | VAEncPictureParameterBufferVP9 *vpic = ctx->codec_picture_params; |
| @@ -64,7 +65,7 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines | |||
| 64 | 65 | ||
| 65 | if (!(ctx->va_rc_mode & VA_RC_CQP)) { | 66 | if (!(ctx->va_rc_mode & VA_RC_CQP)) { |
| 66 | vseq->bits_per_second = ctx->va_bit_rate; | 67 | vseq->bits_per_second = ctx->va_bit_rate; |
| 67 | vseq->intra_period = ctx->gop_size; | 68 | vseq->intra_period = base_ctx->gop_size; |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | vpic->frame_width_src = avctx->width; | 71 | vpic->frame_width_src = avctx->width; |
| @@ -76,17 +77,18 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) · 5 unmodified lines | |||
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, | 79 | static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, |
| 79 | VAAPIEncodePicture *pic) | 80 | VAAPIEncodePicture *vaapi_pic) |
| 80 | { | 81 | { |
| 81 | VAAPIEncodeContext *ctx = avctx->priv_data; | 82 | FFHWBaseEncodeContext *base_ctx = avctx->priv_data; |
| 82 | VAAPIEncodeVP9Context *priv = avctx->priv_data; | 83 | VAAPIEncodeVP9Context *priv = avctx->priv_data; |
| 84 | const FFHWBaseEncodePicture *pic = &vaapi_pic->base; | ||
| 83 | VAAPIEncodeVP9Picture *hpic = pic->priv_data; | 85 | VAAPIEncodeVP9Picture *hpic = pic->priv_data; |
| 84 | VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params; | 86 | VAEncPictureParameterBufferVP9 *vpic = vaapi_pic->codec_picture_params; |
| 85 | int i; | 87 | int i; |
| 86 | int num_tile_columns; | 88 | int num_tile_columns; |
| 87 | 89 | ||
| 88 | vpic->reconstructed_frame = pic->recon_surface; | 90 | vpic->reconstructed_frame = vaapi_pic->recon_surface; |
| 89 | vpic->coded_buf = pic->output_buffer; | 91 | vpic->coded_buf = vaapi_pic->output_buffer; |
| 90 | 92 | ||
| 91 | // Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64) | 93 | // Maximum width of a tile in units of superblocks is MAX_TILE_WIDTH_B64(64) |
| 92 | // So the number of tile columns is related to the width of the picture. | 94 | // So the number of tile columns is related to the width of the picture. |
| @@ -107,7 +109,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 14 unmodified lines | |||
| 107 | VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data; | 109 | VAAPIEncodeVP9Picture *href = pic->refs[0][0]->priv_data; |
| 108 | av_assert0(href->slot == 0 || href->slot == 1); | 110 | av_assert0(href->slot == 0 || href->slot == 1); |
| 109 | 111 | ||
| 110 | if (ctx->max_b_depth > 0) { | 112 | if (base_ctx->max_b_depth > 0) { |
| 111 | hpic->slot = !href->slot; | 113 | hpic->slot = !href->slot; |
| 112 | vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc; | 114 | vpic->refresh_frame_flags = 1 << hpic->slot | 0xfc; |
| 113 | } else { | 115 | } else { |
| @@ -127,7 +129,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 13 unmodified lines | |||
| 127 | av_assert0(href0->slot < pic->b_depth + 1 && | 129 | av_assert0(href0->slot < pic->b_depth + 1 && |
| 128 | href1->slot < pic->b_depth + 1); | 130 | href1->slot < pic->b_depth + 1); |
| 129 | 131 | ||
| 130 | if (pic->b_depth == ctx->max_b_depth) { | 132 | if (pic->b_depth == base_ctx->max_b_depth) { |
| 131 | // Unreferenced frame. | 133 | // Unreferenced frame. |
| 132 | vpic->refresh_frame_flags = 0x00; | 134 | vpic->refresh_frame_flags = 0x00; |
| 133 | hpic->slot = 8; | 135 | hpic->slot = 8; |
| @@ -159,11 +161,11 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, · 25 unmodified lines | |||
| 159 | 161 | ||
| 160 | for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { | 162 | for (i = 0; i < MAX_REFERENCE_LIST_NUM; i++) { |
| 161 | for (int j = 0; j < pic->nb_refs[i]; j++) { | 163 | for (int j = 0; j < pic->nb_refs[i]; j++) { |
| 162 | VAAPIEncodePicture *ref_pic = pic->refs[i][j]; | 164 | FFHWBaseEncodePicture *ref_pic = pic->refs[i][j]; |
| 163 | int slot; | 165 | int slot; |
| 164 | slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot; | 166 | slot = ((VAAPIEncodeVP9Picture*)ref_pic->priv_data)->slot; |
| 165 | av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); | 167 | av_assert0(vpic->reference_frames[slot] == VA_INVALID_SURFACE); |
| 166 | vpic->reference_frames[slot] = ref_pic->recon_surface; | 168 | vpic->reference_frames[slot] = ((VAAPIEncodePicture *)ref_pic)->recon_surface; |
| 167 | } | 169 | } |
| 168 | } | 170 | } |
| 169 | 171 | ||
| @@ -307,7 +309,7 @@ const FFCodec ff_vp9_vaapi_encoder = { · 137 unmodified lines | |||
| 307 | .p.id = AV_CODEC_ID_VP9, | 309 | .p.id = AV_CODEC_ID_VP9, |
| 308 | .priv_data_size = sizeof(VAAPIEncodeVP9Context), | 310 | .priv_data_size = sizeof(VAAPIEncodeVP9Context), |
| 309 | .init = &vaapi_encode_vp9_init, | 311 | .init = &vaapi_encode_vp9_init, |
| 310 | FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet), | 312 | FF_CODEC_RECEIVE_PACKET_CB(&ff_hw_base_encode_receive_packet), |
| 311 | .close = &ff_vaapi_encode_close, | 313 | .close = &ff_vaapi_encode_close, |
| 312 | .p.priv_class = &vaapi_encode_vp9_class, | 314 | .p.priv_class = &vaapi_encode_vp9_class, |
| 313 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | | 315 | .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE | |