Skip to content
This repository was archived by the owner on Jun 10, 2024. It is now read-only.

Commit e19e85a

Browse files
committed
Refactoring PyNvCodec module
1 parent 5742166 commit e19e85a

15 files changed

+2806
-2539
lines changed

.clang-format

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
# We'll use defaults from the LLVM style, but with 4 columns indentation.
3+
BasedOnStyle: LLVM
4+
IndentWidth: 2
5+
BreakBeforeBraces: Linux
6+
---
7+
Language: Cpp
8+
# Force pointers to the type for C++.
9+
DerivePointerAlignment: false
10+
PointerAlignment: Left

PyNvCodec/TC/src/MemoryInterfaces.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Copyright 2019 NVIDIA Corporation
33
* Copyright 2021 Videonetics Technology Private Limited
4-
*
4+
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
66
* you may not use this file except in compliance with the License.
77
* You may obtain a copy of the License at
@@ -79,12 +79,12 @@ struct AllocRegister {
7979
}
8080
};
8181

82-
AllocRegister BuffersRegister, HWSurfaceRegister, CudaBuffersRegiser;
82+
AllocRegister BuffersRegister, HWSurfaceRegister, CudaBuffersRegister;
8383

8484
bool CheckAllocationCounters() {
8585
auto numLeakedBuffers = BuffersRegister.GetSize();
8686
auto numLeakedSurfaces = HWSurfaceRegister.GetSize();
87-
auto numLeakedCudaBuffers = CudaBuffersRegiser.GetSize();
87+
auto numLeakedCudaBuffers = CudaBuffersRegister.GetSize();
8888

8989
if (numLeakedBuffers) {
9090
cerr << "Leaked buffers (id : size): " << endl;
@@ -105,10 +105,10 @@ bool CheckAllocationCounters() {
105105
if (numLeakedCudaBuffers) {
106106
cerr << "Leaked CUDA buffers (id : size): " << endl;
107107
for (auto i = 0; i < numLeakedCudaBuffers; i++) {
108-
auto pNote = CudaBuffersRegiser.GetNoteByIndex(i);
108+
auto pNote = CudaBuffersRegister.GetNoteByIndex(i);
109109
cerr << "\t" << pNote->id << "\t: " << pNote->size << endl;
110110
}
111-
}
111+
}
112112

113113
return (0U == numLeakedBuffers) && (0U == numLeakedSurfaces) && (0U == numLeakedCudaBuffers);
114114
}
@@ -309,7 +309,7 @@ bool CudaBuffer::Allocate() {
309309

310310
if (0U != gpuMem) {
311311
#ifdef TRACK_TOKEN_ALLOCATIONS
312-
id = CudaBuffersRegiser.AddNote(GetRawMemSize());
312+
id = CudaBuffersRegister.AddNote(GetRawMemSize());
313313
#endif
314314
return true;
315315
}
@@ -323,7 +323,7 @@ void CudaBuffer::Deallocate() {
323323

324324
#ifdef TRACK_TOKEN_ALLOCATIONS
325325
AllocInfo info(id, GetRawMemSize());
326-
CudaBuffersRegiser.DeleteNote(info);
326+
CudaBuffersRegister.DeleteNote(info);
327327
#endif
328328
}
329329

@@ -444,8 +444,8 @@ void SurfacePlane::Export(CUdeviceptr dst, uint32_t dst_pitch, CUcontext ctx,
444444
}
445445

446446
SurfacePlane::SurfacePlane(uint32_t newWidth, uint32_t newHeight,
447-
uint32_t newElemSize, uint32_t srcPitch,
448-
CUdeviceptr src, CUcontext context, CUstream str)
447+
uint32_t newElemSize, uint32_t srcPitch,
448+
CUdeviceptr src, CUcontext context, CUstream str)
449449
: SurfacePlane(newWidth, newHeight, newElemSize, context) {
450450
Import(src, srcPitch, context, str);
451451
}

PyNvCodec/inc/PyNvCodec.hpp

Lines changed: 30 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ class CuvidParserException : public std::runtime_error {
6161
CuvidParserException() : std::runtime_error("HW reset") {}
6262
};
6363

64+
class CudaResMgr
65+
{
66+
private:
67+
CudaResMgr();
68+
69+
public:
70+
CUcontext GetCtx(size_t idx);
71+
CUstream GetStream(size_t idx);
72+
~CudaResMgr();
73+
static CudaResMgr& Instance();
74+
static size_t GetNumGpus();
75+
76+
std::vector<std::pair<CUdevice, CUcontext>> g_Contexts;
77+
std::vector<CUstream> g_Streams;
78+
79+
static std::mutex gInsMutex;
80+
static std::mutex gCtxMutex;
81+
static std::mutex gStrMutex;
82+
};
83+
6484
class PyFrameUploader {
6585
std::unique_ptr<CudaUploadFrame> uploader;
6686
uint32_t surfaceWidth, surfaceHeight;
@@ -95,7 +115,7 @@ class PyBufferUploader {
95115
CUstream str);
96116

97117
PyBufferUploader(uint32_t elemSize, uint32_t numElems,
98-
size_t ctx, size_t str) :
118+
size_t ctx, size_t str) :
99119
PyBufferUploader(elemSize, numElems, (CUcontext)ctx, (CUstream)str) {}
100120

101121
std::shared_ptr<CudaBuffer> UploadSingleBuffer(py::array_t<uint8_t> &buffer);
@@ -136,7 +156,7 @@ class PyCudaBufferDownloader {
136156
CUstream str);
137157

138158
PyCudaBufferDownloader(uint32_t elemSize, uint32_t numElems,
139-
size_t ctx, size_t str) :
159+
size_t ctx, size_t str) :
140160
PyCudaBufferDownloader(elemSize, numElems, (CUcontext)ctx, (CUstream)str) {}
141161

