added howto use for the utility classes (#511)
* added howto use for the utility classes
* Update docs/conceptual/rocDecode-memory-types.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/conceptual/rocDecode-memory-types.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocDecode-bitstream.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocDecode-bitstream.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocDecode-bitstream.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocDecode-bitstream.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocdecode.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocdecode.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update using-rocDecode-ffmpeg.rst
* key frame -> keyframe
* `api` -> ``api``
* must -> need to
* added a sample walkthrough; removed the bitstream reader info; streamlined info
* Update docs/how-to/using-rocDecode-videodecode-sample.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocDecode-videodecode-sample.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update docs/how-to/using-rocdecode.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* Update rocDecode-samples.rst
* Update docs/how-to/using-rocdecode.rst
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
* updated tables and other minor things
* updated with Leo's suggestion
* Update using-rocDecode-ffmpeg.rst
* added detail to information about the frame buffers
* small changes based on feedback
* updated
---------
Co-authored-by: Leo Paoletti <164940351+lpaoletti@users.noreply.github.com>
Co-authored-by: Lakshmi Kumar <lakshmi.kumar@amd.com>
[ROCm/rocdecode commit: dcddb9d5ea]
Tá an tiomantas seo le fáil i:
tiomanta ag
GitHub
tuismitheoir
23309b2e4c
tiomantas
99b53ab2a5
@@ -0,0 +1,24 @@
|
||||
.. meta::
|
||||
:description: rocDecode memory types
|
||||
:keywords: parse video, parse, decode, video decoder, video decoding, rocDecode, AMD, ROCm, memory types
|
||||
|
||||
********************************************************************
|
||||
rocDecode surface data memory locations
|
||||
********************************************************************
|
||||
|
||||
Surface data memory refers to the memory used by rocDecode for decoded frames and processing results. There are three locations where surface data memory can be stored: device memory, host memory, and internal memory.
|
||||
|
||||
Device memory refers to GPU memory. It's optimized for operations performed by the GPU, avoiding unnecessary memory transfers between the device and the host. It's used for standalone GPU processing and high-performance computing tasks where multiple operations are performed on the same data.
|
||||
|
||||
|
||||
Host memory refers to CPU memory. It's suitable for when the memory needs to be accessed or manipulated by CPU-side applications or when data needs to be transferred between systems.
|
||||
|
||||
Internal memory refers to intermediate GPU memory that is shared between operators. It's optimized for operator chaining within GPU workflows. It keeps data localized on the GPU so it can be accessed by subsequent operations, reducing latency and improving throughput. For example, in image processing pipelines, the results of a resizing operator can directly feed into a filtering operator without needing to copy data to the host between each step. This optimization is especially useful for large datasets and real-time applications.
|
||||
|
||||
|
||||
The ``OutputSurfaceMemoryType_enum`` enum type defines ``OUT_SURFACE_MEM_DEV_COPIED``, ``OUT_SURFACE_MEM_HOST_COPIED``, and ``OUT_SURFACE_MEM_DEV_INTERNAL``, for the three different types of memory locations. ``OUT_SURFACE_MEM_DEV_COPIED`` indicates device, or GPU, memory. ``OUT_SURFACE_MEM_HOST_COPIED`` indicates host, or CPU, memory. And ``OUT_SURFACE_MEM_DEV_INTERNAL`` indicates intermediate GPU memory.
|
||||
|
||||
``OUT_SURFACE_MEM_DEV_COPIED`` is not supported when the FFmpeg decoder is used.
|
||||
|
||||
A fourth enum, ``OUT_SURFACE_MEM_NOT_MAPPED``, is used only for performance purposes. The decoded frames are not available when this memory type is used.
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
.. meta::
|
||||
:description: Using rocDecode with the FFMpeg demultiplexer
|
||||
:keywords: parse video, parse, rocDecode, AMD, ROCm, FFmpeg demuxer
|
||||
|
||||
********************************************************************
|
||||
Using the rocDecode FFmpeg demultiplexer
|
||||
********************************************************************
|
||||
|
||||
The rocDecode FFmpeg demultiplexer (demuxer) extracts coded picture data from digital media files.
|
||||
|
||||
To use the rocDecode FFmpeg demuxer , import the ``video_demuxer.h`` header file.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
#include "video_demuxer.h"
|
||||
|
||||
Instantiate a ``VideoDemuxer`` with the path to the video file. The ``GetCodecId`` and ``GetBitDepth`` functions can be used to obtain the video stream's codec ID and bit depth. The ``AVCodec2RocDecVideoCodec`` utility function converts the codec ID returned from the demuxer to its corresponding ``rocDecVideoCodec_enum`` value.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
VideoDemuxer *demuxer;
|
||||
demuxer = new VideoDemuxer(input_file_path.c_str());
|
||||
rocdec_codec_id = AVCodec2RocDecVideoCodec(demuxer->GetCodecID());
|
||||
bit_depth = demuxer->GetBitDepth();
|
||||
|
||||
Call ``Demux`` to extract frame data from the stream:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
demuxer->Demux(&pvideo, &n_video_bytes, &pts);
|
||||
|
||||
The demuxer will demultiplex frames sequentially starting at the beginning of the stream. To start the demultiplexing and decoding process from a different frame, create a seek context that specifies a seek criteria and a seek mode.
|
||||
|
||||
The seek criteria describes whether the demuxer needs to seek to a specific frame or seek to a specific timestamp. The seek mode indicates whether the demuxer should seek to the exact frame or to the previous keyframe.
|
||||
|
||||
The seek criteria is defined by the ``SeekCriteriaEnum`` enum and the seek mode is defined by the ``SeekModeEnum`` enum. Both the ``SeekCriteriaEnum`` and the ``SeekModeEnum`` are defined in ``video_demuxer.h``.
|
||||
|
||||
Set the seek criteria to ``SEEK_CRITERIA_FRAME_NUM`` to seek to a frame or to ``SEEK_CRITERIA_TIME_STAMP`` to seek to a timestamp. Set the seek mode to ``SEEK_MODE_EXACT_FRAME`` to seek to the exact frame or to ``SEEK_MODE_PREV_KEY_FRAME`` to seek to the previous keyframe.
|
||||
|
||||
From |videodecode|_:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
VideoSeekContext video_seek_ctx;
|
||||
[...]
|
||||
do {
|
||||
[...]
|
||||
if (seek_criteria == 1 && first_frame) {
|
||||
// use VideoSeekContext class to seek to given frame number
|
||||
video_seek_ctx.seek_frame_ = seek_to_frame;
|
||||
video_seek_ctx.seek_crit_ = SEEK_CRITERIA_FRAME_NUM;
|
||||
video_seek_ctx.seek_mode_ = (seek_mode ? SEEK_MODE_EXACT_FRAME : SEEK_MODE_PREV_KEY_FRAME);
|
||||
demuxer->Seek(video_seek_ctx, &pvideo, &n_video_bytes);
|
||||
pts = video_seek_ctx.out_frame_pts_;
|
||||
std::cout << "info: Number of frames that were decoded during seek - " << video_seek_ctx.num_frames_decoded_ << std::endl;
|
||||
first_frame = false;
|
||||
} else if (seek_criteria == 2 && first_frame) {
|
||||
// use VideoSeekContext class to seek to given timestamp
|
||||
video_seek_ctx.seek_frame_ = seek_to_frame;
|
||||
video_seek_ctx.seek_crit_ = SEEK_CRITERIA_TIME_STAMP;
|
||||
video_seek_ctx.seek_mode_ = (seek_mode ? SEEK_MODE_EXACT_FRAME : SEEK_MODE_PREV_KEY_FRAME);
|
||||
demuxer->Seek(video_seek_ctx, &pvideo, &n_video_bytes);
|
||||
pts = video_seek_ctx.out_frame_pts_;
|
||||
std::cout << "info: Duration of frame found after seek - " << video_seek_ctx.out_frame_duration_ << " ms" << std::endl;
|
||||
first_frame = false;
|
||||
} else {
|
||||
demuxer->Demux(&pvideo, &n_video_bytes, &pts);
|
||||
}
|
||||
[...]
|
||||
} while (n_video_bytes);
|
||||
|
||||
Delete the demuxer once demultiplexing is complete.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
delete demuxer;
|
||||
|
||||
.. |videodecode| replace:: ``videodecode.cpp``
|
||||
.. _videodecode: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecode/videodecode.cpp
|
||||
|
||||
.. |videodecoderaw| replace:: ``videodecoderaw.cpp``
|
||||
.. _videodecoderaw: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecodeRaw
|
||||
|
||||
.. |common| replace:: ``common.h``
|
||||
.. _common: https://github.com/ROCm/rocDecode/blob/develop/samples/common.h
|
||||
|
||||
.. |apifolder| replace:: ``api`` folder
|
||||
.. _apifolder: https://github.com/ROCm/rocDecode/tree/develop/api
|
||||
|
||||
.. |utilsfolder| replace:: ``utils`` folder
|
||||
.. _utilsfolder: https://github.com/ROCm/rocDecode/tree/develop/utils
|
||||
|
||||
|
||||
.. |reconfig_struct| replace:: ``ReconfigParams_t``
|
||||
.. _reconfig_struct: https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/structReconfigParams__t.html
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
.. meta::
|
||||
:description: UUsing the rocDecode RocVideoDecoder
|
||||
:keywords: parse video, parse, decode, video decoder, video decoding, rocDecode, AMD, ROCm, RocVideoDecoder
|
||||
|
||||
********************************************************************
|
||||
Using the rocDecode RocVideoDecoder
|
||||
********************************************************************
|
||||
|
||||
rocDecode provides two ways of decoding a video stream: using the rocDecode RocVideoDecoder on GPU or using the FFmpeg decoder on CPU.
|
||||
|
||||
This topic covers how to decode a video stream using the RocVideoDecoder class in |roc_video_dec|_. The RocVideoDecode class provides high-level calls to the core APIs in the |apifolder|_ of the rocDecode GitHub repository. For information about the core APIs, see :doc:`Using the rocDecode core APIs <./using-rocdecode>`.
|
||||
|
||||
The RocVideoDecoder takes a demultiplexed coded picture as input. The picture can be demultiplexed from a video stream using the :doc:`FFmpeg demultiplexer <./using-rocDecode-ffmpeg>`.
|
||||
|
||||
To use the rocDecode video decoder, import the ``roc_video_dec.h`` header file and instantiate ``RocVideoDecoder``.
|
||||
|
||||
The ``RocVideoDecoder`` constructor takes the following parameters:
|
||||
|
||||
.. list-table::
|
||||
:widths: 15 70 15
|
||||
:header-rows: 1
|
||||
|
||||
* - Parameter
|
||||
- Description
|
||||
- Default
|
||||
|
||||
* - ``device_id``
|
||||
- ``int`` |br| |br| The GPU device ID. |br| |br| Set it to 0 for the first device, 1 for the second device, 2 for the third device, and so on for each subsequent device.
|
||||
- 0
|
||||
|
||||
* - ``out_mem_type``
|
||||
- |OutputSurfaceMemoryType|_ |br| |br| The memory type where the surface data, such as the decoded frames, resides. |br| |br| 0: ``OUT_SURFACE_MEM_DEV_INTERNAL``. The surface data is stored internally on memory shared by the GPU and CPU. |br| |br| 1: ``OUT_SURFACE_MEM_DEV_COPIED``. The surface data resides on the GPU. |br| |br| 2: ``OUT_SURFACE_MEM_HOST_COPIED``. The surface data resides on the CPU. |br| |br| See :doc:`Surface data memory locations <../conceptual/rocDecode-memory-types>` for more information.
|
||||
- 0, OUT_SURFACE_MEM_DEV_INTERNAL
|
||||
|
||||
* - ``codec``
|
||||
- |rocDecVideoCodec|_ |br| |br| The video file's codec ID converted to ``rocDecVideoCodec`` using ``AVCodec2RocDecVideoCodec``.
|
||||
- No default, a value must be provided
|
||||
|
||||
* - ``force_zero_latency``
|
||||
- ``bool`` |br| |br| Set to ``true`` to flush decoded frames for immediate display.
|
||||
- ``false``
|
||||
|
||||
* - ``p_crop_rect``
|
||||
- ``const Rect *`` |br| |br| The rectangle to use for cropping.
|
||||
- No cropping
|
||||
|
||||
* - ``extract_user_SEI_Message``
|
||||
- ``bool`` |br| |br| Set to ``true`` to extract Supplemental Enhancement Information (SEI) from the video stream.
|
||||
- ``false``, no SEI will be extracted
|
||||
|
||||
* - ``disp_delay``
|
||||
- ``uint32_t`` |br| |br| Delay the display by this number of frames.
|
||||
- 0, no delay in displaying the frames
|
||||
|
||||
* - ``max_width``
|
||||
- ``int`` |br| |br| Max width.
|
||||
- 0
|
||||
|
||||
* - ``max_height``
|
||||
- ``int`` |br| |br| Max height.
|
||||
- 0
|
||||
|
||||
* - ``clk_rate``
|
||||
- ``uint32_t`` |br| |br| Clock rate.
|
||||
- 1000
|
||||
|
||||
|
||||
.. |br| raw:: html
|
||||
|
||||
</br>
|
||||
|
||||
|
||||
For example, from |videodecode|_:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
RocVideoDecoder viddec(device_id, mem_type, rocdec_codec_id, b_force_zero_latency, p_crop_rect, b_extract_sei_messages, disp_delay);
|
||||
|
||||
``RocVideoDecoder`` will create a parser and a decoder, and initialize HIP on the device.
|
||||
|
||||
The same decoder instance is reused when there's a change to the video resolution without a change in the codec.
|
||||
|
||||
The decoder maintains a pool of frame buffers for decoded images that haven't yet been displayed or processed. When the video stream resolution changes, the existing frame buffers in the buffer pool are deleted. The decoder is then reconfigured for the new resolution and new buffers are created.
|
||||
|
||||
To prevent the remaining frames in the buffers from being deleted along with the buffers, a callback function can be defined to consume the remaining frames.
|
||||
|
||||
The |reconfig_struct|_ struct stores information on how to handle the reconfiguration. A callback, a user-defined flush mode, and a user-defined struct are passed to ``ReconfigParams_t``. The reconfiguration parameters are then passed to the decoder using ``SetReconfigParams``.
|
||||
|
||||
The reconfiguration parameters need to be defined prior to entering the decoding loop.
|
||||
|
||||
For example, the reconfiguration structs are defined in |common|_ in the rocDecode samples and then used in ``videodecode.cpp``:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
typedef enum ReconfigFlushMode_enum {
|
||||
RECONFIG_FLUSH_MODE_NONE = 0, /**< Just flush to get the frame count */
|
||||
RECONFIG_FLUSH_MODE_DUMP_TO_FILE = 1, /**< The remaining frames will be dumped to file in this mode */
|
||||
RECONFIG_FLUSH_MODE_CALCULATE_MD5 = 2, /**< Calculate the MD5 of the flushed frames */
|
||||
} ReconfigFlushMode;
|
||||
|
||||
typedef struct ReconfigDumpFileStruct_t {
|
||||
bool b_dump_frames_to_file;
|
||||
std::string output_file_name;
|
||||
void *md5_generator_handle;
|
||||
} ReconfigDumpFileStruct;
|
||||
|
||||
|
||||
reconfig_params.p_fn_reconfigure_flush = ReconfigureFlushCallback;
|
||||
reconfig_user_struct.b_dump_frames_to_file = dump_output_frames;
|
||||
reconfig_user_struct.output_file_name = output_file_path;
|
||||
if (dump_output_frames) {
|
||||
reconfig_params.reconfig_flush_mode = RECONFIG_FLUSH_MODE_DUMP_TO_FILE;
|
||||
} else {
|
||||
reconfig_params.reconfig_flush_mode = RECONFIG_FLUSH_MODE_NONE;
|
||||
}
|
||||
reconfig_params.p_reconfig_user_struct = &reconfig_user_struct;
|
||||
viddec.SetReconfigParams(&reconfig_params);
|
||||
|
||||
|
||||
In the decode loop, the demultiplexed coded picture is passed to ``DecodeFrame``. Once the frame is decoded and processed, it is released with ``ReleaseFrame``.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. |videodecode| replace:: ``videodecode.cpp``
|
||||
.. _videodecode: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecode/videodecode.cpp
|
||||
|
||||
.. |videodecoderaw| replace:: ``videodecoderaw.cpp``
|
||||
.. _videodecoderaw: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecodeRaw
|
||||
|
||||
.. |common| replace:: ``common.h``
|
||||
.. _common: https://github.com/ROCm/rocDecode/blob/develop/samples/common.h
|
||||
|
||||
.. |apifolder| replace:: ``api`` folder
|
||||
.. _apifolder: https://github.com/ROCm/rocDecode/tree/develop/api
|
||||
|
||||
.. |utilsfolder| replace:: ``utils`` folder
|
||||
.. _utilsfolder: https://github.com/ROCm/rocDecode/tree/develop/utils
|
||||
|
||||
.. |roc_video_dec| replace:: ``roc_video_dec.h``
|
||||
.. _utilsfolder: https://github.com/ROCm/rocDecode/tree/develop/utils/rocvideodecode/roc_video_dec.h
|
||||
|
||||
.. |reconfig_struct| replace:: ``ReconfigParams_t``
|
||||
.. _reconfig_struct: https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/structReconfigParams__t.html
|
||||
|
||||
.. |OutputSurfaceMemoryType| replace:: ``OutputSurfaceMemoryType``
|
||||
.. _OutputSurfaceMemoryType: https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/roc__video__dec_8h.html
|
||||
|
||||
.. |rocDecVideoCodec| replace:: ``rocDecVideoCodec``
|
||||
.. _rocDecVideoCodec: https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/rocdecode_8h.html
|
||||
@@ -0,0 +1,261 @@
|
||||
.. meta::
|
||||
:description: Understanding the rocDecode videodecode sample
|
||||
:keywords: parse video, parse, decode, video decoder, video decoding, rocDecode, AMD, ROCm, sample, walkthrough
|
||||
|
||||
********************************************************************
|
||||
Understanding the rocDecode videodecode sample
|
||||
********************************************************************
|
||||
|
||||
The |videodecode|_ sample in the rocDecode GitHub repository |samplefolder|_ demonstrates how to decode a video stream.
|
||||
|
||||
As with the other rocDecode samples, ``videodecode.cpp`` uses the utility classes in the rocDecode repository's |utilsfolder|_.
|
||||
|
||||
rocDecode provides two ways to decode a video stream: using the rocDecode RocVideoDecoder on GPU or using the FFMpeg video decoder on CPU.
|
||||
|
||||
The ``videodecode.cpp`` sample lets the user choose which method to use through the ``--backend`` argument.
|
||||
|
||||
``videodecode.cpp`` takes the following arguments:
|
||||
|
||||
.. list-table::
|
||||
:widths: 10 30 60
|
||||
:header-rows: 1
|
||||
|
||||
* - Argument
|
||||
- Description
|
||||
- Note
|
||||
|
||||
* - ``-i``
|
||||
- Input file path
|
||||
- Required. The path to the input video stream.
|
||||
|
||||
* - ``-o``
|
||||
- Output file path
|
||||
- Optional. The file to which to write the decoded frames, including those that remain in the decoded frame buffer pool when the RocVideoDecoder is being reconfigured.
|
||||
|
||||
* - ``-d``
|
||||
- GPU device ID
|
||||
- Optional. Set it to 0 for the first device, 1 for the second device, 2 for the third device, and so on for each subsequent device. Set to 0 by default.
|
||||
|
||||
* - ``-backend``
|
||||
- The backend to use for decoding
|
||||
- Optional. Set it to 0 to use RocVideoDecode on GPU, 1 to use the FFMpeg decoder on CPU, or 2 to use the FFMpeg decoder with no multithreading on CPU. Uses RocVideoDecode on GPU by default.
|
||||
|
||||
* - ``-f``
|
||||
- Number of frames to decode
|
||||
- Optional. Decodes the entire stream by default.
|
||||
|
||||
* - ``-z``
|
||||
- Force zero latency
|
||||
- Optional. When set to ``true`` forces decoded frames to be flushed out for display immediately. ``false`` by default.
|
||||
|
||||
* - ``-disp_delay``
|
||||
- Display delay
|
||||
- Optional. The number of frames to decode before displaying the results. Set to 1 by default.
|
||||
|
||||
* - ``-sei``
|
||||
- Extract Supplemental Enhancement Information (SEI)
|
||||
- Optional. Set to ``true`` to extract SEI. ``false`` by default.
|
||||
|
||||
* - ``-md5``
|
||||
- Generate MD5 message digest
|
||||
- Optional. Set to ``true`` to generate the MD5 message digest for the decoded YUV image sequence. ``false`` by default.
|
||||
|
||||
* - ``-md5_check``
|
||||
- Compare the generated MD5 with a provided MD5 string
|
||||
- Optional. When a file containing an MD5 string is passed to this argument, the MD5 message is compared to the string in the file.
|
||||
|
||||
* - ``-crop``
|
||||
- Crop rectangle
|
||||
- Optional. Takes four integers defining the crop rectangle to use with the output. This argument is ignored when using interopped decoded frame. See the documentation for the `Rect struct <https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/structRect.html>`_ for more information. There is no cropping by default.
|
||||
|
||||
* - ``-m``
|
||||
- The output surface memory type
|
||||
- Optional. The memory type where the surface data, such as the decoded frames, resides. Set this to 0 for intermediate GPU memory, to 1 for GPU memory, and to 2 for CPU memory. See :doc:`Surface data memory locations <../conceptual/rocDecode-memory-types>` for more information. Uses intermediate GPU memory by default.
|
||||
|
||||
* - ``-seek_criteria``
|
||||
- Seek criteria and seek starting point
|
||||
- Optional. Set to 1 and the frame number to start demultiplexing from that specific frame. Set to 2 and the timestamp to start demultiplexing from that specific timestamp. The seek criteria and starting point must be comma-separated (``,``). Demultiplexing begins at the first frame by default.
|
||||
|
||||
|
||||
* - ``-seek_mode``
|
||||
- Seek mode
|
||||
- Optional. Set to 0 to seek to the previous keyframe. Set to 1 to seek to the exact frame. Seeks to previous keyframe by default.
|
||||
|
||||
* - ``-no_ffmpeg_demux``
|
||||
- Don't use the FFMpeg demultiplexer
|
||||
- Optional. Set to ``true`` to use the RocDecode bitstream reader to obtain picture data. The bitstream reader can only be used with an elementary stream. The FFmpeg demultiplexer is used by default.
|
||||
|
||||
Because the ``videodecode.cpp`` example can use the RocDecode RocVideoDecoder, the FFMpeg decoder, the FFmpeg demultiplexer (demuxer), or the RocDecode bitstream reader, it imports the ``roc_video_dec.h``, ``video_demuxer.h``, and ``ffmpeg_video_dec.h`` header files. These headers contain the convenience classes and functions for decoding and demultiplexing video.
|
||||
|
||||
|
||||
The FFMpeg demuxer is used to demultiplex the input stream unless the ``-no_ffmpeg_demux`` argument was set to ``true``.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
VideoDemuxer *demuxer;
|
||||
demuxer = new VideoDemuxer(input_file_path.c_str());
|
||||
|
||||
|
||||
.. code:: C++
|
||||
|
||||
The ``GetCodecId`` and ``GetBitDepth`` functions are used to obtain the video stream's codec and bit depth. The ``AVCodec2RocDecVideoCodec`` utility function converts the codec returned from the demuxer to its corresponding ``rocDecVideoCodec_enum`` value.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
rocdec_codec_id = AVCodec2RocDecVideoCodec(demuxer->GetCodecID());
|
||||
bit_depth = demuxer->GetBitDepth();
|
||||
|
||||
The codec ID and bit depth are used to instantiate the video decoder. If the GPU backend was selected, the RocVideoDecoder is instantiated:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
RocVideoDecoder *viddec;
|
||||
viddec = new RocVideoDecoder(device_id, mem_type, rocdec_codec_id, b_force_zero_latency, p_crop_rect, b_extract_sei_messages, disp_delay);
|
||||
|
||||
For more information about the rocDecode RocVideoDecoder, see :doc:`Using the rocDecode RocVideoDecoder <./using-rocDecode-video-decoder>`.
|
||||
|
||||
If the CPU backend was selected, the FFMpeg decoder is instantiated:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
viddec = new FFMpegVideoDecoder(device_id, mem_type, rocdec_codec_id, b_force_zero_latency, p_crop_rect, b_extract_sei_messages, disp_delay);
|
||||
|
||||
The decoder instance is reused when there is a change to the video resolution without a change in the codec. When the video stream resolution changes, the decoder is reconfigured for the new resolution and the pool of frame buffers that the decoder maintains is deleted.
|
||||
|
||||
The |reconfig_struct|_ struct is used to store information on how to handle the frames that remain in the buffers at the time of reconfiguration. A callback, a user-defined flush mode, and a user-defined struct are passed to ``ReconfigParams_t``. The reconfiguration parameters are then passed to the decoder using ``SetReconfigParams``.
|
||||
|
||||
The reconfiguration structs are defined in |common|_ in the rocDecode samples. Three possibilities for the remaining frames in the decoded frame buffer pool are provided:
|
||||
|
||||
* ``RECONFIG_FLUSH_MODE_NONE``: delete the frames along with the buffers.
|
||||
* ``RECONFIG_FLUSH_MODE_DUMP_TO_FILE``: write the frames to the specified output file before deleting the buffers.
|
||||
* ``RECONFIG_FLUSH_MODE_CALCULATE_MD5``: calculate the MD5 of the frames before deleting the buffers.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
typedef enum ReconfigFlushMode_enum {
|
||||
RECONFIG_FLUSH_MODE_NONE = 0, /**< Just flush to get the frame count */
|
||||
RECONFIG_FLUSH_MODE_DUMP_TO_FILE = 1, /**< The remaining frames will be dumped to file in this mode */
|
||||
RECONFIG_FLUSH_MODE_CALCULATE_MD5 = 2, /**< Calculate the MD5 of the flushed frames */
|
||||
} ReconfigFlushMode;
|
||||
|
||||
typedef struct ReconfigDumpFileStruct_t {
|
||||
bool b_dump_frames_to_file;
|
||||
std::string output_file_name;
|
||||
void *md5_generator_handle;
|
||||
} ReconfigDumpFileStruct;
|
||||
|
||||
|
||||
If the ``-o`` output file path argument was set, the remaining frames in the decoded frame buffer pool will be written to the output file upon reconfiguration. If the ``-md5`` argument was set to ``true``, the MD5 of the frames in the decoded frame buffer pool will be calculated before they're flushed or written to file. If neither option was selected, the frames in the decoded frame buffer pool will be deleted along with the buffers without being saved or processed.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
reconfig_params.p_fn_reconfigure_flush = ReconfigureFlushCallback;
|
||||
reconfig_user_struct.b_dump_frames_to_file = dump_output_frames;
|
||||
reconfig_user_struct.output_file_name = output_file_path;
|
||||
if (dump_output_frames) {
|
||||
reconfig_params.reconfig_flush_mode = RECONFIG_FLUSH_MODE_DUMP_TO_FILE;
|
||||
} else if (b_generate_md5) {
|
||||
reconfig_params.reconfig_flush_mode = RECONFIG_FLUSH_MODE_CALCULATE_MD5;
|
||||
} else {
|
||||
reconfig_params.reconfig_flush_mode = RECONFIG_FLUSH_MODE_NONE;
|
||||
}
|
||||
reconfig_params.p_reconfig_user_struct = &reconfig_user_struct;
|
||||
|
||||
The reconfiguration parameters need to be defined prior to entering the decoding loop.
|
||||
|
||||
In the decode loop, the video stream is demultiplexed before being decoded.
|
||||
|
||||
The demuxer will demultiplex frames sequentially starting at the beginning of the stream unless ``-seek_criteria`` was set to either 1 or 2.
|
||||
|
||||
If the ``-seek_criteria`` argument was set to 1 and ``-seek_mode`` was set to 1, the demuxer will start demultiplexing the video at the frame provided.
|
||||
|
||||
If the ``-seek_criteria`` argument was set to 1 and ``-seek_mode`` wasn't set or was set to 0, the demuxer will start demultiplexing the video at the first keyframe before the frame provided.
|
||||
|
||||
If the ``-seek_criteria`` argument was set to 2 the demuxer will start demultiplexing the video at the timestamp provided.
|
||||
|
||||
The seek criteria is defined by the ``SeekCriteriaEnum`` enum and the seek mode is defined by the ``SeekModeEnum`` enum. Both the ``SeekCriteriaEnum`` and the ``SeekModeEnum`` are defined in ``video_demuxer.h``.
|
||||
|
||||
From ``videodecode.cpp``:
|
||||
|
||||
.. code:: C++
|
||||
|
||||
VideoSeekContext video_seek_ctx;
|
||||
[...]
|
||||
do {
|
||||
[...]
|
||||
if (seek_criteria == 1 && first_frame) {
|
||||
// use VideoSeekContext class to seek to given frame number
|
||||
video_seek_ctx.seek_frame_ = seek_to_frame;
|
||||
video_seek_ctx.seek_crit_ = SEEK_CRITERIA_FRAME_NUM;
|
||||
video_seek_ctx.seek_mode_ = (seek_mode ? SEEK_MODE_EXACT_FRAME : SEEK_MODE_PREV_KEY_FRAME);
|
||||
demuxer->Seek(video_seek_ctx, &pvideo, &n_video_bytes);
|
||||
pts = video_seek_ctx.out_frame_pts_;
|
||||
std::cout << "info: Number of frames that were decoded during seek - " << video_seek_ctx.num_frames_decoded_ << std::endl;
|
||||
first_frame = false;
|
||||
} else if (seek_criteria == 2 && first_frame) {
|
||||
// use VideoSeekContext class to seek to given timestamp
|
||||
video_seek_ctx.seek_frame_ = seek_to_frame;
|
||||
video_seek_ctx.seek_crit_ = SEEK_CRITERIA_TIME_STAMP;
|
||||
video_seek_ctx.seek_mode_ = (seek_mode ? SEEK_MODE_EXACT_FRAME : SEEK_MODE_PREV_KEY_FRAME);
|
||||
demuxer->Seek(video_seek_ctx, &pvideo, &n_video_bytes);
|
||||
pts = video_seek_ctx.out_frame_pts_;
|
||||
std::cout << "info: Duration of frame found after seek - " << video_seek_ctx.out_frame_duration_ << " ms" << std::endl;
|
||||
first_frame = false;
|
||||
} else {
|
||||
demuxer->Demux(&pvideo, &n_video_bytes, &pts);
|
||||
}
|
||||
|
||||
The video can now be decoded using the ``DecodeFrame`` function.
|
||||
|
||||
If the ``-md5`` argument was set to ``true``, MD5 is calculated for the file. If an output file path was provided, the decoded frames will be written to file.
|
||||
|
||||
The frame is released with ``ReleaseFrame`` once processing is complete.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
n_frame_returned = viddec->DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts, &decoded_pics);
|
||||
|
||||
[...]
|
||||
|
||||
for (int i = 0; i < n_frame_returned; i++) {
|
||||
pframe = viddec->GetFrame(&pts);
|
||||
if (b_generate_md5) {
|
||||
md5_generator->UpdateMd5ForFrame(pframe, surf_info);
|
||||
}
|
||||
if (dump_output_frames && mem_type != OUT_SURFACE_MEM_NOT_MAPPED) {
|
||||
viddec->SaveFrameToFile(output_file_path, pframe, surf_info);
|
||||
}
|
||||
|
||||
viddec->ReleaseFrame(pts);
|
||||
|
||||
|
||||
The demuxer is deleted once decoding is done.
|
||||
|
||||
.. code:: C++
|
||||
|
||||
delete demuxer;
|
||||
|
||||
.. |videodecode| replace:: ``videodecode.cpp``
|
||||
.. _videodecode: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecode/videodecode.cpp
|
||||
|
||||
.. |videodecoderaw| replace:: ``videodecoderaw.cpp``
|
||||
.. _videodecoderaw: https://github.com/ROCm/rocDecode/tree/develop/samples/videoDecodeRaw
|
||||
|
||||
.. |common| replace:: ``common.h``
|
||||
.. _common: https://github.com/ROCm/rocDecode/blob/develop/samples/common.h
|
||||
|
||||
.. |apifolder| replace:: ``api`` folder
|
||||
.. _apifolder: https://github.com/ROCm/rocDecode/tree/develop/api
|
||||
|
||||
.. |utilsfolder| replace:: ``utils`` folder
|
||||
.. _utilsfolder: https://github.com/ROCm/rocDecode/tree/develop/utils
|
||||
|
||||
.. |samplefolder| replace:: ``samples`` folder
|
||||
.. _samplefolder: https://github.com/ROCm/rocDecode/tree/develop/samples
|
||||
|
||||
.. |reconfig_struct| replace:: ``ReconfigParams_t``
|
||||
.. _reconfig_struct: https://rocm.docs.amd.com/projects/rocDecode/en/latest/doxygen/html/structReconfigParams__t.html
|
||||
|
||||
.. |br| raw:: html
|
||||
|
||||
</br>
|
||||
@@ -1,214 +1,229 @@
|
||||
.. meta::
|
||||
:description: Using rocDecode
|
||||
:keywords: parse video, parse, decode, video decoder, video decoding, rocDecode, AMD, ROCm
|
||||
|
||||
********************************************************************
|
||||
Using rocDecode
|
||||
********************************************************************
|
||||
|
||||
To learn how to use the rocDecode SDK library and its different utilities, follow these instructions:
|
||||
|
||||
1. API overview
|
||||
====================================================
|
||||
|
||||
All rocDecode APIs are exposed in the header files ``rocdecode.h`` and ``rocparser.h``. You can find
|
||||
these files in the `api` folder in the rocDecode repository.
|
||||
|
||||
The samples use the ``RocVideoDecoder`` user class provided in ``roc_video_dec.h`` in the ``utils`` folder
|
||||
of the rocDecode repository.
|
||||
|
||||
A video parser (defined in ``rocparser.h``) is needed to extract and decode headers from the bitstream
|
||||
in order to organize the data into a structured format for the hardware decoder. The parser is critical in
|
||||
video decoding, as it controls the decoding and display of a bitstream's individual frames and fields.
|
||||
|
||||
The parser object in ``rocparser.h`` has three main APIs:
|
||||
|
||||
* ``rocDecCreateVideoParser()``
|
||||
* ``rocDecParseVideoData()``
|
||||
* ``rocDecDestroyVideoParser()``
|
||||
|
||||
2. Create a parser object
|
||||
====================================================
|
||||
|
||||
The ``rocDecCreateVideoParser()`` API creates a video parser object for the codec that you specify. The
|
||||
API takes ``max_num_decode_surfaces``, which determines the Decoded Picture Buffer (DPB) size for
|
||||
decoding. When creating a parser object, the application must register certain callback functions with
|
||||
the driver, which is called from the parser during decode.
|
||||
|
||||
* ``pfn_sequence_callback`` is called when the parser encounters a new sequence header. The parser
|
||||
informs you of the minimum number of surfaces needed by the parser's DPB to successfully decode
|
||||
the bitstream. In addition, the caller can set additional parameters, like ``max_display_delay``, to
|
||||
control frame decoding and display.
|
||||
|
||||
* The ``pfn_decode_picture`` callback function is triggered when a picture is set for decoding.
|
||||
|
||||
* The ``pfn_display_picture`` callback function is triggered when a frame in display order is ready to be
|
||||
consumed by the caller.
|
||||
|
||||
* The ``pfn_get_sei_msg`` callback function is triggered when your Supplementation Enhancement
|
||||
Information (SEI) message is parsed and sent back to the caller.
|
||||
|
||||
3. Parse video data
|
||||
====================================================
|
||||
|
||||
Elementary stream video packets extracted from the de-multiplexer are fed into the parser using the
|
||||
``rocDecParseVideoData()`` API.
|
||||
|
||||
During this call, the parser triggers the callbacks as it encounters a new sequence header, receives
|
||||
compressed frame/field data ready to be decoded, or when it's ready to display a frame. If any of the
|
||||
callbacks return a failure, it is propagated back to the application so the decoding can be ended
|
||||
gracefully.
|
||||
|
||||
4. Query decode capabilities
|
||||
====================================================
|
||||
|
||||
The ``rocDecGetDecoderCaps()`` API allows you to query the capabilities of the underlying hardware
|
||||
video decoder. Decoder capabilities usually include supported codecs, maximum resolution, and
|
||||
bit-depth.
|
||||
|
||||
The following pseudo-code illustrates the use of this API. The application handles the error
|
||||
appropriately for non-supported decoder capabilities.
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
RocdecDecodeCaps decode_caps;
|
||||
memset(&decode_caps, 0, sizeof(decode_caps));
|
||||
decode_caps.codec_type = p_video_format->codec;
|
||||
decode_caps.chroma_format = p_video_format->chroma_format;
|
||||
decode_caps.bit_depth_minus_8 = p_video_format->bit_depth_luma_minus8;
|
||||
|
||||
ROCDEC_API_CALL(rocDecGetDecoderCaps(&decode_caps));
|
||||
|
||||
if(!decode_caps.is_supported) {
|
||||
ROCDEC_THROW("Rocdec:: Codec not supported on this GPU: ", ROCDEC_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((p_video_format->coded_width > decode_caps.max_width) ||
|
||||
(p_video_format->coded_height > decode_caps.max_height)) {
|
||||
|
||||
std::ostringstream errorString;
|
||||
errorString << std::endl
|
||||
<< "Resolution : " << p_video_format->coded_width << "x" << p_video_format->coded_height << std::endl
|
||||
<< "Max Supported (wxh) : " << decode_caps.max_width << "x" << decode_caps.max_height << std::endl
|
||||
<< "Resolution not supported on this GPU ";
|
||||
|
||||
const std::string cErr = errorString.str();
|
||||
ROCDEC_THROW(cErr, ROCDEC_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
5. Create a decoder
|
||||
====================================================
|
||||
|
||||
``rocDecCreateDecoder()`` creates an instance of the hardware video decoder object and provides you
|
||||
with a handle upon successful creation. Refer to the ``RocDecoderCreateInfo`` structure for information
|
||||
about the parameters passed for creating the decoder. For example,
|
||||
``RocDecoderCreateInfo::codec_type`` represents the codec type of the video. The decoder handle
|
||||
returned by ``rocDecCreateDecoder()`` must be retained for the entire decode session because the
|
||||
handle is passed along with the other decoding APIs. In addition, you can inform display or crop
|
||||
dimensions along with this API.
|
||||
|
||||
6. Decode the frame
|
||||
====================================================
|
||||
|
||||
After de-multiplexing and parsing, you can decode bitstream data containing a frame/field using
|
||||
hardware.
|
||||
|
||||
Use the ``rocDecDecodeFrame()`` 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 ``rocDecDecodeFrame()`` call takes the decoder handle and the pointer to the ``RocdecPicParams``
|
||||
structure and initiates the video decoding using VA-API.
|
||||
|
||||
7. Query the decoding status
|
||||
====================================================
|
||||
|
||||
After submitting a frame for decoding, you can call ``rocDecGetDecodeStatus()`` to query the decoding
|
||||
status for a given frame. A structure pointer, ``RocdecDecodeStatus*``, is filled and returned.
|
||||
|
||||
The API inputs are:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
* ``pic_idx``: An `int` value for the ``picIdx`` for which you want a status in order to index of the picture.
|
||||
* ``decode_status``: A pointer to ``RocdecDecodeStatus`` as a return value.
|
||||
|
||||
The API returns one of the following statuses:
|
||||
|
||||
* Invalid (0): Decode status is not valid.
|
||||
* In Progress (1): Decoding is in progress.
|
||||
* Success (2): Decoding was successful and no errors were returned.
|
||||
* Error (8): The frame was corrupted, but the error was not concealed.
|
||||
* Error Concealed (9): The frame was corrupted and the error was concealed.
|
||||
* Displaying (10): Decode is complete, display in progress.
|
||||
|
||||
8. Prepare the decoded frame for further processing
|
||||
====================================================
|
||||
|
||||
The decoded frames can be used for further postprocessing using ``rocDecGetVideoFrame()``. The
|
||||
successful completion of ``rocDecGetVideoFrame()`` 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 on the output surface,
|
||||
such as YUV format, dimensions, and pitch from this call. In the high-level ``RocVideoDecoder`` class, we
|
||||
provide four different surface type modes for the mapped surface, as specified in
|
||||
``OutputSurfaceMemoryType``.
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
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.
|
||||
|
||||
Refer to the ``RocVideoDecoder`` class and
|
||||
`samples <https://github.com/ROCm/rocDecode/tree/develop/samples>`_ for details on how to use
|
||||
these APIs.
|
||||
|
||||
9. Reconfigure the decoder
|
||||
====================================================
|
||||
|
||||
You can call ``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.
|
||||
|
||||
The API inputs are:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
* ``reconfig_params``: You must specify the parameters for the changes in
|
||||
``RocdecReconfigureDecoderInfo``. The width and height used for reconfiguration cannot exceed the
|
||||
values set for ``max_width`` and ``max_height``, defined in ``RocDecoderCreateInfo``. If you need to
|
||||
change these values, you have to destroy and recreate the session.
|
||||
|
||||
.. note::
|
||||
|
||||
You must call ``rocDecReconfigureDecoder()`` during ``RocdecParserParams::pfn_sequence_callback``.
|
||||
|
||||
10. Destroy the decoder
|
||||
====================================================
|
||||
|
||||
You must call the ``rocDecDestroyDecoder()`` to destroy the session and free up resources.
|
||||
|
||||
The API input is:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
|
||||
The API returns a ``RocdecDecodeStatus`` value.
|
||||
|
||||
11. Destroy the parser
|
||||
====================================================
|
||||
|
||||
You must call ``rocDecDestroyVideoParser()`` to destroy the parser object and free up all allocated
|
||||
resources at the end of video decoding.
|
||||
.. meta::
|
||||
:description: Using rocDecode
|
||||
:keywords: parse video, parse, decode, video decoder, video decoding, rocDecode, core APIs, AMD, ROCm
|
||||
|
||||
********************************************************************
|
||||
Using the rocDecode core APIs
|
||||
********************************************************************
|
||||
|
||||
rocDecode core APIs are available in the |apifolder|_ of the `rocDecode GitHub repository <https://github.com/ROCm/rocDecode>`_.
|
||||
|
||||
.. note::
|
||||
|
||||
The rocDecode samples use the utility classes in the |utilsfolder|_ instead of the core APIs. For information about using the utility classes, see :doc:`Using rocDecode with the FFmpeg decoder <./using-rocDecode-ffmpeg>` and :doc:`Using rocDecode with the bitstream decoder <./using-rocDecode-bitstream>`.
|
||||
|
||||
|
||||
API overview
|
||||
====================================================
|
||||
|
||||
All rocDecode APIs are exposed in the header files ``rocdecode.h`` and ``rocparser.h``. You can find
|
||||
these files in the ``api`` folder in the rocDecode repository.
|
||||
|
||||
The samples use the ``RocVideoDecoder`` user class provided in ``roc_video_dec.h`` in the ``utils`` folder
|
||||
of the rocDecode repository.
|
||||
|
||||
A video parser (defined in ``rocparser.h``) is needed to extract and decode headers from the bitstream
|
||||
in order to organize the data into a structured format for the hardware decoder. The parser is critical in
|
||||
video decoding, as it controls the decoding and display of a bitstream's individual frames and fields.
|
||||
|
||||
The parser object in ``rocparser.h`` has three main APIs:
|
||||
|
||||
* ``rocDecCreateVideoParser()``
|
||||
* ``rocDecParseVideoData()``
|
||||
* ``rocDecDestroyVideoParser()``
|
||||
|
||||
Create a parser object
|
||||
====================================================
|
||||
|
||||
The ``rocDecCreateVideoParser()`` API creates a video parser object for the codec that you specify. The
|
||||
API takes ``max_num_decode_surfaces``, which determines the Decoded Picture Buffer (DPB) size for
|
||||
decoding. When creating a parser object, the application must register certain callback functions with
|
||||
the driver, which is called from the parser during decode.
|
||||
|
||||
|
||||
* ``pfn_sequence_callback`` is called when the parser encounters a new sequence header. The parser
|
||||
informs you of the minimum number of surfaces needed by the parser's DPB to successfully decode
|
||||
the bitstream. In addition, the caller can set additional parameters, like ``max_display_delay``, to
|
||||
control frame decoding and display.
|
||||
|
||||
* The ``pfn_decode_picture`` callback function is triggered when a picture is set for decoding.
|
||||
|
||||
* The ``pfn_display_picture`` callback function is triggered when a frame in display order is ready to be
|
||||
consumed by the caller.
|
||||
|
||||
* The ``pfn_get_sei_msg`` callback function is triggered when your Supplementation Enhancement
|
||||
Information (SEI) message is parsed and returned to the caller.
|
||||
|
||||
|
||||
Parse video data
|
||||
====================================================
|
||||
|
||||
Elementary stream video packets extracted from the de-multiplexer are fed into the parser using the
|
||||
``rocDecParseVideoData()`` API.
|
||||
|
||||
During this call, the parser triggers the callbacks as it encounters a new sequence header, receives
|
||||
compressed frame/field data ready to be decoded, or when it's ready to display a frame. If any of the
|
||||
callbacks return a failure, it is propagated back to the application so the decoding can be ended
|
||||
gracefully.
|
||||
|
||||
Query decode capabilities
|
||||
====================================================
|
||||
|
||||
The ``rocDecGetDecoderCaps()`` API allows you to query the capabilities of the underlying hardware
|
||||
video decoder. Decoder capabilities usually include supported codecs, maximum resolution, and
|
||||
bit depth.
|
||||
|
||||
|
||||
The following pseudo-code illustrates the use of this API. The application handles the error
|
||||
appropriately for non-supported decoder capabilities.
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
RocdecDecodeCaps decode_caps;
|
||||
memset(&decode_caps, 0, sizeof(decode_caps));
|
||||
decode_caps.codec_type = p_video_format->codec;
|
||||
decode_caps.chroma_format = p_video_format->chroma_format;
|
||||
decode_caps.bit_depth_minus_8 = p_video_format->bit_depth_luma_minus8;
|
||||
|
||||
ROCDEC_API_CALL(rocDecGetDecoderCaps(&decode_caps));
|
||||
|
||||
if(!decode_caps.is_supported) {
|
||||
ROCDEC_THROW("Rocdec:: Codec not supported on this GPU: ", ROCDEC_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((p_video_format->coded_width > decode_caps.max_width) ||
|
||||
(p_video_format->coded_height > decode_caps.max_height)) {
|
||||
|
||||
std::ostringstream errorString;
|
||||
errorString << std::endl
|
||||
<< "Resolution : " << p_video_format->coded_width << "x" << p_video_format->coded_height << std::endl
|
||||
<< "Max Supported (wxh) : " << decode_caps.max_width << "x" << decode_caps.max_height << std::endl
|
||||
<< "Resolution not supported on this GPU ";
|
||||
|
||||
const std::string cErr = errorString.str();
|
||||
ROCDEC_THROW(cErr, ROCDEC_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Create a decoder
|
||||
====================================================
|
||||
|
||||
``rocDecCreateDecoder()`` creates an instance of the hardware video decoder object and provides you
|
||||
with a handle upon successful creation. Refer to the ``RocDecoderCreateInfo`` structure for information
|
||||
about the parameters passed for creating the decoder. For example,
|
||||
``RocDecoderCreateInfo::codec_type`` represents the codec type of the video. The decoder handle
|
||||
returned by ``rocDecCreateDecoder()`` needs to be retained for the entire decode session because the
|
||||
handle is passed along with the other decoding APIs. In addition, you can inform display or crop
|
||||
dimensions along with this API.
|
||||
|
||||
Decode the frame
|
||||
====================================================
|
||||
|
||||
After de-multiplexing and parsing, you can decode bitstream data containing a frame/field using
|
||||
hardware.
|
||||
|
||||
Use the ``rocDecDecodeFrame()`` 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 ``rocDecDecodeFrame()`` call takes the decoder handle and the pointer to the ``RocdecPicParams``
|
||||
structure and initiates the video decoding using VA-API.
|
||||
|
||||
Query the decoding status
|
||||
====================================================
|
||||
|
||||
After submitting a frame for decoding, you can call ``rocDecGetDecodeStatus()`` to query the decoding
|
||||
status for a given frame. A structure pointer, ``RocdecDecodeStatus*``, is filled and returned.
|
||||
|
||||
The API inputs are:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
* ``pic_idx``: An `int` value for the ``picIdx`` for which you want a status in order to index of the picture.
|
||||
* ``decode_status``: A pointer to ``RocdecDecodeStatus`` as a return value.
|
||||
|
||||
The API returns one of the following statuses:
|
||||
|
||||
* Invalid (0): Decode status is not valid.
|
||||
* In Progress (1): Decoding is in progress.
|
||||
* Success (2): Decoding was successful and no errors were returned.
|
||||
* Error (8): The frame was corrupted, but the error was not concealed.
|
||||
* Error Concealed (9): The frame was corrupted and the error was concealed.
|
||||
* Displaying (10): Decode is complete, display in progress.
|
||||
|
||||
Prepare the decoded frame for further processing
|
||||
====================================================
|
||||
|
||||
The decoded frames can be used for further postprocessing using ``rocDecGetVideoFrame()``. The
|
||||
successful completion of ``rocDecGetVideoFrame()`` 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 on the output surface,
|
||||
such as YUV format, dimensions, and pitch from this call. In the high-level ``RocVideoDecoder`` class, we
|
||||
provide four different surface type modes for the mapped surface, as specified in
|
||||
``OutputSurfaceMemoryType``.
|
||||
|
||||
.. code:: cpp
|
||||
|
||||
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 need to 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 reuse by the ``RocVideoDecoder`` class.
|
||||
|
||||
Refer to the ``RocVideoDecoder`` class and
|
||||
`samples <https://github.com/ROCm/rocDecode/tree/develop/samples>`_ for details on how to use
|
||||
these APIs.
|
||||
|
||||
Reconfigure the decoder
|
||||
====================================================
|
||||
|
||||
You can call ``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.
|
||||
|
||||
The API inputs are:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
* ``reconfig_params``: You need to specify the parameters for the changes in
|
||||
``RocdecReconfigureDecoderInfo``. The width and height used for reconfiguration cannot exceed the
|
||||
values set for ``max_width`` and ``max_height``, defined in ``RocDecoderCreateInfo``. If you need to
|
||||
change these values, you have to destroy and recreate the session.
|
||||
|
||||
.. note::
|
||||
|
||||
You need to call ``rocDecReconfigureDecoder()`` during ``RocdecParserParams::pfn_sequence_callback``.
|
||||
|
||||
Destroy the decoder
|
||||
====================================================
|
||||
|
||||
You need to call the ``rocDecDestroyDecoder()`` to destroy the session and free up resources.
|
||||
|
||||
The API input is:
|
||||
|
||||
* ``decoder_handle``: A ``RocDecoder`` handler, ``rocDecDecoderHandle``.
|
||||
|
||||
The API returns a ``RocdecDecodeStatus`` value.
|
||||
|
||||
Destroy the parser
|
||||
====================================================
|
||||
|
||||
You need to call ``rocDecDestroyVideoParser()`` to destroy the parser object and free up all allocated
|
||||
resources at the end of video decoding.
|
||||
|
||||
|
||||
.. |apifolder| replace:: ``api`` folder
|
||||
.. _apifolder: https://github.com/ROCm/rocDecode/tree/develop/api
|
||||
|
||||
.. |utilsfolder| replace:: ``utils`` folder
|
||||
.. _utilsfolder: https://github.com/ROCm/rocDecode/tree/develop/utils
|
||||
|
||||
@@ -27,10 +27,15 @@ The rocDecode public repository is located at `https://github.com/ROCm/rocDecode
|
||||
.. grid-item-card:: Conceptual
|
||||
|
||||
* :doc:`Video decoding pipeline <./conceptual/video-decoding-pipeline>`
|
||||
* :doc:`rocDecode surface memory locations <./conceptual/rocDecode-memory-types>`
|
||||
|
||||
.. grid-item-card:: How to
|
||||
|
||||
* :doc:`Using rocDecode <./how-to/using-rocdecode>`
|
||||
* :doc:`Understand the rocDecode videodecode.cpp sample <./how-to/using-rocDecode-videodecode-sample>`
|
||||
* :doc:`Use the rocDecode RocVideoDecoder <./how-to/using-rocDecode-video-decoder>`
|
||||
* :doc:`Use the rocDecode FFmpeg demultiplexer <./how-to/using-rocDecode-ffmpeg>`
|
||||
* :doc:`Use the rocDecode core APIs <./how-to/using-rocdecode>`
|
||||
|
||||
|
||||
.. grid-item-card:: Samples
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ subtrees:
|
||||
|
||||
- caption: Install
|
||||
entries:
|
||||
- file: install/prerequisites.rst
|
||||
- file: install/rocDecode-prerequisites.rst
|
||||
title: rocDecode prerequisites
|
||||
- file: install/rocDecode-package-install.rst
|
||||
title: Installing rocDecode with the package installer
|
||||
@@ -17,22 +17,28 @@ subtrees:
|
||||
- url: https://github.com/ROCm/rocDecode/tree/develop/docker
|
||||
title: rocDecode Docker containers
|
||||
|
||||
- caption: Samples
|
||||
entries:
|
||||
- file: tutorials/rocDecode-samples.rst
|
||||
title: rocDecode samples
|
||||
- url: https://github.com/ROCm/rocDecode/tree/develop/samples
|
||||
title: rocDecode samples on GitHub
|
||||
|
||||
- caption: How to
|
||||
entries:
|
||||
- file: how-to/using-rocdecode.rst
|
||||
title: Using rocDecode
|
||||
|
||||
- caption: Conceptual
|
||||
entries:
|
||||
- file: conceptual/video-decoding-pipeline.rst
|
||||
title: Video decoding pipeline
|
||||
- file: conceptual/rocDecode-memory-types.rst
|
||||
title: rocDecode surface memory locations
|
||||
|
||||
- caption: Samples
|
||||
entries:
|
||||
- file: tutorials/rocDecode-samples.rst
|
||||
title: rocDecode samples
|
||||
|
||||
- caption: How to
|
||||
entries:
|
||||
- file: how-to/using-rocDecode-videodecode-sample.rst
|
||||
title: Understand the rocDecode videodecode sample
|
||||
- file: how-to/using-rocDecode-video-decoder.rst
|
||||
title: Use the rocDecode RocVideoDecoder
|
||||
- file: how-to/using-rocDecode-ffmpeg.rst
|
||||
title: Use the rocDecode FFmpeg demultiplexer
|
||||
- file: how-to/using-rocdecode.rst
|
||||
title: Use the rocDecode core APIs
|
||||
|
||||
- caption: Reference
|
||||
entries:
|
||||
|
||||
@@ -8,6 +8,8 @@ rocDecode samples
|
||||
|
||||
rocDecode samples are available in the `rocDecode GitHub repository <https://github.com/ROCm/rocDecode/tree/develop/samples>`_.
|
||||
|
||||
You can find a walkthrough of the ``videodecode.cpp`` sample at :doc:`Understanding the videodecode.cpp sample <../how-to/using-rocDecode-videodecode-sample>`.
|
||||
|
||||
All three rocDecode packages, ``rocDecode``, ``rocdecode-dev``, and ``rocdecode-test``, must be installed to use the rocDecode samples.
|
||||
|
||||
If you're using a :doc:`package installer <./install/rocDecode-package-install>`, install ``rocdecode``, ``rocdecode-dev``, and ``rocdecode-test``.
|
||||
@@ -18,7 +20,7 @@ If you're building and installing rocDecode from its :doc:`source code <../insta
|
||||
|
||||
python3 rocDecode-setup.py --developer ON
|
||||
|
||||
The rocDecode-test package needs to be built and installed as well:
|
||||
The ``rocDecode-test`` package needs to be built and installed as well:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
@@ -27,3 +29,4 @@ The rocDecode-test package needs to be built and installed as well:
|
||||
ctest -VV
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@ using ROCm HIP, thereby avoiding unnecessary data copies via the PCIe bus. You c
|
||||
frames using scaling or color conversion and augmentation kernels (on a GPU or host) in a format for
|
||||
GPU/CPU-accelerated inferencing and training.
|
||||
|
||||
In addition, you can use the rocDecode API to create multiple instances of video decoder based on the
|
||||
number of available VCNs in a GPU device. By configuring the decoder for a device, all available
|
||||
VCNs can be used seamlessly for decoding a batch of video streams in parallel.
|
||||
In addition, you can use the rocDecode API to create multiple instances of video decoders based on the number of available VCNs on a GPU device. By configuring the decoder for a device, all available VCNs can be used seamlessly to decode a batch of video streams in parallel.
|
||||
|
||||
For more information, refer to the
|
||||
:doc:`Video decoding pipeline <./conceptual/video-decoding-pipeline>`.
|
||||
|
||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir