-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathbuffer.cpp
More file actions
95 lines (78 loc) · 2.25 KB
/
Copy pathbuffer.cpp
File metadata and controls
95 lines (78 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "libspdl/cuda/nvdec/detail/buffer.h"
#include "libspdl/core/detail/tracing.h"
#include "libspdl/cuda/detail/utils.h"
#include <cuda.h>
#include <fmt/core.h>
#include <fmt/format.h>
namespace spdl::cuda::detail {
FrameBuffer::FrameBuffer(
size_t num_frames,
size_t width,
size_t height,
const CUDAConfig& cfg)
: shape_({num_frames, height + height / 2, width}), cfg_(cfg) {}
bool FrameBuffer::empty() const {
return queue_.empty();
}
void FrameBuffer::push(void* src_ptr, size_t pitch) {
if (!current_) {
current_ = cuda_buffer(shape_, cfg_);
idx_ = 0;
}
// get the next buffer point
auto h2 = shape_[1], width = shape_[2];
size_t offset = idx_ * h2 * width;
auto* dst_ptr = (uint8_t*)current_->data() + offset;
// Perform copy
CUDA_MEMCPY2D cfg{
.srcXInBytes = 0,
.srcY = 0,
.srcMemoryType = CU_MEMORYTYPE_DEVICE,
.srcHost = nullptr,
.srcDevice = (CUdeviceptr)src_ptr,
.srcArray = nullptr,
.srcPitch = pitch,
.dstXInBytes = 0,
.dstY = 0,
.dstMemoryType = CU_MEMORYTYPE_DEVICE,
.dstHost = nullptr,
.dstDevice = (CUdeviceptr)dst_ptr,
.dstArray = nullptr,
.dstPitch = width,
.WidthInBytes = width,
.Height = h2,
};
TRACE_EVENT("nvdec", "cuMemcpy2DAsync");
auto stream = (CUstream)cfg_.stream;
CHECK_CU(cuMemcpy2DAsync(&cfg, stream), "Failed to copy a frame.");
CHECK_CU(cuStreamSynchronize(stream), "Failed to synchronize stream.");
// Move the buffer if full
++idx_;
if (idx_ == shape_[0]) {
queue_.emplace_back(current_.release());
}
}
CUDABufferPtr FrameBuffer::pop() {
if (queue_.empty()) {
SPDL_FAIL_INTERNAL(fmt::format("There is no buffer available."));
}
CUDABufferPtr ret = std::move(queue_.front());
queue_.pop_front();
return ret;
}
void FrameBuffer::flush() {
if (current_ && idx_ > 0) {
// Adjust shape to reflect actual number of frames
current_->shape[0] = idx_;
queue_.emplace_back(current_.release());
idx_ = 0;
}
}
}; // namespace spdl::cuda::detail