Using rocPyDecode#
RocPyDecode is a python library module which allows python decoding functionality using rocDecode C++ SDK library backend.
1. API overview#
All rocPyDecode APIs are exposed using the header files decoder.py
and demuxer.py
. You can find
these files in the pyRocVideoDecode folder in the rocPyDecode github repository.
For detailed explanation of rocDecode API, please refer to rocDecode documentation.
The samples uses the pyRocVideoDecode
python module to interface with the low level rocVideoDecode
class available in the C++ rocDecode library.
The pyRocVideoDecode
module exposes the following APIs through two python classes PyRocVideoDecoder
and PyVideoDemuxer
.
- class PyRocVideoDecoder (Video decoder class)
GetDeviceinfo(self)
-> API to get device information of the current deviceSetReconfigParams(self)
-> API to reconfigure decoder when thre is codec/resolution changesDecodeFrame(self)
-> API to trigger decoding of a frame through the low level decoderGetFrame(self)
-> API to receive a decoded output frame in video memorySaveFrameToFile(self)
-> API to bring back the decoded output frame to host and save it to a fileReleaseFrame(self)
-> API to release the decoded frame after useGetOutputSurfaceInfo(self)
-> API to get the output surface information like resolution, bit_depth and color_format of the decoded frameGetNumOfFlushedFrames(self)
-> API to get the number of flushed frames during reconfigure
- class PyVideoDemuxer (python demuxer class)
GetCodecId(self)
-> API to get the Codec_id of the current stream from the demuxerDemuxFrame(self)
-> API to demultiplex a frame using FFMPEG API
The workflow of rocPyDecode
is exactly similar to the rocDecode
C++ library. Please refer to rocDecode documentation for further details.
2. Create a decoder instance using rocPyDecode#
PyRocVideoDecoder()
python module creates an instance of video decoder underneath and exposes C++ APIs to python using pybind.
PyRocVideoDecoder()
in turn creates an instance of RocVideoDecoder()
class and returns a handle upon successful creation.
3. Decoding video frames using PyRocVideoDecoder()
#
After de-multiplexing and parsing, the user can decode bitstream data containing a frame/field in hardware.
Use the DecodeFrame()
API to submit a new frame for hardware decoding. Underneath the
driver, the Video Acceleration API (VA-API) is used to submit compressed picture data to the driver.
The parser extracts all the necessary information from the bitstream and fills the RocdecPicParams
structure that’s appropriate for the codec. The high-level RocVideoDecoder
class connects the parser
and decoder used for all sample applications.
The DecodeFrame()
function will call the C++ rocDecDecodeFrame()
api which takes the decoder handle and the pointer to
the RocdecPicParams
structure and initiates the video decoding using VA-API.
4. Using the decoded frame for further processing#
The decoded frames can be used for further postprocessing using GetFrame()
API. The
successful completion of GetFrame()
indicates that the decoding process is complete and
the device memory pointer is inter-opped into the ROCm HIP address space in order to further process
the decoded frame in device memory. The caller gets the necessary information of the output surface,
such as YUV format, dimensions, and pitch by calling the GetOutputSurfaceInfo()
api call.
In the high-level RocVideoDecoder
class, we provide four different surface_type modes for the mapped surface, as specified in
OutputSurfaceMemoryType. Please refer to rocDecode documentation for further details on these modes.
typedef enum OutputSurfaceMemoryType_enum {
OUT_SURFACE_MEM_DEV_INTERNAL = 0, /**< Internal interopped decoded surface memory **/
OUT_SURFACE_MEM_DEV_COPIED = 1, /**< decoded output will be copied to a separate device memory **/
OUT_SURFACE_MEM_HOST_COPIED = 2 /**< decoded output will be copied to a separate host memory **/
OUT_SURFACE_MEM_NOT_MAPPED = 3 /**< decoded output is not available (interop won't be used): useful for decode only performance app*/
} OutputSurfaceMemoryType;
If the mapped surface type is OUT_SURFACE_MEM_DEV_INTERNAL
, the direct pointer to the decoded
surface is provided. You must call ReleaseFrame()
(RocVideoDecoder
class). If the requested surface
type is OUT_SURFACE_MEM_DEV_COPIED
or OUT_SURFACE_MEM_HOST_COPIED
, the internal
decoded frame is copied to another buffer, either in device memory or host memory. After that, it’s
immediately unmapped for re-use by the RocVideoDecoder
class.
PyRocVideoDecoder()
can pass the appropriate mem_type to rocVideoDecoder
class on creation.
Refer to the PyRocVideoDecoder
class and
samples for details on how to use
these APIs and various use-case examples
5. Reconfiguring the decoder#
SetReconfigParams()
api is used to set reconfig parameters from Python to the low_level video decoder.
The C++ library uses rocDecReconfigureDecoder()
to reuse a single decoder for multiple clips or when the
video resolution changes during the decode. The API currently supports resolution changes, resize
parameter changes, and target area parameter changes for the same codec without destroying an
ongoing decoder instance. This can improve performance and reduce overall latency.
6. Destroying the decoder instance#
The decoder resources will be destroyed when the Python class object is released.