ffmpeg software decoder implementation (#461)

* WIP: ffmpeg based software decoder

* minor update

* WIP: FFMpeg SW decoder support

* FFMpeg decoder working version

* working version without threading

* multithreading working with FFMpeg decoder

* moved ffmpeg decoder to separate folder

* updated changelog

* minor change

* resolved review comments

* resolved review comments

---------

Co-authored-by: Lakshmi Kumar <lakshmi.kumar@amd.com>
Tento commit je obsažen v:
Rajy Rawther
2024-12-04 11:11:02 -08:00
odevzdal GitHub
rodič 924d19eb65
revize 52eb62fabf
9 změnil soubory, kde provedl 1213 přidání a 81 odebrání
+66 -33
Zobrazit soubor
@@ -78,6 +78,45 @@ typedef enum OutputSurfaceMemoryType_enum {
#endif
#define ERR(X) std::cerr << "[ERR] " << " {" << __func__ <<"} " << " " << X << std::endl;
inline int GetChromaPlaneCount(rocDecVideoSurfaceFormat surface_format) {
int num_planes = 1;
switch (surface_format) {
case rocDecVideoSurfaceFormat_NV12:
case rocDecVideoSurfaceFormat_P016:
num_planes = 1;
break;
case rocDecVideoSurfaceFormat_YUV444:
case rocDecVideoSurfaceFormat_YUV444_16Bit:
num_planes = 2;
break;
case rocDecVideoSurfaceFormat_YUV420:
case rocDecVideoSurfaceFormat_YUV420_16Bit:
num_planes = 2;
break;
}
return num_planes;
};
inline float GetChromaHeightFactor(rocDecVideoSurfaceFormat surface_format) {
float factor = 0.5;
switch (surface_format) {
case rocDecVideoSurfaceFormat_NV12:
case rocDecVideoSurfaceFormat_P016:
case rocDecVideoSurfaceFormat_YUV420:
case rocDecVideoSurfaceFormat_YUV420_16Bit:
factor = 0.5;
break;
case rocDecVideoSurfaceFormat_YUV444:
case rocDecVideoSurfaceFormat_YUV444_16Bit:
factor = 1.0;
break;
}
return factor;
};
class RocVideoDecodeException : public std::exception {
public:
@@ -162,22 +201,20 @@ typedef struct ReconfigParams_t {
class RocVideoDecoder {
public:
/**
* @brief Construct a new Roc Video Decoder object
*
* @param hip_ctx
* @param b_use_device_mem
* @param codec
* @param device_id
* @param b_low_latency
* @param device_frame_pitched
* @param p_crop_rect
* @param extract_user_SEI_Message
* @param max_width
* @param max_height
* @param clk_rate
* @param force_zero_latency
*/
/**
* @brief Construct a new Roc Video Decoder object
*
* @param device_id : device_id to initialize HIP and VCN
* @param out_mem_type : out_mem_type for the decoded surface
* @param codec : codec type
* @param force_zero_latency : to force zero latency (output in decoding orde)
* @param p_crop_rect : to crop output
* @param extract_user_SEI_Message : enable to extract SEI
* @param disp_delay : output delayed by #disp_delay surfaces
* @param max_width : Max. width for the output surface
* @param max_height : Max. height for the output surface
* @param clk_rate : FPS clock-rate
*/
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);
@@ -215,12 +252,8 @@ class RocVideoDecoder {
/**
* @brief This function is used to get the current frame size based on pixel format.
*/
int GetFrameSize() { assert(disp_width_); return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * byte_per_pixel_; }
virtual int GetFrameSize() { assert(disp_width_); return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * byte_per_pixel_; }
/**
* @brief This function is used to get the current frame size based on pitch
*/
int GetFrameSizePitched() { assert(surface_stride_); return surface_stride_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)); }
/**
* @brief Get the Bit Depth and BytesPerPixel associated with the pixel format
@@ -285,12 +318,12 @@ class RocVideoDecoder {
* @param num_decoded_pics - nummber of pictures decoded in this call
* @return int - num of frames to display
*/
int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts = 0, int *num_decoded_pics = nullptr);
virtual int DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts = 0, int *num_decoded_pics = nullptr);
/**
* @brief This function returns a decoded frame and timestamp. This should be called in a loop fetching all the available frames
*
*/
uint8_t* GetFrame(int64_t *pts);
virtual uint8_t* GetFrame(int64_t *pts);
/**
* @brief function to release frame after use by the application: Only used with "OUT_SURFACE_MEM_DEV_INTERNAL"
@@ -300,7 +333,7 @@ class RocVideoDecoder {
* @return true - success
* @return false - falied
*/
bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false);
virtual bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false);
/**
* @brief utility function to save image to a file
@@ -331,12 +364,12 @@ class RocVideoDecoder {
* @param surf_info - surface info
* @param rgb_image_size - image size for rgb (optional). A non_zero value indicates the surf_mem holds an rgb interleaved image and the entire size will be dumped to file
*/
void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size = 0);
virtual void SaveFrameToFile(std::string output_file_name, void *surf_mem, OutputSurfaceInfo *surf_info, size_t rgb_image_size = 0);
/**
* @brief Helper funtion to close a existing file and dump to new file in case of multiple files using same decoder
*/
void ResetSaveFrameToFile();
virtual void ResetSaveFrameToFile();
/**
* @brief Helper function to start MD5 calculation
@@ -387,7 +420,12 @@ class RocVideoDecoder {
*/
bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth);
private:
/**
* @brief This function reconfigure decoder if there is a change in sequence params.
*/
virtual int ReconfigureDecoder(RocdecVideoFormat *p_video_format);
protected:
/**
* @brief Callback function to be registered for getting a callback when decoding of sequence starts
*/
@@ -429,11 +467,6 @@ class RocVideoDecoder {
* @brief This function gets called when all unregistered user SEI messages are parsed for a frame
*/
int GetSEIMessage(RocdecSeiMessageInfo *p_sei_message_info);
/**
* @brief This function reconfigure decoder if there is a change in sequence params.
*/
int ReconfigureDecoder(RocdecVideoFormat *p_video_format);
/**
* @brief function to release all internal frames and clear the vp_frames_q_ (used with reconfigure): Only used with "OUT_SURFACE_MEM_DEV_INTERNAL"
@@ -495,7 +528,7 @@ class RocVideoDecoder {
uint32_t target_width_ = 0;
uint32_t target_height_ = 0;
int max_width_ = 0, max_height_ = 0;
uint32_t chroma_height_ = 0;
uint32_t chroma_height_ = 0, chroma_width_ = 0;
uint32_t num_chroma_planes_ = 0;
uint32_t num_components_ = 0;
uint32_t surface_stride_ = 0;