vaapi_video_encoder_delegate.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/gpu/vaapi/vaapi_video_encoder_delegate.h"
  5. #include <va/va.h>
  6. #include "base/memory/ref_counted_memory.h"
  7. #include "media/base/video_frame.h"
  8. #include "media/gpu/codec_picture.h"
  9. #include "media/gpu/gpu_video_encode_accelerator_helpers.h"
  10. #include "media/gpu/macros.h"
  11. #include "media/gpu/vaapi/va_surface.h"
  12. #include "media/gpu/vaapi/vaapi_utils.h"
  13. #include "media/gpu/vaapi/vaapi_wrapper.h"
  14. #include "media/video/video_encode_accelerator.h"
  15. namespace media {
  16. VaapiVideoEncoderDelegate::EncodeJob::EncodeJob(
  17. bool keyframe,
  18. base::TimeDelta timestamp,
  19. VASurfaceID input_surface_id,
  20. scoped_refptr<CodecPicture> picture,
  21. std::unique_ptr<ScopedVABuffer> coded_buffer)
  22. : keyframe_(keyframe),
  23. timestamp_(timestamp),
  24. input_surface_id_(input_surface_id),
  25. picture_(std::move(picture)),
  26. coded_buffer_(std::move(coded_buffer)) {
  27. DCHECK(picture_);
  28. DCHECK(coded_buffer_);
  29. }
  30. VaapiVideoEncoderDelegate::EncodeJob::EncodeJob(bool keyframe,
  31. base::TimeDelta timestamp,
  32. VASurfaceID input_surface_id)
  33. : keyframe_(keyframe),
  34. timestamp_(timestamp),
  35. input_surface_id_(input_surface_id) {}
  36. VaapiVideoEncoderDelegate::EncodeJob::~EncodeJob() = default;
  37. std::unique_ptr<VaapiVideoEncoderDelegate::EncodeResult>
  38. VaapiVideoEncoderDelegate::EncodeJob::CreateEncodeResult(
  39. const BitstreamBufferMetadata& metadata) && {
  40. return std::make_unique<EncodeResult>(std::move(coded_buffer_), metadata);
  41. }
  42. base::TimeDelta VaapiVideoEncoderDelegate::EncodeJob::timestamp() const {
  43. return timestamp_;
  44. }
  45. VABufferID VaapiVideoEncoderDelegate::EncodeJob::coded_buffer_id() const {
  46. return coded_buffer_->id();
  47. }
  48. VASurfaceID VaapiVideoEncoderDelegate::EncodeJob::input_surface_id() const {
  49. return input_surface_id_;
  50. }
  51. const scoped_refptr<CodecPicture>&
  52. VaapiVideoEncoderDelegate::EncodeJob::picture() const {
  53. return picture_;
  54. }
  55. VaapiVideoEncoderDelegate::EncodeResult::EncodeResult(
  56. std::unique_ptr<ScopedVABuffer> coded_buffer,
  57. const BitstreamBufferMetadata& metadata)
  58. : coded_buffer_(std::move(coded_buffer)), metadata_(metadata) {}
  59. VaapiVideoEncoderDelegate::EncodeResult::~EncodeResult() = default;
  60. VABufferID VaapiVideoEncoderDelegate::EncodeResult::coded_buffer_id() const {
  61. return coded_buffer_->id();
  62. }
  63. const BitstreamBufferMetadata&
  64. VaapiVideoEncoderDelegate::EncodeResult::metadata() const {
  65. return metadata_;
  66. }
  67. VaapiVideoEncoderDelegate::VaapiVideoEncoderDelegate(
  68. scoped_refptr<VaapiWrapper> vaapi_wrapper,
  69. base::RepeatingClosure error_cb)
  70. : vaapi_wrapper_(vaapi_wrapper), error_cb_(error_cb) {
  71. DETACH_FROM_SEQUENCE(sequence_checker_);
  72. }
  73. VaapiVideoEncoderDelegate::~VaapiVideoEncoderDelegate() = default;
  74. size_t VaapiVideoEncoderDelegate::GetBitstreamBufferSize() const {
  75. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  76. return GetEncodeBitstreamBufferSize(GetCodedSize());
  77. }
  78. void VaapiVideoEncoderDelegate::BitrateControlUpdate(
  79. uint64_t encoded_chunk_size_bytes) {
  80. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  81. }
  82. BitstreamBufferMetadata VaapiVideoEncoderDelegate::GetMetadata(
  83. const EncodeJob& encode_job,
  84. size_t payload_size) {
  85. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  86. return BitstreamBufferMetadata(payload_size, encode_job.IsKeyframeRequested(),
  87. encode_job.timestamp());
  88. }
  89. bool VaapiVideoEncoderDelegate::Encode(EncodeJob& encode_job) {
  90. if (!PrepareEncodeJob(encode_job)) {
  91. VLOGF(1) << "Failed preparing an encode job";
  92. return false;
  93. }
  94. if (!vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(
  95. encode_job.input_surface_id())) {
  96. VLOGF(1) << "Failed to execute encode";
  97. return false;
  98. }
  99. return true;
  100. }
  101. std::unique_ptr<VaapiVideoEncoderDelegate::EncodeResult>
  102. VaapiVideoEncoderDelegate::GetEncodeResult(
  103. std::unique_ptr<EncodeJob> encode_job) {
  104. const VASurfaceID va_surface_id = encode_job->input_surface_id();
  105. const uint64_t encoded_chunk_size = vaapi_wrapper_->GetEncodedChunkSize(
  106. encode_job->coded_buffer_id(), va_surface_id);
  107. if (encoded_chunk_size == 0) {
  108. VLOGF(1) << "Invalid encoded chunk size";
  109. return nullptr;
  110. }
  111. BitrateControlUpdate(encoded_chunk_size);
  112. auto metadata = GetMetadata(*encode_job, encoded_chunk_size);
  113. return std::move(*encode_job).CreateEncodeResult(metadata);
  114. }
  115. } // namespace media