142162
bool DownloadSingleCudaBuffer(std::shared_ptr<CudaBuffer> buffer,
@@ -275,11 +295,11 @@ class PyNvDecoder {
275295
PyNvDecoder(pathToFile, (CUcontext)ctx, (CUstream)str, ffmpeg_options){}
276296

277297
static Buffer *getElementaryVideo(DemuxFrame *demuxer,
278-
SeekContext &seek_ctx, bool needSEI);
298+
SeekContext *seek_ctx, bool needSEI);
279299

280300
static Surface *getDecodedSurface(NvdecDecodeFrame *decoder,
281301
DemuxFrame *demuxer,
282-
SeekContext &seek_ctx, bool needSEI);
302+
SeekContext *seek_ctx, bool needSEI);
283303

284304
uint32_t Width() const;
285305

@@ -305,148 +325,15 @@ class PyNvDecoder {
305325

306326
Pixel_Format GetPixelFormat() const;
307327

308-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(py::array_t<uint8_t> &packet,
309-
py::array_t<uint8_t> &sei);
310-
311-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(PacketData &enc_packet_data,
312-
py::array_t<uint8_t> &packet,
313-
py::array_t<uint8_t> &sei);
314-
315-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(py::array_t<uint8_t> &packet,
316-
py::array_t<uint8_t> &sei,
317-
PacketData &pkt_data);
318-
319-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(PacketData &enc_packet_data,
320-
py::array_t<uint8_t> &packet,
321-
py::array_t<uint8_t> &sei,
322-
PacketData &pkt_data);
323-
324-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(py::array_t<uint8_t> &packet);
325-
326-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(PacketData &enc_packet_data,
327-
py::array_t<uint8_t> &packet);
328-
329-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(py::array_t<uint8_t> &packet,
330-
PacketData &pkt_data);
331-
332-
std::shared_ptr<Surface> DecodeSurfaceFromPacket(PacketData &enc_packet_data,
333-
py::array_t<uint8_t> &packet,
334-
PacketData &pkt_data);
335-
336-
std::shared_ptr<Surface> DecodeSingleSurface(py::array_t<uint8_t> &sei);
337-
338-
std::shared_ptr<Surface> DecodeSingleSurface(py::array_t<uint8_t> &sei,
339-
PacketData &pkt_data);
340-
341-
std::shared_ptr<Surface> DecodeSingleSurface(py::array_t<uint8_t> &sei,
342-
SeekContext &ctx);
343-
344-
std::shared_ptr<Surface> DecodeSingleSurface(py::array_t<uint8_t> &sei,
345-
SeekContext &ctx,
346-
PacketData &pkt_data);
347-
348-
std::shared_ptr<Surface> DecodeSingleSurface();
349-
350-
std::shared_ptr<Surface> DecodeSingleSurface(PacketData &pkt_data);
351-
352-
std::shared_ptr<Surface> DecodeSingleSurface(SeekContext &ctx);
353-
354-
std::shared_ptr<Surface> DecodeSingleSurface(SeekContext &ctx,
355-
PacketData &pkt_data);
356-
357-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
358-
py::array_t<uint8_t> &sei);
359-
360-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
361-
py::array_t<uint8_t> &sei,
362-
PacketData &pkt_data);
363-
364-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
365-
py::array_t<uint8_t> &sei,
366-
SeekContext &ctx);
328+
bool DecodeSurface(class DecodeContext &ctx);
367329

