develop/utils/rocvideodecode/roc_video_dec.h Source File

develop/utils/rocvideodecode/roc_video_dec.h Source File#

rocDecode: develop/utils/rocvideodecode/roc_video_dec.h Source File
roc_video_dec.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved.
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22 
23 #pragma once
24 
25 #include <stdint.h>
26 #include <mutex>
27 #include <vector>
28 #include <string>
29 #include <iostream>
30 #include <sstream>
31 #include <string.h>
32 #include <queue>
33 #include <stdexcept>
34 #include <exception>
35 #include <cstring>
36 #include <unordered_map>
37 #include <chrono>
38 #include <thread>
39 #include <hip/hip_runtime.h>
40 #include "rocdecode/rocdecode.h"
41 #include "rocdecode/rocparser.h"
42 
51 #define MAX_FRAME_NUM 16
52 
53 typedef int (ROCDECAPI *PFNRECONFIGUEFLUSHCALLBACK)(void *, uint32_t, void *);
54 
55 typedef enum SeiAvcHevcPayloadType_enum {
56  SEI_TYPE_TIME_CODE = 136,
57  SEI_TYPE_USER_DATA_UNREGISTERED = 5
58 } SeiAvcHevcPayloadType;
59 
65 } OutputSurfaceMemoryType;
66 
67 #define TOSTR(X) std::to_string(static_cast<int>(X))
68 #define STR(X) std::string(X)
69 
70 #if DBGINFO
71 #define ROCDEC_INFO(X) std::clog << "[INF] " << " {" << __func__ <<"} " << " " << X << std::endl;
72 #else
73 #define ROCDEC_INFO(X) ;
74 #endif
75 #define ROCDEC_ERR(X) std::cerr << "[ERR] " << " {" << __func__ <<"} " << " " << X << std::endl;
76 
77 inline int GetChromaPlaneCount(rocDecVideoSurfaceFormat surface_format) {
78  int num_planes = 1;
79  switch (surface_format) {
82  num_planes = 1;
83  break;
90  num_planes = 2;
91  break;
92  }
93 
94  return num_planes;
95 };
96 
97 inline float GetChromaHeightFactor(rocDecVideoSurfaceFormat surface_format) {
98  float factor = 0.5;
99  switch (surface_format) {
104  factor = 0.5;
105  break;
110  factor = 1.0;
111  break;
112  }
113 
114  return factor;
115 };
116 
117 class RocVideoDecodeException : public std::exception {
118 public:
119 
120  explicit RocVideoDecodeException(const std::string& message, const int err_code):_message(message), _err_code(err_code) {}
121  explicit RocVideoDecodeException(const std::string& message):_message(message), _err_code(-1) {}
122  virtual const char* what() const throw() override {
123  return _message.c_str();
124  }
125  int Geterror_code() const { return _err_code; }
126 private:
127  std::string _message;
128  int _err_code;
129 };
130 
131 #define ROCDEC_THROW(X, CODE) throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X , CODE);
132 
133 #define ROCDEC_API_CALL( rocDecAPI ) \
134  do { \
135  rocDecStatus error_code = rocDecAPI; \
136  if( error_code != ROCDEC_SUCCESS) { \
137  std::ostringstream error_log; \
138  error_log << #rocDecAPI << " returned " << rocDecGetErrorName(error_code) << " at " <<__FILE__ <<":" << __LINE__;\
139  ROCDEC_THROW(error_log.str(), error_code); \
140  } \
141  } while (0)
142 
143 #define HIP_API_CALL( call ) \
144  do { \
145  hipError_t hip_status = call; \
146  if (hip_status != hipSuccess) { \
147  const char *sz_err_name = NULL; \
148  sz_err_name = hipGetErrorName(hip_status); \
149  std::ostringstream error_log; \
150  error_log << "hip API error " << sz_err_name ; \
151  ROCDEC_THROW(error_log.str(), hip_status); \
152  } \
153  } \
154  while (0)
155 
156 #define CHECK_ZERO(str, value) \
157  if (value == 0) { \
158  ROCDEC_ERR(STR(str) + " is 0."); \
159  }
160 
161 struct Rect {
162  int left;
163  int top;
164  int right;
165  int bottom;
166 };
167 
168 struct Dim {
169  int w, h;
170 };
171 
172 static inline int align(int value, int alignment) {
173  return (value + alignment - 1) & ~(alignment - 1);
174 }
175 
176 typedef struct DecFrameBuffer_ {
177  uint8_t *frame_ptr;
178  int64_t pts;
181 
182 
183 typedef struct OutputSurfaceInfoType {
184  uint32_t output_width;
185  uint32_t output_height;
186  uint32_t output_pitch;
187  uint32_t output_vstride;
188  uint32_t chroma_height;
190  uint32_t bytes_per_pixel;
191  uint32_t bit_depth;
192  uint32_t num_chroma_planes;
194  rocDecVideoSurfaceFormat surface_format;
195  OutputSurfaceMemoryType mem_type;
197 
198 typedef struct ReconfigParams_t {
199  PFNRECONFIGUEFLUSHCALLBACK p_fn_reconfigure_flush;
200  void *p_reconfig_user_struct;
201  uint32_t reconfig_flush_mode;
203 
205  public:
220  RocVideoDecoder(int device_id, OutputSurfaceMemoryType out_mem_type, rocDecVideoCodec codec, bool force_zero_latency = false,
221  const Rect *p_crop_rect = nullptr, bool extract_user_SEI_Message = false, uint32_t disp_delay = 0, int max_width = 0, int max_height = 0,
222  uint32_t clk_rate = 1000, bool skip_init = false);
223 
224  virtual ~RocVideoDecoder();
225 
226  rocDecVideoCodec GetCodecId() { return codec_id_; }
227 
231  uint32_t GetWidth() {CHECK_ZERO("Display width", disp_width_); return disp_width_;}
232 
236  int GetDecodeWidth() {CHECK_ZERO("Coded width", coded_width_); return coded_width_; }
237 
241  uint32_t GetHeight() {CHECK_ZERO("Display height", disp_height_); return disp_height_; }
242 
246  int GetChromaHeight() {CHECK_ZERO("Chroma height", chroma_height_); return chroma_height_; }
247 
251  int GetNumChromaPlanes() {return num_chroma_planes_; }
252 
256  virtual int GetFrameSize() {CHECK_ZERO("Display width", disp_width_); return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * byte_per_pixel_; }
257 
258 
264  uint32_t GetBitDepth() {return (bitdepth_minus_8_ + 8); }
265  uint32_t GetBytePerPixel() {CHECK_ZERO("Bytes per pixel", byte_per_pixel_); return byte_per_pixel_; }
269  size_t GetSurfaceSize() {CHECK_ZERO("Surface size", surface_size_); return surface_size_; }
270  uint32_t GetSurfaceStride() {CHECK_ZERO("Surface stride", surface_stride_); return surface_stride_; }
271  //RocDecImageFormat GetSubsampling() { return subsampling_; }
278  const char *GetCodecFmtName(rocDecVideoCodec codec_id);
279 
286  const char *GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id);
287 
295  virtual bool GetOutputSurfaceInfo(OutputSurfaceInfo **surface_info);
296 
304  bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush = false);
305 
322  virtual int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts = 0, int *num_decoded_pics = nullptr);
327  virtual uint8_t* GetFrame(int64_t *pts);
328 
337  virtual bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false);
338 
347  //void SaveImage(std::string output_file_name, void* dev_mem, OutputImageInfo* image_info, bool is_output_RGB = 0);
348 
358  void GetDeviceinfo(std::string &device_name, std::string &gcn_arch_name, int &pci_bus_id, int &pci_domain_id, int &pci_device_id);
359 
368  virtual void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size = 0);
369 
373  virtual void ResetSaveFrameToFile();
374 
380  int32_t GetNumOfFlushedFrames() { return num_frames_flushed_during_reconfig_;}
381 
385 
386  // Session overhead refers to decoder initialization and deinitialization time
387  void AddDecoderSessionOverHead(std::thread::id session_id, double duration) { session_overhead_[session_id] += duration; }
388  double GetDecoderSessionOverHead(std::thread::id session_id) {
389  if (session_overhead_.find(session_id) != session_overhead_.end()) {
390  return session_overhead_[session_id];
391  } else {
392  return 0;
393  }
394  }
395 
401  bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth);
402 
406  virtual int ReconfigureDecoder(RocdecVideoFormat *p_video_format);
407 
408  protected:
412  static int ROCDECAPI HandleVideoSequenceProc(void *p_user_data, RocdecVideoFormat *p_video_format) { return ((RocVideoDecoder *)p_user_data)->HandleVideoSequence(p_video_format); }
413 
417  static int ROCDECAPI HandlePictureDecodeProc(void *p_user_data, RocdecPicParams *p_pic_params) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDecode(p_pic_params); }
418 
422  static int ROCDECAPI HandlePictureDisplayProc(void *p_user_data, RocdecParserDispInfo *p_disp_info) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDisplay(p_disp_info); }
423 
427  static int ROCDECAPI HandleSEIMessagesProc(void *p_user_data, RocdecSeiMessageInfo *p_sei_message_info) { return ((RocVideoDecoder *)p_user_data)->GetSEIMessage(p_sei_message_info); }
428 
434 
440 
449  int GetSEIMessage(RocdecSeiMessageInfo *p_sei_message_info);
450 
458 
463  bool InitHIP(int device_id);
464 
469  std::chrono::_V2::system_clock::time_point StartTimer();
470 
475  double StopTimer(const std::chrono::_V2::system_clock::time_point &start_time);
476 
477  int num_devices_;
478  int device_id_;
479  RocdecVideoParser rocdec_parser_ = nullptr;
480  rocDecDecoderHandle roc_decoder_ = nullptr;
481  OutputSurfaceMemoryType out_mem_type_ = OUT_SURFACE_MEM_DEV_INTERNAL;
482  rocDecVideoCodec codec_id_ = rocDecVideoCodec_NumCodecs;
483  bool b_force_zero_latency_ = false;
484  bool b_extract_sei_message_ = false;
485  uint32_t disp_delay_;
486  ReconfigParams *p_reconfig_params_ = nullptr;
487  bool b_force_recofig_flush_ = false;
488  int32_t num_frames_flushed_during_reconfig_ = 0;
489  hipDeviceProp_t hip_dev_prop_;
490  hipStream_t hip_stream_ = nullptr;
491  rocDecVideoChromaFormat video_chroma_format_ = rocDecVideoChromaFormat_420;
492  rocDecVideoSurfaceFormat video_surface_format_ = rocDecVideoSurfaceFormat_NV12;
493  RocdecSeiMessageInfo *curr_sei_message_ptr_ = nullptr;
494  RocdecSeiMessageInfo sei_message_display_q_[MAX_FRAME_NUM];
495  RocdecVideoFormat *curr_video_format_ptr_ = nullptr;
496  int output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0;
497  int decoded_pic_cnt_ = 0;
498  int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM];
499  int num_alloced_frames_ = 0;
500  int last_decode_surf_idx_ = 0;
501  std::ostringstream input_video_info_str_;
502  int bitdepth_minus_8_ = 0;
503  uint32_t byte_per_pixel_ = 1;
504  uint32_t coded_width_ = 0;
505  uint32_t disp_width_ = 0;
506  uint32_t coded_height_ = 0;
507  uint32_t disp_height_ = 0;
508  uint32_t target_width_ = 0;
509  uint32_t target_height_ = 0;
510  int max_width_ = 0, max_height_ = 0;
511  uint32_t chroma_height_ = 0, chroma_width_ = 0;
512  uint32_t num_decode_surfaces_ = 0;
513  uint32_t num_chroma_planes_ = 0;
514  uint32_t num_components_ = 0;
515  uint32_t surface_stride_ = 0;
516  uint32_t surface_vstride_ = 0, chroma_vstride_ = 0; // vertical stride between planes: used when using internal dev memory
517  size_t surface_size_ = 0;
518  OutputSurfaceInfo output_surface_info_ = {};
519  std::mutex mtx_vp_frame_;
520  std::vector<DecFrameBuffer> vp_frames_; // vector of decoded frames
521  std::queue<DecFrameBuffer> vp_frames_q_;
522  Rect disp_rect_ = {}; // displayable area specified in the bitstream
523  Rect crop_rect_ = {}; // user specified region of interest within diplayable area disp_rect_
524  FILE *fp_sei_ = NULL;
525  FILE *fp_out_ = NULL;
526  bool is_output_surface_changed_ = false;
527  std::string current_output_filename = "";
528  uint32_t extra_output_file_count_ = 0;
529  std::thread::id decoder_session_id_; // Decoder session identifier. Used to gather session level stats.
530  std::unordered_map<std::thread::id, double> session_overhead_; // Records session overhead of initialization+deinitialization time. Format is (thread id, duration)
531 };
Definition: roc_video_dec.h:117
Definition: roc_video_dec.h:204
virtual void ResetSaveFrameToFile()
Helper funtion to close a existing file and dump to new file in case of multiple files using same dec...
virtual bool GetOutputSurfaceInfo(OutputSurfaceInfo **surface_info)
Get the pointer to the Output Image Info.
virtual bool ReleaseFrame(int64_t pTimestamp, bool b_flushing=false)
function to release frame after use by the application: Only used with "OUT_SURFACE_MEM_DEV_INTERNAL"
int FlushAndReconfigure()
Function to force Reconfigure Flush: needed for random seeking to key frames.
void WaitForDecodeCompletion()
Function to wait for the decode completion of the last submitted picture.
int32_t GetNumOfFlushedFrames()
Get the Num Of Flushed Frames from video decoder object.
Definition: roc_video_dec.h:380
const char * GetCodecFmtName(rocDecVideoCodec codec_id)
Get the name of the output format.
uint32_t GetWidth()
Get the output frame width.
Definition: roc_video_dec.h:231
int GetNumChromaPlanes()
This function is used to get the number of chroma planes.
Definition: roc_video_dec.h:251
virtual int ReconfigureDecoder(RocdecVideoFormat *p_video_format)
This function reconfigure decoder if there is a change in sequence params.
static int ROCDECAPI HandlePictureDisplayProc(void *p_user_data, RocdecParserDispInfo *p_disp_info)
Callback function to be registered for getting a callback when a decoded frame is available for displ...
Definition: roc_video_dec.h:422
int HandlePictureDisplay(RocdecParserDispInfo *p_disp_info)
This function gets called after a picture is decoded and available for display. Frames are fetched an...
int GetChromaHeight()
This function is used to get the current chroma height.
Definition: roc_video_dec.h:246
uint32_t GetHeight()
Get the output frame height.
Definition: roc_video_dec.h:241
int GetSEIMessage(RocdecSeiMessageInfo *p_sei_message_info)
This function gets called when all unregistered user SEI messages are parsed for a frame.
uint32_t GetBitDepth()
Get the Bit Depth and BytesPerPixel associated with the pixel format.
Definition: roc_video_dec.h:264
double StopTimer(const std::chrono::_V2::system_clock::time_point &start_time)
Function to get elapsed time.
static int ROCDECAPI HandlePictureDecodeProc(void *p_user_data, RocdecPicParams *p_pic_params)
Callback function to be registered for getting a callback when a decoded frame is ready to be decoded...
Definition: roc_video_dec.h:417
bool InitHIP(int device_id)
Function to Initialize GPU-HIP.
bool ReleaseInternalFrames()
function to release all internal frames and clear the vp_frames_q_ (used with reconfigure): Only used...
virtual uint8_t * GetFrame(int64_t *pts)
This function returns a decoded frame and timestamp. This should be called in a loop fetching all the...
virtual void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size=0)
Helper function to dump decoded output surface to file.
void GetDeviceinfo(std::string &device_name, std::string &gcn_arch_name, int &pci_bus_id, int &pci_domain_id, int &pci_device_id)
utility function to save image to a file
bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth)
Check if the given Video Codec is supported on the given GPU.
std::chrono::_V2::system_clock::time_point StartTimer()
Function to get start time.
virtual int GetFrameSize()
This function is used to get the current frame size based on pixel format.
Definition: roc_video_dec.h:256
const char * GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id)
function to return the name from surface_format_id
size_t GetSurfaceSize()
Functions to get the output surface attributes.
Definition: roc_video_dec.h:269
static int ROCDECAPI HandleSEIMessagesProc(void *p_user_data, RocdecSeiMessageInfo *p_sei_message_info)
Callback function to be registered for getting a callback when all the unregistered user SEI Messages...
Definition: roc_video_dec.h:427
virtual int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts=0, int *num_decoded_pics=nullptr)
this function decodes a frame and returns the number of frames avalable for display
int GetDecodeWidth()
This function is used to get the actual decode width.
Definition: roc_video_dec.h:236
RocVideoDecoder(int device_id, OutputSurfaceMemoryType out_mem_type, rocDecVideoCodec codec, bool force_zero_latency=false, const Rect *p_crop_rect=nullptr, bool extract_user_SEI_Message=false, uint32_t disp_delay=0, int max_width=0, int max_height=0, uint32_t clk_rate=1000, bool skip_init=false)
Construct a new Roc Video Decoder object.
int HandlePictureDecode(RocdecPicParams *p_pic_params)
This function gets called when a picture is ready to be decoded. rocDecDecodeFrame is called from thi...
bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush=false)
Function to set the Reconfig Params object.
int HandleVideoSequence(RocdecVideoFormat *p_video_format)
This function gets called when a sequence is ready to be decoded. The function also gets called when ...
static int ROCDECAPI HandleVideoSequenceProc(void *p_user_data, RocdecVideoFormat *p_video_format)
Callback function to be registered for getting a callback when decoding of sequence starts.
Definition: roc_video_dec.h:412
OutputSurfaceMemoryType_enum
Definition: roc_video_dec.h:60
@ OUT_SURFACE_MEM_HOST_COPIED
Definition: roc_video_dec.h:63
@ OUT_SURFACE_MEM_DEV_COPIED
Definition: roc_video_dec.h:62
@ OUT_SURFACE_MEM_DEV_INTERNAL
Definition: roc_video_dec.h:61
@ OUT_SURFACE_MEM_NOT_MAPPED
Definition: roc_video_dec.h:64
The AMD rocDecode Library.
@ rocDecVideoCodec_NumCodecs
Definition: rocdecode.h:87
@ rocDecVideoSurfaceFormat_YUV420
Definition: rocdecode.h:109
@ rocDecVideoSurfaceFormat_YUV422
Definition: rocdecode.h:112
@ rocDecVideoSurfaceFormat_YUV444_16Bit
Definition: rocdecode.h:107
@ rocDecVideoSurfaceFormat_YUV420_16Bit
Definition: rocdecode.h:110
@ rocDecVideoSurfaceFormat_P016
Definition: rocdecode.h:104
@ rocDecVideoSurfaceFormat_NV12
Definition: rocdecode.h:103
@ rocDecVideoSurfaceFormat_YUV422_16Bit
Definition: rocdecode.h:113
@ rocDecVideoSurfaceFormat_YUV444
Definition: rocdecode.h:106
void * rocDecDecoderHandle
Definition: rocdecode.h:51
@ rocDecVideoChromaFormat_420
Definition: rocdecode.h:125
The AMD rocParser Library.
void * RocdecVideoParser
Definition: rocparser.h:46
Definition: roc_video_dec.h:176
uint8_t * frame_ptr
Definition: roc_video_dec.h:177
int picture_index
Definition: roc_video_dec.h:179
int64_t pts
Definition: roc_video_dec.h:178
Definition: roc_video_dec.h:168
Definition: roc_video_dec.h:183
uint32_t output_vstride
Definition: roc_video_dec.h:187
uint32_t output_pitch
Definition: roc_video_dec.h:186
uint32_t output_height
Definition: roc_video_dec.h:185
uint32_t chroma_height
Definition: roc_video_dec.h:188
uint64_t output_surface_size_in_bytes
Definition: roc_video_dec.h:193
uint32_t num_chroma_planes
Definition: roc_video_dec.h:192
uint32_t bit_depth
Definition: roc_video_dec.h:191
uint32_t bytes_per_pixel
Definition: roc_video_dec.h:190
rocDecVideoSurfaceFormat surface_format
Definition: roc_video_dec.h:194
Rect disp_rect
Definition: roc_video_dec.h:189
uint32_t output_width
Definition: roc_video_dec.h:184
OutputSurfaceMemoryType mem_type
Definition: roc_video_dec.h:195
Definition: roc_video_dec.h:198
Definition: roc_video_dec.h:161
Timing Info struct\Used in rocdecParseVideoData API with PFNVIDDISPLAYCALLBACK pfn_display_picture.
ROCDEC_VIDEO_FORMAT structUsed in Parser callback API.
Definition: rocparser.h:64
Definition: rocdecode.h:1619