develop/projects/rocdecode/utils/rocvideodecode/roc_video_dec.h Source File

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

rocDecode: develop/projects/rocdecode/utils/rocvideodecode/roc_video_dec.h Source File
roc_video_dec.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2023 - 2026 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 <iomanip>
32 #include <string.h>
33 #include <queue>
34 #include <stdexcept>
35 #include <exception>
36 #include <cstring>
37 #include <unordered_map>
38 #include <chrono>
39 #include <thread>
40 #include <ctime>
41 #include <time.h>
42 #include <unistd.h>
43 #include <sys/syscall.h>
44 #include <hip/hip_runtime.h>
45 #include "rocdecode/rocdecode.h"
46 #include "rocdecode/rocparser.h"
47 
48 #define ROCVIDEODEC_TOSTR(X) std::to_string(X)
49 #define ROCVIDEODEC_STR(X) std::string(X)
50 
51 // Simple logging macros - format matches src/commons.h:
52 // [0, Critical] filename:line: timestamp_us us: [pid:X tid:Y hashid:0xZZZZZ] func(): message
53 #define RocVideoDecCriticalLog(msg) \
54  do { \
55  struct timespec _ts_; \
56  clock_gettime(CLOCK_MONOTONIC, &_ts_); \
57  uint64_t _us_ = static_cast<uint64_t>(_ts_.tv_sec) * 1000000ULL + _ts_.tv_nsec / 1000ULL; \
58  const char *_f_ = strrchr(__FILE__, '/'); \
59  pid_t _tid_ = static_cast<pid_t>(syscall(SYS_gettid)); \
60  std::ostringstream _htid_oss_; \
61  _htid_oss_ << "0x" << std::hex << std::setw(5) << std::setfill('0') \
62  << (std::hash<std::thread::id>{}(std::this_thread::get_id()) & 0xFFFFF); \
63  std::cerr << "[0, Critical] " << (_f_ ? _f_ + 1 : __FILE__) \
64  << ":" << __LINE__ << ": " << _us_ << " us: [pid:" \
65  << getpid() << " tid:" << _tid_ << " hashid:" << _htid_oss_.str() << "] " \
66  << __func__ << "(): " << (msg) << std::endl; \
67  } while (0)
68 
77 #define MAX_FRAME_NUM 16
78 
79 typedef int (ROCDECAPI *PFNRECONFIGUEFLUSHCALLBACK)(void *, uint32_t, void *);
80 
81 typedef enum SeiAvcHevcPayloadType_enum {
82  SEI_TYPE_TIME_CODE = 136,
83  SEI_TYPE_USER_DATA_UNREGISTERED = 5
84 } SeiAvcHevcPayloadType;
85 
91 } OutputSurfaceMemoryType;
92 
93 inline int GetChromaPlaneCount(rocDecVideoSurfaceFormat surface_format) {
94  int num_planes = 1;
95  switch (surface_format) {
98  default:
99  num_planes = 1;
100  break;
107  num_planes = 2;
108  break;
109  }
110 
111  return num_planes;
112 };
113 
114 inline float GetChromaHeightFactor(rocDecVideoSurfaceFormat surface_format) {
115  float factor = 0.5;
116  switch (surface_format) {
121  default:
122  factor = 0.5;
123  break;
128  factor = 1.0;
129  break;
130  }
131 
132  return factor;
133 };
134 
135 class RocVideoDecodeException : public std::exception {
136 public:
137 
138  explicit RocVideoDecodeException(const std::string& message, const int err_code):_message(message), _err_code(err_code) {}
139  explicit RocVideoDecodeException(const std::string& message):_message(message), _err_code(-1) {}
140  virtual const char* what() const throw() override {
141  return _message.c_str();
142  }
143  int Geterror_code() const { return _err_code; }
144 private:
145  std::string _message;
146  int _err_code;
147 };
148 
149 #define ROCDEC_THROW(X, CODE) throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X , CODE);
150 
151 #define ROCDEC_API_CALL( rocDecAPI ) \
152  do { \
153  rocDecStatus error_code = rocDecAPI; \
154  if( error_code != ROCDEC_SUCCESS) { \
155  std::ostringstream error_log; \
156  error_log << #rocDecAPI << " returned " << rocDecGetErrorName(error_code) << " at " <<__FILE__ <<":" << __LINE__;\
157  ROCDEC_THROW(error_log.str(), error_code); \
158  } \
159  } while (0)
160 
161 #define HIP_API_CALL( call ) \
162  do { \
163  hipError_t hip_status = call; \
164  if (hip_status != hipSuccess) { \
165  const char *sz_err_name = NULL; \
166  sz_err_name = hipGetErrorName(hip_status); \
167  std::ostringstream error_log; \
168  error_log << "hip API error " << sz_err_name ; \
169  ROCDEC_THROW(error_log.str(), hip_status); \
170  } \
171  } \
172  while (0)
173 
174 #define CHECK_ZERO(str, value) \
175  do { \
176  if (value == 0) { \
177  RocVideoDecCriticalLog(ROCVIDEODEC_STR(str) + " is 0."); \
178  } \
179  } while (0)
180 
181 struct Rect {
182  int left;
183  int top;
184  int right;
185  int bottom;
186 };
187 
188 struct Dim {
189  int w, h;
190 };
191 
192 static inline int align(int value, int alignment) {
193  return (value + alignment - 1) & ~(alignment - 1);
194 }
195 
196 typedef struct DecFrameBuffer_ {
197  uint8_t *frame_ptr;
198  int64_t pts;
201 
202 
203 typedef struct OutputSurfaceInfoType {
204  uint32_t output_width;
205  uint32_t output_height;
206  uint32_t output_pitch;
207  uint32_t output_vstride;
208  uint32_t chroma_height;
210  uint32_t bytes_per_pixel;
211  uint32_t bit_depth;
212  uint32_t num_chroma_planes;
214  rocDecVideoSurfaceFormat surface_format;
215  OutputSurfaceMemoryType mem_type;
217 
218 typedef struct ReconfigParams_t {
219  PFNRECONFIGUEFLUSHCALLBACK p_fn_reconfigure_flush;
220  void *p_reconfig_user_struct;
221  uint32_t reconfig_flush_mode;
223 
225  public:
240  RocVideoDecoder(int device_id, OutputSurfaceMemoryType out_mem_type, rocDecVideoCodec codec, bool force_zero_latency = false,
241  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,
242  uint32_t clk_rate = 1000, bool skip_init = false);
243 
244  virtual ~RocVideoDecoder();
245 
246  rocDecVideoCodec GetCodecId() { return codec_id_; }
247 
251  uint32_t GetWidth() {CHECK_ZERO("Display width", disp_width_); return disp_width_;}
252 
256  int GetDecodeWidth() {CHECK_ZERO("Coded width", coded_width_); return coded_width_; }
257 
261  uint32_t GetHeight() {CHECK_ZERO("Display height", disp_height_); return disp_height_; }
262 
266  int GetChromaHeight() {CHECK_ZERO("Chroma height", chroma_height_); return chroma_height_; }
267 
271  int GetNumChromaPlanes() {return num_chroma_planes_; }
272 
276  virtual int GetFrameSize() {CHECK_ZERO("Display width", disp_width_); return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * byte_per_pixel_; }
277 
278 
284  uint32_t GetBitDepth() {return (bitdepth_minus_8_ + 8); }
285  uint32_t GetBytePerPixel() {CHECK_ZERO("Bytes per pixel", byte_per_pixel_); return byte_per_pixel_; }
289  size_t GetSurfaceSize() {CHECK_ZERO("Surface size", surface_size_); return surface_size_; }
290  uint32_t GetSurfaceStride() {CHECK_ZERO("Surface stride", surface_stride_); return surface_stride_; }
291  //RocDecImageFormat GetSubsampling() { return subsampling_; }
298  const char *GetCodecFmtName(rocDecVideoCodec codec_id);
299 
306  const char *GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id);
307 
315  virtual bool GetOutputSurfaceInfo(OutputSurfaceInfo **surface_info);
316 
324  bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush = false);
325 
342  virtual int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts = 0, int *num_decoded_pics = nullptr);
347  virtual uint8_t* GetFrame(int64_t *pts);
348 
357  virtual bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false);
358 
367  //void SaveImage(std::string output_file_name, void* dev_mem, OutputImageInfo* image_info, bool is_output_RGB = 0);
368 
378  void GetDeviceinfo(std::string &device_name, std::string &gcn_arch_name, int &pci_bus_id, int &pci_domain_id, int &pci_device_id);
379 
388  virtual void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size = 0);
389 
393  virtual void ResetSaveFrameToFile();
394 
400  int32_t GetNumOfFlushedFrames() { return num_frames_flushed_during_reconfig_;}
401 
405 
406  // Session overhead refers to decoder initialization and deinitialization time
407  void AddDecoderSessionOverHead(std::thread::id session_id, double duration) { session_overhead_[session_id] += duration; }
408  double GetDecoderSessionOverHead(std::thread::id session_id) {
409  if (session_overhead_.find(session_id) != session_overhead_.end()) {
410  return session_overhead_[session_id];
411  } else {
412  return 0;
413  }
414  }
415 
421  bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth);
422 
426  virtual int ReconfigureDecoder(RocdecVideoFormat *p_video_format);
427 
428  protected:
432  static int ROCDECAPI HandleVideoSequenceProc(void *p_user_data, RocdecVideoFormat *p_video_format) { return ((RocVideoDecoder *)p_user_data)->HandleVideoSequence(p_video_format); }
433 
437  static int ROCDECAPI HandlePictureDecodeProc(void *p_user_data, RocdecPicParams *p_pic_params) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDecode(p_pic_params); }
438 
442  static int ROCDECAPI HandlePictureDisplayProc(void *p_user_data, RocdecParserDispInfo *p_disp_info) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDisplay(p_disp_info); }
443 
447  static int ROCDECAPI HandleSEIMessagesProc(void *p_user_data, RocdecSeiMessageInfo *p_sei_message_info) { return ((RocVideoDecoder *)p_user_data)->GetSEIMessage(p_sei_message_info); }
448 
454 
460 
469  int GetSEIMessage(RocdecSeiMessageInfo *p_sei_message_info);
470 
478 
483  bool InitHIP(int device_id);
484 
489  std::chrono::_V2::system_clock::time_point StartTimer();
490 
495  double StopTimer(const std::chrono::_V2::system_clock::time_point &start_time);
496 
497  int num_devices_;
498  int device_id_;
499  RocdecVideoParser rocdec_parser_ = nullptr;
500  rocDecDecoderHandle roc_decoder_ = nullptr;
501  OutputSurfaceMemoryType out_mem_type_ = OUT_SURFACE_MEM_DEV_INTERNAL;
502  rocDecVideoCodec codec_id_ = rocDecVideoCodec_NumCodecs;
503  bool b_force_zero_latency_ = false;
504  bool b_extract_sei_message_ = false;
505  uint32_t disp_delay_;
506  ReconfigParams *p_reconfig_params_ = nullptr;
507  bool b_force_recofig_flush_ = false;
508  int32_t num_frames_flushed_during_reconfig_ = 0;
509  hipDeviceProp_t hip_dev_prop_;
510  hipStream_t hip_stream_ = nullptr;
511  rocDecVideoChromaFormat video_chroma_format_ = rocDecVideoChromaFormat_420;
512  rocDecVideoSurfaceFormat video_surface_format_ = rocDecVideoSurfaceFormat_NV12;
513  RocdecSeiMessageInfo *curr_sei_message_ptr_ = nullptr;
514  RocdecSeiMessageInfo sei_message_display_q_[MAX_FRAME_NUM];
515  RocdecVideoFormat *curr_video_format_ptr_ = nullptr;
516  int output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0;
517  int decoded_pic_cnt_ = 0;
518  int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM];
519  int num_alloced_frames_ = 0;
520  int last_decode_surf_idx_ = 0;
521  std::ostringstream input_video_info_str_;
522  int bitdepth_minus_8_ = 0;
523  uint32_t byte_per_pixel_ = 1;
524  uint32_t coded_width_ = 0;
525  uint32_t disp_width_ = 0;
526  uint32_t coded_height_ = 0;
527  uint32_t disp_height_ = 0;
528  uint32_t target_width_ = 0;
529  uint32_t target_height_ = 0;
530  int max_width_ = 0, max_height_ = 0;
531  uint32_t chroma_height_ = 0, chroma_width_ = 0;
532  uint32_t num_decode_surfaces_ = 0;
533  uint32_t num_chroma_planes_ = 0;
534  uint32_t num_components_ = 0;
535  uint32_t surface_stride_ = 0;
536  uint32_t surface_vstride_ = 0, chroma_vstride_ = 0; // vertical stride between planes: used when using internal dev memory
537  size_t surface_size_ = 0;
538  OutputSurfaceInfo output_surface_info_ = {};
539  std::mutex mtx_vp_frame_;
540  std::vector<DecFrameBuffer> vp_frames_; // vector of decoded frames
541  std::queue<DecFrameBuffer> vp_frames_q_;
542  Rect disp_rect_ = {}; // displayable area specified in the bitstream
543  Rect crop_rect_ = {}; // user specified region of interest within diplayable area disp_rect_
544  FILE *fp_sei_ = NULL;
545  FILE *fp_out_ = NULL;
546  bool is_output_surface_changed_ = false;
547  std::string current_output_filename = "";
548  uint32_t extra_output_file_count_ = 0;
549  std::thread::id decoder_session_id_; // Decoder session identifier. Used to gather session level stats.
550  std::unordered_map<std::thread::id, double> session_overhead_; // Records session overhead of initialization+deinitialization time. Format is (thread id, duration)
551 };
Definition: roc_video_dec.h:135
Definition: roc_video_dec.h:224
virtual void ResetSaveFrameToFile()
Helper function to close an existing file and dump to new file in case of multiple files using same d...
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:400
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:251
int GetNumChromaPlanes()
This function is used to get the number of chroma planes.
Definition: roc_video_dec.h:271
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:442
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:266
uint32_t GetHeight()
Get the output frame height.
Definition: roc_video_dec.h:261
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:284
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:437
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:276
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:289
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:447
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 available for display
int GetDecodeWidth()
This function is used to get the actual decode width.
Definition: roc_video_dec.h:256
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:432
OutputSurfaceMemoryType_enum
Definition: roc_video_dec.h:86
@ OUT_SURFACE_MEM_HOST_COPIED
Definition: roc_video_dec.h:89
@ OUT_SURFACE_MEM_DEV_COPIED
Definition: roc_video_dec.h:88
@ OUT_SURFACE_MEM_DEV_INTERNAL
Definition: roc_video_dec.h:87
@ OUT_SURFACE_MEM_NOT_MAPPED
Definition: roc_video_dec.h:90
The AMD rocDecode Library.
@ rocDecVideoCodec_NumCodecs
Definition: rocdecode.h:87
@ rocDecVideoSurfaceFormat_YUV420
Definition: rocdecode.h:111
@ rocDecVideoSurfaceFormat_YUV422
Definition: rocdecode.h:114
@ rocDecVideoSurfaceFormat_YUV444_16Bit
Definition: rocdecode.h:109
@ rocDecVideoSurfaceFormat_YUV420_16Bit
Definition: rocdecode.h:112
@ rocDecVideoSurfaceFormat_P016
Definition: rocdecode.h:106
@ rocDecVideoSurfaceFormat_NV12
Definition: rocdecode.h:105
@ rocDecVideoSurfaceFormat_YUV422_16Bit
Definition: rocdecode.h:115
@ rocDecVideoSurfaceFormat_YUV444
Definition: rocdecode.h:108
void * rocDecDecoderHandle
Definition: rocdecode.h:51
@ rocDecVideoChromaFormat_420
Definition: rocdecode.h:134
The AMD rocParser Library.
void * RocdecVideoParser
Definition: rocparser.h:46
Definition: roc_video_dec.h:196
uint8_t * frame_ptr
Definition: roc_video_dec.h:197
int picture_index
Definition: roc_video_dec.h:199
int64_t pts
Definition: roc_video_dec.h:198
Definition: roc_video_dec.h:188
Definition: roc_video_dec.h:203
uint32_t output_vstride
Definition: roc_video_dec.h:207
uint32_t output_pitch
Definition: roc_video_dec.h:206
uint32_t output_height
Definition: roc_video_dec.h:205
uint32_t chroma_height
Definition: roc_video_dec.h:208
uint64_t output_surface_size_in_bytes
Definition: roc_video_dec.h:213
uint32_t num_chroma_planes
Definition: roc_video_dec.h:212
uint32_t bit_depth
Definition: roc_video_dec.h:211
uint32_t bytes_per_pixel
Definition: roc_video_dec.h:210
rocDecVideoSurfaceFormat surface_format
Definition: roc_video_dec.h:214
Rect disp_rect
Definition: roc_video_dec.h:209
uint32_t output_width
Definition: roc_video_dec.h:204
OutputSurfaceMemoryType mem_type
Definition: roc_video_dec.h:215
Definition: roc_video_dec.h:218
Definition: roc_video_dec.h:181
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:1628