368-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
369-
py::array_t<uint8_t> &sei,
370-
SeekContext &ctx,
371-
PacketData &pkt_data);
330+
bool DecodeFrame(class DecodeContext &ctx, py::array_t<uint8_t>& frame);
372331

373-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame);
374-
375-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
376-
PacketData &pkt_data);
377-
378-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
379-
SeekContext &ctx);
380-
381-
bool DecodeSingleFrame(py::array_t<uint8_t> &frame,
382-
SeekContext &ctx,
383-
PacketData &pkt_data);
384-
385-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
386-
py::array_t<uint8_t> &packet,
387-
py::array_t<uint8_t> &sei);
388-
389-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
390-
PacketData &enc_packet_data,
391-
py::array_t<uint8_t> &packet,
392-
py::array_t<uint8_t> &sei);
393-
394-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
395-
py::array_t<uint8_t> &packet,
396-
py::array_t<uint8_t> &sei,
397-
PacketData &pkt_data);
398-
399-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
400-
PacketData &enc_packet_data,
401-
py::array_t<uint8_t> &packet,
402-
py::array_t<uint8_t> &sei,
403-
PacketData &pkt_data);
404-
405-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
406-
py::array_t<uint8_t> &packet);
407-
408-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
409-
PacketData &enc_packet_data,
410-
py::array_t<uint8_t> &packet);
411-
412-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
413-
py::array_t<uint8_t> &packet,
414-
PacketData &pkt_data);
415-
416-
bool DecodeFrameFromPacket(py::array_t<uint8_t> &frame,
417-
PacketData &enc_packet_data,
418-
py::array_t<uint8_t> &packet,
419-
PacketData &pkt_data);
420-
421-
bool FlushSingleFrame(py::array_t<uint8_t> &frame);
422-
423-
bool FlushSingleFrame(py::array_t<uint8_t> &frame, PacketData &pkt_data);
424-
425-
std::shared_ptr<Surface> FlushSingleSurface();
426-
427-
std::shared_ptr<Surface> FlushSingleSurface(PacketData &pkt_data);
428-
429-
private:
430-
bool DecodeSurface(struct DecodeContext &ctx);
431-
432-
Surface *getDecodedSurfaceFromPacket(py::array_t<uint8_t> *pPacket,
433-
PacketData *p_packet_data = nullptr,
332+
Surface *getDecodedSurfaceFromPacket(const py::array_t<uint8_t> *pPacket,
333+
const PacketData *p_packet_data = nullptr,
434334
bool no_eos = false);
435-
};
436335

437-
struct EncodeContext {
438-
std::shared_ptr<Surface> rawSurface;
439-
py::array_t<uint8_t> *pPacket;
440-
const py::array_t<uint8_t> *pMessageSEI;
441-
bool sync;
442-
bool append;
443-
444-
EncodeContext(std::shared_ptr<Surface> spRawSurface,
445-
py::array_t<uint8_t> *packet,
446-
const py::array_t<uint8_t> *messageSEI, bool is_sync,
447-
bool is_append)
448-
: rawSurface(spRawSurface), pPacket(packet), pMessageSEI(messageSEI),
449-
sync(is_sync), append(is_append) {}
336+
void DownloaderLazyInit();
450337
};
451338

