| /* |
| * Copyright 2020 Google LLC |
| * |
| */ |
| |
| /* |
| * Copyright (c) 2020, Alliance for Open Media. All rights reserved |
| * |
| * This source code is subject to the terms of the BSD 2 Clause License and |
| * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| * was not distributed with this source code in the LICENSE file, you can |
| * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| * Media Patent License 1.0 was not distributed with this source code in the |
| * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| */ |
| |
| #pragma once |
| #include "frame_queue.h" |
| #include "log.h" |
| #include <vector> |
| #include <list> |
| #include <mutex> |
| #include <memory> |
| #include "aom/aom_decoder.h" |
| |
| #include <wrl.h> |
| #include <wrl/client.h> |
| #include <d3d12.h> |
| #include <assert.h> |
| |
| using namespace Microsoft::WRL; |
| |
| #define MEM_BLOCK_SIZE 65536 |
| #define TEXTURE_MEM_ALIGNMENT 256 |
| #define TEXTURE_MEM_ALIGNMENT_1 (TEXTURE_MEM_ALIGNMENT - 1) |
| #define TEXTURE_MEM_ALIGNMENT_SHIFT 8 |
| #define MEM_ALIGN_64K (1 << 16) |
| |
| typedef struct OutBuffer { |
| void* pMem; |
| size_t memSize; |
| uint32_t frameWidth; |
| uint32_t frameHeight; |
| |
| uint32_t renderWidth; |
| uint32_t renderHeight; |
| |
| uint8_t* planes[3]; |
| uint32_t strides[3]; |
| frame_buffer_type fb_type; |
| ComPtr<ID3D12Resource> d3d12buffer; |
| ComPtr<ID3D12Resource> d3d12textures[3]; |
| size_t buffer_size; |
| |
| uint64_t pts; |
| uint32_t frame_no; |
| uint32_t frame_no_offset; |
| uint32_t shown; |
| OutBuffer() { memset(this, 0, sizeof(OutBuffer)); } |
| ~OutBuffer() {} |
| void Reset() { |
| for (int i = 0; i < 3; i++) { |
| d3d12textures[i].Reset(); |
| d3d12buffer.Reset(); |
| planes[i] = 0; |
| strides[i] = 0; |
| } |
| pMem = 0; |
| memSize = 0; |
| renderWidth = 0; |
| renderHeight = 0; |
| frameWidth = 0; |
| frameHeight = 0; |
| fb_type = fbtNone; |
| } |
| } OutBuffer; |
| |
| class OutBufferStorage; |
| class OutBufferWrapper { |
| public: |
| OutBufferWrapper(OutBuffer* buffer, OutBufferStorage* storage) : buffer_(buffer), storage_(storage) {} |
| ~OutBufferWrapper(); |
| OutBuffer* Buffer() { return buffer_; } |
| uint32_t Shown() { return buffer_->shown; } |
| void SetShown(uint32_t val) { buffer_->shown = val; } |
| void ReleaseRented(); |
| |
| private: |
| OutBuffer* buffer_; |
| OutBufferStorage* storage_; |
| }; |
| |
| typedef enum { CBUFREADBACK = 0x1, CBUFTEXTURE = 0x2, CBUFALL = 0x3 } cbufFlags; |
| |
| class OutBufferStorage { |
| public: |
| OutBufferStorage(int queue_size, ID3D12Device* dx12_device); |
| ~OutBufferStorage() { |
| if (queue_free_.Size() != queue_size_) { |
| XB_LOGE << "OutBufferStorage still has unreleashed buffers!! " << (queue_size_ - queue_free_.Size()); |
| rented_.clear(); |
| XB_LOGE << "Release it anyway"; |
| } |
| } |
| |
| size_t GetSize() { return queue_free_.Size(); } |
| std::shared_ptr<OutBufferWrapper> GetFreeBuffer(uint32_t width, uint32_t height, frame_buffer_type fb_type, |
| size_t buffer_size, uint32_t flags); |
| std::shared_ptr<OutBufferWrapper> ReleaseRentedBuffer(void* ptr); |
| std::shared_ptr<OutBufferWrapper> FindRentedBuffer(void* ptr); |
| |
| private: |
| void Push(OutBuffer* frame); |
| friend class OutBufferWrapper; |
| |
| private: |
| std::vector<OutBuffer> storage_; |
| std::list<std::shared_ptr<OutBufferWrapper> > rented_; |
| myqueue<OutBuffer*> queue_free_; |
| int queue_size_; |
| std::mutex cs_; |
| ComPtr<ID3D12Device> dx12_device_; |
| }; |