VideoToSequence sample (#373)

* videoToSequence sample initial commit

* add frame_num calculation when seeking

* update README

* addressed review comments

* added FlushAndReconfigure() to flush out frames with seek
This commit is contained in:
Rajy Rawther
2024-07-22 05:42:58 -07:00
committed by GitHub
parent ac82d17e9f
commit fe5f63428c
5 changed files with 696 additions and 6 deletions
+40 -5
View File
@@ -73,6 +73,11 @@ RocVideoDecoder::~RocVideoDecoder() {
roc_decoder_ = nullptr;
}
if (curr_video_format_ptr_) {
delete curr_video_format_ptr_;
curr_video_format_ptr_ = nullptr;
}
std::lock_guard<std::mutex> lock(mtx_vp_frame_);
if (out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL) {
for (auto &p_frame : vp_frames_) {
@@ -250,6 +255,11 @@ static void GetSurfaceStrideInternal(rocDecVideoSurfaceFormat surface_format, ui
* 0: fail, 1: succeeded, > 1: override dpb size of parser (set by CUVIDPARSERPARAMS::max_num_decode_surfaces while creating parser)
*/
int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
if (p_video_format == nullptr) {
ROCDEC_THROW("Rocdec:: Invalid video format in HandleVideoSequence: ", ROCDEC_INVALID_PARAMETER);
return 0;
}
auto start_time = StartTimer();
input_video_info_str_.str("");
input_video_info_str_.clear();
@@ -280,7 +290,6 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
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
@@ -291,12 +300,16 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
ROCDEC_THROW(cErr, ROCDEC_NOT_SUPPORTED);
return 0;
}
if (curr_video_format_ptr_ == nullptr) {
curr_video_format_ptr_ = new RocdecVideoFormat();
}
// store current video format: this is required to call reconfigure from application in case of random seek
if (curr_video_format_ptr_) memcpy(curr_video_format_ptr_, p_video_format, sizeof(RocdecVideoFormat));
if (coded_width_ && coded_height_) {
// rocdecCreateDecoder() has been called before, and now there's possible config change
return ReconfigureDecoder(p_video_format);
}
// e_codec has been set in the constructor (for parser). Here it's set again for potential correction
codec_id_ = p_video_format->codec;
video_chroma_format_ = p_video_format->chroma_format;
@@ -431,17 +444,38 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
* @return true : success
* @return false : fail
*/
bool RocVideoDecoder::SetReconfigParams(ReconfigParams *p_reconfig_params) {
bool RocVideoDecoder::SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush) {
if (!p_reconfig_params) {
std::cerr << "ERROR: Invalid reconfig struct passed! "<< std::endl;
return false;
}
//save it
p_reconfig_params_ = p_reconfig_params;
b_force_recofig_flush_ = b_force_reconfig_flush;
return true;
}
/**
* @brief Function to force Reconfigure Flush: needed for random seeking to key frames
*
* @return int 1: Success 0: Fail
*/
int RocVideoDecoder::FlushAndReconfigure() {
if (!p_reconfig_params_) {
std::cerr << "ERROR: Reconfig params is not set! "<< std::endl;
return 0;
}
if (!curr_video_format_ptr_ ) {
std::cerr << "ERROR: video format is not initialized! "<< std::endl;
return 0;
}
//call reconfigure
b_force_recofig_flush_ = true; // if not already set to force reconfigure
ReconfigureDecoder(curr_video_format_ptr_);
return true;
}
/**
* @brief function to reconfigure decoder if there is a change in sequence params.
*
@@ -466,7 +500,8 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
p_video_format->display_area.top == disp_rect_.top &&
p_video_format->display_area.left == disp_rect_.left &&
p_video_format->display_area.right == disp_rect_.right);
if (!is_decode_res_changed && !is_display_rect_changed) {
if (!is_decode_res_changed && !is_display_rect_changed && !b_force_recofig_flush_) {
return 1;
}
@@ -932,7 +967,7 @@ void RocVideoDecoder::SaveFrameToFile(std::string output_file_name, void *surf_m
}
}
is_decoder_reconfigured_ = false;
}
}
if (fp_out_ == nullptr) {
fp_out_ = fopen(output_file_name.c_str(), "wb");
+10 -1
View File
@@ -267,7 +267,14 @@ class RocVideoDecoder {
* @return true : success
* @return false : fail
*/
bool SetReconfigParams(ReconfigParams *p_reconfig_params);
bool SetReconfigParams(ReconfigParams *p_reconfig_params, bool b_force_reconfig_flush = false);
/**
* @brief Function to force Reconfigure Flush: needed for random seeking to key frames
*
* @return int 1: Success 0: Fail
*/
int FlushAndReconfigure();
/**
* @brief this function decodes a frame and returns the number of frames avalable for display
*
@@ -451,6 +458,7 @@ class RocVideoDecoder {
bool b_force_zero_latency_ = false;
uint32_t disp_delay_;
ReconfigParams *p_reconfig_params_ = nullptr;
bool b_force_recofig_flush_ = false;
int32_t num_frames_flushed_during_reconfig_ = 0;
hipDeviceProp_t hip_dev_prop_;
hipStream_t hip_stream_;
@@ -459,6 +467,7 @@ class RocVideoDecoder {
rocDecVideoSurfaceFormat video_surface_format_ = rocDecVideoSurfaceFormat_NV12;
RocdecSeiMessageInfo *curr_sei_message_ptr_ = nullptr;
RocdecSeiMessageInfo sei_message_display_q_[MAX_FRAME_NUM];
RocdecVideoFormat *curr_video_format_ptr_ = nullptr;
int decoded_frame_cnt_ = 0, decoded_frame_cnt_ret_ = 0;
int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM];
int num_alloced_frames_ = 0;