diff --git a/samples/videoDecode/videodecode.cpp b/samples/videoDecode/videodecode.cpp index c7b6405b30..27d8e92976 100644 --- a/samples/videoDecode/videodecode.cpp +++ b/samples/videoDecode/videodecode.cpp @@ -221,6 +221,7 @@ int main(int argc, char **argv) { std::cout << "info: decoding started, please wait!" << std::endl; int n_video_bytes = 0, n_frame_returned = 0, n_frame = 0; + int n_pic_decoded = 0, decoded_pics = 0; uint8_t *pvideo = nullptr; int pkg_flags = 0; uint8_t *pframe = nullptr; @@ -277,7 +278,7 @@ int main(int argc, char **argv) { if (n_video_bytes == 0) { pkg_flags |= ROCDEC_PKT_ENDOFSTREAM; } - n_frame_returned = viddec.DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts); + n_frame_returned = viddec.DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts, &decoded_pics); if (!n_frame && !viddec.GetOutputSurfaceInfo(&surf_info)) { std::cerr << "Error: Failed to get Output Surface Info!" << std::endl; @@ -298,6 +299,7 @@ int main(int argc, char **argv) { auto time_per_decode = std::chrono::duration(end_time - start_time).count(); total_dec_time += time_per_decode; n_frame += n_frame_returned; + n_pic_decoded += decoded_pics; if (num_decoded_frames && num_decoded_frames <= n_frame) { break; } @@ -305,10 +307,13 @@ int main(int argc, char **argv) { } while (n_video_bytes); n_frame += viddec.GetNumOfFlushedFrames(); - std::cout << "info: Total frame decoded: " << n_frame << std::endl; + std::cout << "info: Total pictures decoded: " << n_pic_decoded << std::endl; + std::cout << "info: Total frames output/displayed: " << n_frame << std::endl; if (!dump_output_frames) { - std::cout << "info: avg decoding time per frame: " << total_dec_time / n_frame << " ms" <Demux(&p_video, &n_video_bytes, &pts); - n_frame_returned = p_dec->DecodeFrame(p_video, n_video_bytes, 0, pts); + n_frame_returned = p_dec->DecodeFrame(p_video, n_video_bytes, 0, pts, &decoded_pics); n_frame += n_frame_returned; - if (num_decoded_frames && num_decoded_frames <= n_frame) { + n_pic_decoded += decoded_pics; + if (max_num_frames && max_num_frames <= n_frame) { break; } } while (n_video_bytes); @@ -58,10 +60,14 @@ void DecProc(RocVideoDecoder *p_dec, VideoDemuxer *demuxer, int *pn_frame, doubl auto session_overhead = p_dec->GetDecoderSessionOverHead(std::this_thread::get_id()); // Calculate average decoding time total_dec_time = time_per_decode - session_overhead; - double average_decoding_time = total_dec_time / n_frame; - double n_fps = 1000 / average_decoding_time; + double average_output_time = total_dec_time / n_frame; + double average_decoding_time = total_dec_time / n_pic_decoded; + double n_fps = 1000 / average_output_time; + double n_fps_dec = 1000 / average_decoding_time; *pn_fps = n_fps; + *pn_fps_dec = n_fps_dec; *pn_frame = n_frame; + *pn_pic_dec = n_pic_decoded; } void ShowHelpAndExit(const char *option = NULL) { @@ -81,7 +87,7 @@ int main(int argc, char **argv) { Rect *p_crop_rect = nullptr; OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_NOT_MAPPED; // set to decode only for performance bool b_force_zero_latency = false; - uint32_t num_decoded_frames = 0; // default value is 0, meaning decode the entire stream + uint32_t max_num_frames = 0; // max number of frames to be decoded. default value is 0, meaning decode the entire stream int disp_delay = 0; // Parse command-line arguments @@ -130,7 +136,7 @@ int main(int argc, char **argv) { if (++i == argc) { ShowHelpAndExit("-d"); } - num_decoded_frames = atoi(argv[i]); + max_num_frames = atoi(argv[i]); continue; } if (!strcmp(argv[i], "-z")) { @@ -207,12 +213,16 @@ int main(int argc, char **argv) { } float total_fps = 0; + float total_fps_dec = 0; std::vector v_thread; - std::vector v_fps; - std::vector v_frame; + std::vector v_fps, v_fps_dec; + std::vector v_frame, v_frame_dec; v_fps.resize(n_thread, 0); + v_fps_dec.resize(n_thread, 0); v_frame.resize(n_thread, 0); + v_frame_dec.resize(n_thread, 0); int n_total = 0; + int n_total_dec = 0; OutputSurfaceInfo *p_surf_info; std::string device_name; @@ -227,18 +237,23 @@ int main(int argc, char **argv) { } for (int i = 0; i < n_thread; i++) { - v_thread.push_back(std::thread(DecProc, v_viddec[i].get(), v_demuxer[i].get(), &v_frame[i], &v_fps[i], num_decoded_frames)); + v_thread.push_back(std::thread(DecProc, v_viddec[i].get(), v_demuxer[i].get(), &v_frame[i], &v_frame_dec[i], &v_fps[i], &v_fps_dec[i], max_num_frames)); } for (int i = 0; i < n_thread; i++) { v_thread[i].join(); total_fps += v_fps[i]; + total_fps_dec += v_fps_dec[i]; n_total += v_frame[i]; + n_total_dec += v_frame_dec[i]; } - std::cout << "info: Total frame decoded: " << n_total << std::endl; - std::cout << "info: avg decoding time per frame: " << 1000 / total_fps << " ms" << std::endl; - std::cout << "info: avg FPS: " << total_fps << std::endl; + std::cout << "info: Total pictures decoded: " << n_total_dec << std::endl; + std::cout << "info: Total frames output/displayed: " << n_total << std::endl; + std::cout << "info: avg decoding time per picture: " << 1000 / total_fps_dec << " ms" << std::endl; + std::cout << "info: avg decode FPS: " << total_fps_dec << std::endl; + std::cout << "info: avg output/display time per frame: " << 1000 / total_fps << " ms" << std::endl; + std::cout << "info: avg output/display FPS: " << total_fps << std::endl; } catch (const std::exception &ex) { std::cout << ex.what() << std::endl; exit(1); diff --git a/src/parser/av1_parser.cpp b/src/parser/av1_parser.cpp index 8b97e8ec71..f1c2410bf7 100644 --- a/src/parser/av1_parser.cpp +++ b/src/parser/av1_parser.cpp @@ -180,6 +180,7 @@ ParserResult Av1VideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t ERR(STR("Failed to decode!")); return ret; } + pic_count_++; dpb_buffer_.dec_ref_count[curr_pic_.pic_idx]--; memset(&tile_group_data_, 0, sizeof(Av1TileGroupDataInfo)); if ((ret = DecodeFrameWrapup()) != PARSER_OK) { @@ -576,7 +577,6 @@ ParserResult Av1VideoParser::DecodeFrameWrapup() { return ret; } } - pic_count_++; memset(&frame_header_, 0, sizeof(Av1FrameHeader)); return ret; } diff --git a/test/testScripts/run_rocDecodeSamples.py b/test/testScripts/run_rocDecodeSamples.py index 6c88e98b27..62576e52a6 100644 --- a/test/testScripts/run_rocDecodeSamples.py +++ b/test/testScripts/run_rocDecodeSamples.py @@ -140,10 +140,9 @@ if sampleMode == 0: /\tCrop : /{next} /\tResize : /{next} /^$/{next} - /info: Total frame decoded: / {totalFrames=$5; next} - /info: avg decoding time per frame: /{timePerFrame=$7; next} - /info: avg FPS: / { printf("%s, %s, %d, %d, %f, %f\n", filename, codec, bitDepth, totalFrames, timePerFrame, $4) }' rocDecode_videoDecode_results/rocDecode_output.log >> rocDecode_videoDecode_results/rocDecode_test_results.csv''' - + /info: Total pictures decoded: / {totalFrames=$5; next} + /info: avg decoding time per picture: /{timePerFrame=$7; next} + /info: avg decode FPS: / { printf("%s, %s, %d, %d, %f, %f\n", filename, codec, bitDepth, totalFrames, timePerFrame, $5) }' rocDecode_videoDecode_results/rocDecode_output.log >> rocDecode_videoDecode_results/rocDecode_test_results.csv''' os.system(runAwk_csv) elif sampleMode == 1: for current_file in iter_files(filesDirPath): @@ -172,9 +171,9 @@ elif sampleMode == 1: /\tCrop : /{next} /\tResize : /{next} /^$/{next} - /info: Total frame decoded: / {totalFrames=$5; next} - /info: avg decoding time per frame: /{timePerFrame=$7; next} - /info: avg FPS: / { printf("%s, %d, %s, %d, %d, %f, %f\n", filename, numThreads, codec, bitDepth, totalFrames, timePerFrame, $4) }' rocDecode_videoDecodePerf_results/rocDecode_output.log >> rocDecode_videoDecodePerf_results/rocDecode_test_results.csv''' + /info: Total pictures decoded: / {totalFrames=$5; next} + /info: avg decoding time per picture: /{timePerFrame=$7; next} + /info: avg decode FPS: / { printf("%s, %d, %s, %d, %d, %f, %f\n", filename, numThreads, codec, bitDepth, totalFrames, timePerFrame, $5) }' rocDecode_videoDecodePerf_results/rocDecode_output.log >> rocDecode_videoDecodePerf_results/rocDecode_test_results.csv''' sys.stdout = orig_stdout os.system(runAwk_csv) diff --git a/utils/rocvideodecode/roc_video_dec.cpp b/utils/rocvideodecode/roc_video_dec.cpp index 476e5a94ee..54b1aecba1 100644 --- a/utils/rocvideodecode/roc_video_dec.cpp +++ b/utils/rocvideodecode/roc_video_dec.cpp @@ -528,7 +528,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) { } } } - decoded_frame_cnt_ = 0; // reset frame_count + output_frame_cnt_ = 0; // reset frame_count if (is_decode_res_changed) { coded_width_ = p_video_format->coded_width; coded_height_ = p_video_format->coded_height; @@ -643,6 +643,7 @@ int RocVideoDecoder::HandlePictureDecode(RocdecPicParams *pPicParams) { } pic_num_in_dec_order_[pPicParams->curr_pic_idx] = decode_poc_++; ROCDEC_API_CALL(rocDecDecodeFrame(roc_decoder_, pPicParams)); + decoded_pic_cnt_++; if (b_force_zero_latency_ && ((!pPicParams->field_pic_flag) || (pPicParams->second_field))) { RocdecParserDispInfo disp_info; memset(&disp_info, 0, sizeof(disp_info)); @@ -714,14 +715,14 @@ int RocVideoDecoder::HandlePictureDisplay(RocdecParserDispInfo *pDispInfo) { dec_frame.picture_index = pDispInfo->picture_index; std::lock_guard lock(mtx_vp_frame_); vp_frames_q_.push(dec_frame); - decoded_frame_cnt_++; + output_frame_cnt_++; } else { // copy the decoded surface info device or host uint8_t *p_dec_frame = nullptr; { std::lock_guard lock(mtx_vp_frame_); // if not enough frames in stock, allocate - if ((unsigned)++decoded_frame_cnt_ > vp_frames_.size()) { + if ((unsigned)++output_frame_cnt_ > vp_frames_.size()) { num_alloced_frames_++; DecFrameBuffer dec_frame = { 0 }; if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) { @@ -734,7 +735,7 @@ int RocVideoDecoder::HandlePictureDisplay(RocdecParserDispInfo *pDispInfo) { dec_frame.picture_index = pDispInfo->picture_index; vp_frames_.push_back(dec_frame); } - p_dec_frame = vp_frames_[decoded_frame_cnt_ - 1].frame_ptr; + p_dec_frame = vp_frames_[output_frame_cnt_ - 1].frame_ptr; } // Copy luma data int dst_pitch = disp_width_ * byte_per_pixel_; @@ -790,7 +791,7 @@ int RocVideoDecoder::HandlePictureDisplay(RocdecParserDispInfo *pDispInfo) { if (result == ROCDEC_SUCCESS && (dec_status.decode_status == rocDecodeStatus_Error || dec_status.decode_status == rocDecodeStatus_Error_Concealed)) { std::cerr << "Decode Error occurred for picture: " << pic_num_in_dec_order_[pDispInfo->picture_index] << std::endl; } - decoded_frame_cnt_++; + output_frame_cnt_++; } return 1; @@ -832,8 +833,9 @@ int RocVideoDecoder::GetSEIMessage(RocdecSeiMessageInfo *pSEIMessageInfo) { } -int RocVideoDecoder::DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts) { - decoded_frame_cnt_ = 0, decoded_frame_cnt_ret_ = 0; +int RocVideoDecoder::DecodeFrame(const uint8_t *data, size_t size, int pkt_flags, int64_t pts, int *num_decoded_pics) { + output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0; + decoded_pic_cnt_ = 0; RocdecSourceDataPacket packet = { 0 }; packet.payload = data; packet.payload_size = size; @@ -843,21 +845,23 @@ int RocVideoDecoder::DecodeFrame(const uint8_t *data, size_t size, int pkt_flags packet.flags |= ROCDEC_PKT_ENDOFSTREAM; } ROCDEC_API_CALL(rocDecParseVideoData(rocdec_parser_, &packet)); - - return decoded_frame_cnt_; + if (num_decoded_pics) { + *num_decoded_pics = decoded_pic_cnt_; + } + return output_frame_cnt_; } uint8_t* RocVideoDecoder::GetFrame(int64_t *pts) { - if (decoded_frame_cnt_ > 0) { + if (output_frame_cnt_ > 0) { std::lock_guard lock(mtx_vp_frame_); - decoded_frame_cnt_--; + output_frame_cnt_--; if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL && !vp_frames_q_.empty()) { DecFrameBuffer *fb = &vp_frames_q_.front(); if (pts) *pts = fb->pts; return fb->frame_ptr; } else if (vp_frames_.size() > 0){ - if (pts) *pts = vp_frames_[decoded_frame_cnt_ret_].pts; - return vp_frames_[decoded_frame_cnt_ret_++].frame_ptr; + if (pts) *pts = vp_frames_[output_frame_cnt_ret_].pts; + return vp_frames_[output_frame_cnt_ret_++].frame_ptr; } } return nullptr; diff --git a/utils/rocvideodecode/roc_video_dec.h b/utils/rocvideodecode/roc_video_dec.h index 63d74648c3..797c245583 100644 --- a/utils/rocvideodecode/roc_video_dec.h +++ b/utils/rocvideodecode/roc_video_dec.h @@ -282,9 +282,10 @@ class RocVideoDecoder { * @param size - size of the data buffer in bytes * @param pts - presentation timestamp * @param flags - video packet flags + * @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 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 * @@ -475,7 +476,8 @@ class RocVideoDecoder { 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 output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0; + int decoded_pic_cnt_ = 0; int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM]; int num_alloced_frames_ = 0; std::ostringstream input_video_info_str_;