Added real decode speed report to set it apart from the current output speed report in sample apps (#409)
* * rocDecode: Added real decode speed report.
- The current decode speed report is actually output/display speed report.
- Due to AV1's extensive use of alternate reference frames that are not display, AV1 decoded frame count and output/displayed frame count can be quite different, making the current speed report not an accurate decode speed measurement.
- We now added the actual decode speed report, besides the existing speed report, now called output/display FPS.
* * rocDecode: Added real decode speed report.
- The current decode speed report is actually output/display speed report.
- Due to AV1's extensive use of alternate reference frames that are not display, AV1 decoded frame count and output/displayed frame count can be quite different, making the current speed report not an accurate decode speed measurement.
- We now added the actual decode speed report, besides the existing speed report, now called output/display FPS.
* * rocDecode/Sample script: Added missing changes for sample_mode 0 case.
[ROCm/rocdecode commit: 6253248188]
This commit is contained in:
@@ -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<double, std::milli>(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" <<std::endl;
|
||||
std::cout << "info: avg FPS: " << (n_frame / total_dec_time) * 1000 << std::endl;
|
||||
std::cout << "info: avg decoding time per picture: " << total_dec_time / n_pic_decoded << " ms" <<std::endl;
|
||||
std::cout << "info: avg decode FPS: " << (n_pic_decoded / total_dec_time) * 1000 << std::endl;
|
||||
std::cout << "info: avg output/display time per frame: " << total_dec_time / n_frame << " ms" <<std::endl;
|
||||
std::cout << "info: avg output/display FPS: " << (n_frame / total_dec_time) * 1000 << std::endl;
|
||||
} else {
|
||||
if (mem_type == OUT_SURFACE_MEM_NOT_MAPPED) {
|
||||
std::cout << "info: saving frames with -m 3 option is not supported!" << std::endl;
|
||||
|
||||
@@ -37,8 +37,9 @@ THE SOFTWARE.
|
||||
#include "roc_video_dec.h"
|
||||
#include "common.h"
|
||||
|
||||
void DecProc(RocVideoDecoder *p_dec, VideoDemuxer *demuxer, int *pn_frame, double *pn_fps, int num_decoded_frames) {
|
||||
void DecProc(RocVideoDecoder *p_dec, VideoDemuxer *demuxer, int *pn_frame, int *pn_pic_dec, double *pn_fps, double *pn_fps_dec, int max_num_frames) {
|
||||
int n_video_bytes = 0, n_frame_returned = 0, n_frame = 0;
|
||||
int n_pic_decoded = 0, decoded_pics = 0;
|
||||
uint8_t *p_video = nullptr;
|
||||
int64_t pts = 0;
|
||||
double total_dec_time = 0.0;
|
||||
@@ -46,9 +47,10 @@ void DecProc(RocVideoDecoder *p_dec, VideoDemuxer *demuxer, int *pn_frame, doubl
|
||||
|
||||
do {
|
||||
demuxer->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<std::thread> v_thread;
|
||||
std::vector<double> v_fps;
|
||||
std::vector<int> v_frame;
|
||||
std::vector<double> v_fps, v_fps_dec;
|
||||
std::vector<int> 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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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<std::mutex> 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<std::mutex> 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<std::mutex> 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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user