452339
class PyNvEncoder {
@@ -523,5 +410,5 @@ class PyNvEncoder {
523410
bool FlushSinglePacket(py::array_t<uint8_t> &packet);
524411

525412
private:
526-
bool EncodeSingleSurface(EncodeContext &ctx);
413+
bool EncodeSingleSurface(struct EncodeContext &ctx);
527414
};

PyNvCodec/src/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,15 @@
1616

1717
set(PYNVCODEC_SOURCES
1818
${CMAKE_CURRENT_SOURCE_DIR}/PyNvCodec.cpp
19+
${CMAKE_CURRENT_SOURCE_DIR}/PyFrameUploader.cpp
20+
${CMAKE_CURRENT_SOURCE_DIR}/PyBufferUploader.cpp
21+
${CMAKE_CURRENT_SOURCE_DIR}/PySurfaceDownloader.cpp
22+
${CMAKE_CURRENT_SOURCE_DIR}/PyCudaBufferDownloader.cpp
23+
${CMAKE_CURRENT_SOURCE_DIR}/PySurfaceConverter.cpp
24+
${CMAKE_CURRENT_SOURCE_DIR}/PySurfaceResizer.cpp
25+
${CMAKE_CURRENT_SOURCE_DIR}/PyFFMpegDecoder.cpp
26+
${CMAKE_CURRENT_SOURCE_DIR}/PyFFMpegDemuxer.cpp
27+
${CMAKE_CURRENT_SOURCE_DIR}/PyNvDecoder.cpp
28+
${CMAKE_CURRENT_SOURCE_DIR}/PyNvEncoder.cpp
1929
PARENT_SCOPE
2030
)

PyNvCodec/src/PyBufferUploader.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2019 NVIDIA Corporation
3+
* Copyright 2021 Kognia Sports Intelligence
4+
* Copyright 2021 Videonetics Technology Private Limited
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "PyNvCodec.hpp"
18+
19+
using namespace std;
20+
using namespace VPF;
21+
using namespace chrono;
22+
23+
namespace py = pybind11;
24+
25+
constexpr auto TASK_EXEC_SUCCESS = TaskExecStatus::TASK_EXEC_SUCCESS;
26+
constexpr auto TASK_EXEC_FAIL = TaskExecStatus::TASK_EXEC_FAIL;
27+
28+
PyBufferUploader::PyBufferUploader(uint32_t elemSize, uint32_t numElems,
29+
uint32_t gpu_ID)
30+
{
31+
elem_size = elemSize;
32+
num_elems = numElems;
33+
34+
uploader.reset(UploadBuffer::Make(CudaResMgr::Instance().GetStream(gpu_ID),
35+
CudaResMgr::Instance().GetCtx(gpu_ID),
36+
elem_size, num_elems));
37+
}
38+
39+
PyBufferUploader::PyBufferUploader(uint32_t elemSize, uint32_t numElems,
40+
CUcontext ctx, CUstream str)
41+
{
42+
elem_size = elemSize;
43+
num_elems = numElems;
44+
45+
uploader.reset(UploadBuffer::Make(str, ctx, elem_size, num_elems));
46+
}
47+
48+
shared_ptr<CudaBuffer>
49+
PyBufferUploader::UploadSingleBuffer(py::array_t<uint8_t>& frame)
50+
{
51+
auto pRawBuf = Buffer::Make(frame.size(), frame.mutable_data());
52+
uploader->SetInput(pRawBuf, 0U);
53+
auto res = uploader->Execute();
54+
delete pRawBuf;
55+
56+
if (TASK_EXEC_FAIL == res)
57+
throw runtime_error("Error uploading frame to GPU");
58+
59+
auto pCudaBuffer = (CudaBuffer*)uploader->GetOutput(0U);
60+
if (!pCudaBuffer)
61+
throw runtime_error("Error uploading frame to GPU");
62+
63+
return shared_ptr<CudaBuffer>(pCudaBuffer->Clone());
64+
}
65+
66+
void Init_PyBufferUploader(py::module& m)
67+
{
68+
py::class_<PyBufferUploader>(m, "PyBufferUploader")
69+
.def(py::init<uint32_t, uint32_t, uint32_t>())
70+
.def(py::init<uint32_t, uint32_t, size_t, size_t>())
71+
.def("UploadSingleBuffer", &PyBufferUploader::UploadSingleBuffer,
72+
py::return_value_policy::take_ownership,
73+
py::call_guard<py::gil_scoped_release>());
74+
}

0 commit comments

Comments
 (0)