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 - 2024 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 <assert.h>
26 #include <stdint.h>
27 #include <mutex>
28 #include <vector>
29 #include <string>
30 #include <iostream>
31 #include <sstream>
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 <hip/hip_runtime.h>
40 extern "C" {
41 #include "libavutil/md5.h"
42 #include "libavutil/mem.h"
43 }
44 #include "rocdecode.h"
45 #include "rocparser.h"
46 
55 #define MAX_FRAME_NUM 16
56 
57 typedef int (ROCDECAPI *PFNRECONFIGUEFLUSHCALLBACK)(void *, uint32_t, void *);
58 
59 typedef enum SeiAvcHevcPayloadType_enum {
60  SEI_TYPE_TIME_CODE = 136,
61  SEI_TYPE_USER_DATA_UNREGISTERED = 5
62 } SeiAvcHevcPayloadType;
63 
69 } OutputSurfaceMemoryType;
70 
71 #define TOSTR(X) std::to_string(static_cast<int>(X))
72 #define STR(X) std::string(X)
73 
74 #if DBGINFO
75 #define INFO(X) std::clog << "[INF] " << " {" << __func__ <<"} " << " " << X << std::endl;
76 #else
77 #define INFO(X) ;
78 #endif
79 #define ERR(X) std::cerr << "[ERR] " << " {" << __func__ <<"} " << " " << X << std::endl;
80 
81 class RocVideoDecodeException : public std::exception {
82 public:
83 
84  explicit RocVideoDecodeException(const std::string& message, const int err_code):_message(message), _err_code(err_code) {}
85  explicit RocVideoDecodeException(const std::string& message):_message(message), _err_code(-1) {}
86  virtual const char* what() const throw() override {
87  return _message.c_str();
88  }
89  int Geterror_code() const { return _err_code; }
90 private:
91  std::string _message;
92  int _err_code;
93 };
94 
95 #define ROCDEC_THROW(X, CODE) throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X , CODE);
96 #define THROW(X) throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X);
97 
98 #define ROCDEC_API_CALL( rocDecAPI ) \
99  do { \
100  rocDecStatus error_code = rocDecAPI; \
101  if( error_code != ROCDEC_SUCCESS) { \
102  std::ostringstream error_log; \
103  error_log << #rocDecAPI << " returned " << rocDecGetErrorName(error_code) << " at " <<__FILE__ <<":" << __LINE__;\
104  ROCDEC_THROW(error_log.str(), error_code); \
105  } \
106  } while (0)
107 
108 #define HIP_API_CALL( call ) \
109  do { \
110  hipError_t hip_status = call; \
111  if (hip_status != hipSuccess) { \
112  const char *sz_err_name = NULL; \
113  sz_err_name = hipGetErrorName(hip_status); \
114  std::ostringstream error_log; \
115  error_log << "hip API error " << sz_err_name ; \
116  ROCDEC_THROW(error_log.str(), hip_status); \
117  } \
118  } \
119  while (0)
120 
121 
122 struct Rect {
123  int left;
124  int top;
125  int right;
126  int bottom;
127 };
128 
129 struct Dim {
130  int w, h;
131 };
132 
133 static inline int align(int value, int alignment) {
134  return (value + alignment - 1) & ~(alignment - 1);
135 }
136 
137 typedef struct DecFrameBuffer_ {
138  uint8_t *frame_ptr;
139  int64_t pts;
142 
143 
144 typedef struct OutputSurfaceInfoType {
145  uint32_t output_width;
146  uint32_t output_height;
147  uint32_t output_pitch;
148  uint32_t output_vstride;
149  uint32_t bytes_per_pixel;
150  uint32_t bit_depth;
151  uint32_t num_chroma_planes;
153  rocDecVideoSurfaceFormat surface_format;
154  OutputSurfaceMemoryType mem_type;
156 
157 typedef struct ReconfigParams_t {
158  PFNRECONFIGUEFLUSHCALLBACK p_fn_reconfigure_flush;
159  void *p_reconfig_user_struct;
160  uint32_t reconfig_flush_mode;
162 
164  public:
181  RocVideoDecoder(int device_id, OutputSurfaceMemoryType out_mem_type, rocDecVideoCodec codec, bool force_zero_latency = false,
182  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,
183  uint32_t clk_rate = 1000);
184  ~RocVideoDecoder();
185 
186  rocDecVideoCodec GetCodecId() { return codec_id_; }
187 
188  hipStream_t GetStream() {return hip_stream_;}
189 
193  uint32_t GetWidth() { assert(disp_width_); return disp_width_;}
194 
198  int GetDecodeWidth() { assert(coded_width_); return coded_width_; }
199 
203  uint32_t GetHeight() { assert(disp_height_); return disp_height_; }
204 
208  int GetChromaHeight() { assert(chroma_height_); return chroma_height_; }
209 
213  int GetNumChromaPlanes() { assert(num_chroma_planes_); return num_chroma_planes_; }
214 
218  int GetFrameSize() { assert(disp_width_); return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * byte_per_pixel_; }
219 
223  int GetFrameSizePitched() { assert(surface_stride_); return surface_stride_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)); }
224 
230  uint32_t GetBitDepth() { assert(bitdepth_minus_8_); return (bitdepth_minus_8_ + 8); }
231  uint32_t GetBytePerPixel() { assert(byte_per_pixel_); return byte_per_pixel_; }
235  size_t GetSurfaceSize() { assert(surface_size_); return surface_size_; }
236  uint32_t GetSurfaceStride() { assert(surface_stride_); return surface_stride_; }
237  //RocDecImageFormat GetSubsampling() { return subsampling_; }
244  const char *GetCodecFmtName(rocDecVideoCodec codec_id);
245 
252  const char *GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id);
253 
262 
270  bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush = false);
271 
288  int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts = 0, int *num_decoded_pics = nullptr);
293  uint8_t* GetFrame(int64_t *pts);
294 
303  bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false);
304 
313  //void SaveImage(std::string output_file_name, void* dev_mem, OutputImageInfo* image_info, bool is_output_RGB = 0);
314 
324  void GetDeviceinfo(std::string &device_name, std::string &gcn_arch_name, int &pci_bus_id, int &pci_domain_id, int &pci_device_id);
325 
334  void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size = 0);
335 
340 
344  void InitMd5();
345 
346  void UpdateMd5ForDataBuffer(void *pDevMem, int rgb_image_size);
347 
354  void UpdateMd5ForFrame(void *surf_mem, OutputSurfaceInfo *surf_info);
355 
361  void FinalizeMd5(uint8_t **digest);
367  int32_t GetNumOfFlushedFrames() { return num_frames_flushed_during_reconfig_;}
368 
372 
373  // Session overhead refers to decoder initialization and deinitialization time
374  void AddDecoderSessionOverHead(std::thread::id session_id, double duration) { session_overhead_[session_id] += duration; }
375  double GetDecoderSessionOverHead(std::thread::id session_id) {
376  if (session_overhead_.find(session_id) != session_overhead_.end()) {
377  return session_overhead_[session_id];
378  } else {
379  return 0;
380  }
381  }
382 
388  bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth);
389 
390  private:
394  static int ROCDECAPI HandleVideoSequenceProc(void *p_user_data, RocdecVideoFormat *p_video_format) { return ((RocVideoDecoder *)p_user_data)->HandleVideoSequence(p_video_format); }
395 
399  static int ROCDECAPI HandlePictureDecodeProc(void *p_user_data, RocdecPicParams *p_pic_params) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDecode(p_pic_params); }
400 
404  static int ROCDECAPI HandlePictureDisplayProc(void *p_user_data, RocdecParserDispInfo *p_disp_info) { return ((RocVideoDecoder *)p_user_data)->HandlePictureDisplay(p_disp_info); }
405 
409  static int ROCDECAPI HandleSEIMessagesProc(void *p_user_data, RocdecSeiMessageInfo *p_sei_message_info) { return ((RocVideoDecoder *)p_user_data)->GetSEIMessage(p_sei_message_info); }
410 
415  int HandleVideoSequence(RocdecVideoFormat *p_video_format);
416 
421  int HandlePictureDecode(RocdecPicParams *p_pic_params);
422 
427  int HandlePictureDisplay(RocdecParserDispInfo *p_disp_info);
431  int GetSEIMessage(RocdecSeiMessageInfo *p_sei_message_info);
432 
436  int ReconfigureDecoder(RocdecVideoFormat *p_video_format);
437 
444  bool ReleaseInternalFrames();
445 
450  bool InitHIP(int device_id);
451 
456  std::chrono::_V2::system_clock::time_point StartTimer();
457 
462  double StopTimer(const std::chrono::_V2::system_clock::time_point &start_time);
463 
464  int num_devices_;
465  int device_id_;
466  RocdecVideoParser rocdec_parser_ = nullptr;
467  rocDecDecoderHandle roc_decoder_ = nullptr;
468  OutputSurfaceMemoryType out_mem_type_ = OUT_SURFACE_MEM_DEV_INTERNAL;
469  bool b_extract_sei_message_ = false;
470  bool b_force_zero_latency_ = false;
471  uint32_t disp_delay_;
472  ReconfigParams *p_reconfig_params_ = nullptr;
473  bool b_force_recofig_flush_ = false;
474  int32_t num_frames_flushed_during_reconfig_ = 0;
475  hipDeviceProp_t hip_dev_prop_;
476  hipStream_t hip_stream_;
477  rocDecVideoCodec codec_id_ = rocDecVideoCodec_NumCodecs;
478  rocDecVideoChromaFormat video_chroma_format_ = rocDecVideoChromaFormat_420;
479  rocDecVideoSurfaceFormat video_surface_format_ = rocDecVideoSurfaceFormat_NV12;
480  RocdecSeiMessageInfo *curr_sei_message_ptr_ = nullptr;
481  RocdecSeiMessageInfo sei_message_display_q_[MAX_FRAME_NUM];
482  RocdecVideoFormat *curr_video_format_ptr_ = nullptr;
483  int output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0;
484  int decoded_pic_cnt_ = 0;
485  int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM];
486  int num_alloced_frames_ = 0;
487  int last_decode_surf_idx_ = 0;
488  std::ostringstream input_video_info_str_;
489  int bitdepth_minus_8_ = 0;
490  uint32_t byte_per_pixel_ = 1;
491  uint32_t coded_width_ = 0;
492  uint32_t disp_width_ = 0;
493  uint32_t coded_height_ = 0;
494  uint32_t disp_height_ = 0;
495  uint32_t target_width_ = 0;
496  uint32_t target_height_ = 0;
497  int max_width_ = 0, max_height_ = 0;
498  uint32_t chroma_height_ = 0;
499  uint32_t num_chroma_planes_ = 0;
500  uint32_t num_components_ = 0;
501  uint32_t surface_stride_ = 0;
502  uint32_t surface_vstride_ = 0, chroma_vstride_ = 0; // vertical stride between planes: used when using internal dev memory
503  size_t surface_size_ = 0;
504  OutputSurfaceInfo output_surface_info_ = {};
505  std::mutex mtx_vp_frame_;
506  std::vector<DecFrameBuffer> vp_frames_; // vector of decoded frames
507  std::queue<DecFrameBuffer> vp_frames_q_;
508  Rect disp_rect_ = {}; // displayable area specified in the bitstream
509  Rect crop_rect_ = {}; // user specified region of interest within diplayable area disp_rect_
510  FILE *fp_sei_ = NULL;
511  FILE *fp_out_ = NULL;
512  struct AVMD5 *md5_ctx_;
513  uint8_t md5_digest_[16];
514  bool is_decoder_reconfigured_ = false;
515  std::string current_output_filename = "";
516  uint32_t extra_output_file_count_ = 0;
517  std::thread::id decoder_session_id_; // Decoder session identifier. Used to gather session level stats.
518  std::unordered_map<std::thread::id, double> session_overhead_; // Records session overhead of initialization+deinitialization time. Format is (thread id, duration)
519 };
Definition: roc_video_dec.h:81
Definition: roc_video_dec.h:163
int GetFrameSize()
This function is used to get the current frame size based on pixel format.
Definition: roc_video_dec.h:218
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.
uint8_t * GetFrame(int64_t *pts)
This function returns a decoded frame and timestamp. This should be called in a loop fetching all the...
int FlushAndReconfigure()
Function to force Reconfigure Flush: needed for random seeking to key frames.
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
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:367
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:193
int GetNumChromaPlanes()
This function is used to get the number of chroma planes.
Definition: roc_video_dec.h:213
void InitMd5()
Helper function to start MD5 calculation.
int GetChromaHeight()
This function is used to get the current chroma height.
Definition: roc_video_dec.h:208
uint32_t GetHeight()
Get the output frame height.
Definition: roc_video_dec.h:203
uint32_t GetBitDepth()
Get the Bit Depth and BytesPerPixel associated with the pixel format.
Definition: roc_video_dec.h:230
int GetFrameSizePitched()
This function is used to get the current frame size based on pitch.
Definition: roc_video_dec.h:223
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"
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.
const char * GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id)
function to return the name from surface_format_id
void ResetSaveFrameToFile()
Helper funtion to close a existing file and dump to new file in case of multiple files using same dec...
bool GetOutputSurfaceInfo(OutputSurfaceInfo **surface_info)
Get the pointer to the Output Image Info.
size_t GetSurfaceSize()
Functions to get the output surface attributes.
Definition: roc_video_dec.h:235
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)
Construct a new Roc Video Decoder object.
void UpdateMd5ForFrame(void *surf_mem, OutputSurfaceInfo *surf_info)
Helper function to dump decoded output surface to file.
void FinalizeMd5(uint8_t **digest)
Helper function to complete MD5 calculation.
int GetDecodeWidth()
This function is used to get the actual decode width.
Definition: roc_video_dec.h:198
bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush=false)
Function to set the Reconfig Params object.
OutputSurfaceMemoryType_enum
Definition: roc_video_dec.h:64
@ OUT_SURFACE_MEM_HOST_COPIED
Definition: roc_video_dec.h:67
@ OUT_SURFACE_MEM_DEV_COPIED
Definition: roc_video_dec.h:66
@ OUT_SURFACE_MEM_DEV_INTERNAL
Definition: roc_video_dec.h:65
@ OUT_SURFACE_MEM_NOT_MAPPED
Definition: roc_video_dec.h:68
The AMD rocDecode Library.
@ rocDecVideoCodec_NumCodecs
Definition: rocdecode.h:88
@ rocDecVideoSurfaceFormat_NV12
Definition: rocdecode.h:104
void * rocDecDecoderHandle
Definition: rocdecode.h:52
@ rocDecVideoChromaFormat_420
Definition: rocdecode.h:120
The AMD rocParser Library.
void * RocdecVideoParser
Definition: rocparser.h:46
Definition: roc_video_dec.h:137
uint8_t * frame_ptr
Definition: roc_video_dec.h:138
int picture_index
Definition: roc_video_dec.h:140
int64_t pts
Definition: roc_video_dec.h:139
Definition: roc_video_dec.h:129
Definition: roc_video_dec.h:144
uint32_t output_vstride
Definition: roc_video_dec.h:148
uint32_t output_pitch
Definition: roc_video_dec.h:147
uint32_t output_height
Definition: roc_video_dec.h:146
uint64_t output_surface_size_in_bytes
Definition: roc_video_dec.h:152
uint32_t num_chroma_planes
Definition: roc_video_dec.h:151
uint32_t bit_depth
Definition: roc_video_dec.h:150
uint32_t bytes_per_pixel
Definition: roc_video_dec.h:149
rocDecVideoSurfaceFormat surface_format
Definition: roc_video_dec.h:153
uint32_t output_width
Definition: roc_video_dec.h:145
OutputSurfaceMemoryType mem_type
Definition: roc_video_dec.h:154
Definition: roc_video_dec.h:157
Definition: roc_video_dec.h:122
Timing Info struct\Used in rocdecParseVideoData API with PFNVIDDISPLAYCALLBACK pfn_display_picture.
ROCDEC_VIDEO_FORMAT structUsed in Parser callback API.
Definition: rocparser.h:54
Definition: rocdecode.h:1378