From 55ebf353cceed99e4e9298b504fc207964a91840 Mon Sep 17 00:00:00 2001 From: Rajy Rawther Date: Fri, 10 Nov 2023 12:44:40 -0800 Subject: [PATCH] fix exception handling to gracefully exit (#49) * fix exception handling to gracefully exit * addressed review comments --- samples/videoDecode/videodecode.cpp | 119 +++++++++++++------------ utils/rocvideodecode/roc_video_dec.cpp | 13 ++- utils/rocvideodecode/roc_video_dec.h | 14 +-- 3 files changed, 77 insertions(+), 69 deletions(-) diff --git a/samples/videoDecode/videodecode.cpp b/samples/videoDecode/videodecode.cpp index 11f41988c1..79118e1e5b 100644 --- a/samples/videoDecode/videodecode.cpp +++ b/samples/videoDecode/videodecode.cpp @@ -97,67 +97,72 @@ int main(int argc, char **argv) { } ShowHelpAndExit(argv[i]); } - VideoDemuxer demuxer(inputFilePath.c_str()); - rocDecVideoCodec rocdec_codec_id = AVCodec2RocDecVideoCodec(demuxer.GetCodecID()); - RocVideoDecoder viddec(deviceId, mem_type, rocdec_codec_id, false, true, p_crop_rect); + try { + VideoDemuxer demuxer(inputFilePath.c_str()); + rocDecVideoCodec rocdec_codec_id = AVCodec2RocDecVideoCodec(demuxer.GetCodecID()); + RocVideoDecoder viddec(deviceId, mem_type, rocdec_codec_id, false, true, p_crop_rect); - std::string deviceName, gcnArchName, drmNode; - int pciBusID, pciDomainID, pciDeviceID; + std::string deviceName, gcnArchName, drmNode; + int pciBusID, pciDomainID, pciDeviceID; - viddec.GetDeviceinfo(deviceName, gcnArchName, pciBusID, pciDomainID, pciDeviceID); - std::cout << "info: Using GPU device " << deviceId << " - " << deviceName << "[" << gcnArchName << "] on PCI bus " << - std::setfill('0') << std::setw(2) << std::right << std::hex << pciBusID << ":" << std::setfill('0') << std::setw(2) << - std::right << std::hex << pciDomainID << "." << pciDeviceID << std::dec << std::endl; - std::cout << "info: decoding started, please wait!" << std::endl; + viddec.GetDeviceinfo(deviceName, gcnArchName, pciBusID, pciDomainID, pciDeviceID); + std::cout << "info: Using GPU device " << deviceId << " - " << deviceName << "[" << gcnArchName << "] on PCI bus " << + std::setfill('0') << std::setw(2) << std::right << std::hex << pciBusID << ":" << std::setfill('0') << std::setw(2) << + std::right << std::hex << pciDomainID << "." << pciDeviceID << std::dec << std::endl; + std::cout << "info: decoding started, please wait!" << std::endl; - int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0; - uint8_t *pVideo = nullptr; - uint8_t *pFrame = nullptr; - int64_t pts = 0; - OutputSurfaceInfo *pSurfInfo; - bool bDecodeOutSemiPlanar = false; - uint32_t width, height; - double totalDecTime = 0; - - do { - auto startTime = std::chrono::high_resolution_clock::now(); - demuxer.Demux(&pVideo, &nVideoBytes, &pts); - nFrameReturned = viddec.DecodeFrame(pVideo, nVideoBytes, 0, pts); - auto endTime = std::chrono::high_resolution_clock::now(); - auto timePerFrame = std::chrono::duration(endTime - startTime).count(); - totalDecTime += timePerFrame; - if (!nFrame && !viddec.GetOutputSurfaceInfo(&pSurfInfo)) { - std::cerr << "Error: Failed to get Output Surface Info!" << std::endl; - break; - } - - if (dumpOutputFrames) { - for (int i = 0; i < nFrameReturned; i++) { - pFrame = viddec.GetFrame(&pts); - viddec.SaveSurfToFile(outputFilePath, pFrame, pSurfInfo); - // release frame - viddec.ReleaseFrame(pts); - } - } - nFrame += nFrameReturned; - } while (nVideoBytes); -#if 0 // is flushing required? - // Flush last frames from the decoder if any - do { - // send null packet to decoder to flush out - pVideo = nullptr; nVideoBytes = 0; + int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0; + uint8_t *pVideo = nullptr; + uint8_t *pFrame = nullptr; int64_t pts = 0; - //nFrameReturned = viddec.decode(pVideo, nVideoBytes, pts); - } while (nFrameReturned); -#endif - std::cout << "info: Video codec format: " << viddec.GetCodecFmtName(viddec.GetCodecId()) << std::endl; - std::cout << "info: Video size: [ " << pSurfInfo->output_width << ", " << pSurfInfo->output_height << " ]" << std::endl; - std::cout << "info: Video surface format: " << viddec.GetSurfaceFmtName(pSurfInfo->surface_format) << std::endl; - std::cout << "info: Video Bit depth: " << pSurfInfo->bit_depth << std::endl; - std::cout << "info: Total frame decoded: " << nFrame << std::endl; - if (!dumpOutputFrames) { - std::cout << "info: avg decoding time per frame (ms): " << totalDecTime / nFrame << std::endl; - std::cout << "info: avg FPS: " << (nFrame / totalDecTime) * 1000 << std::endl; + OutputSurfaceInfo *pSurfInfo; + bool bDecodeOutSemiPlanar = false; + uint32_t width, height; + double totalDecTime = 0; + + do { + auto startTime = std::chrono::high_resolution_clock::now(); + demuxer.Demux(&pVideo, &nVideoBytes, &pts); + nFrameReturned = viddec.DecodeFrame(pVideo, nVideoBytes, 0, pts); + auto endTime = std::chrono::high_resolution_clock::now(); + auto timePerFrame = std::chrono::duration(endTime - startTime).count(); + totalDecTime += timePerFrame; + if (!nFrame && !viddec.GetOutputSurfaceInfo(&pSurfInfo)) { + std::cerr << "Error: Failed to get Output Surface Info!" << std::endl; + break; + } + + if (dumpOutputFrames) { + for (int i = 0; i < nFrameReturned; i++) { + pFrame = viddec.GetFrame(&pts); + viddec.SaveSurfToFile(outputFilePath, pFrame, pSurfInfo); + // release frame + viddec.ReleaseFrame(pts); + } + } + nFrame += nFrameReturned; + } while (nVideoBytes); + #if 0 // is flushing required? + // Flush last frames from the decoder if any + do { + // send null packet to decoder to flush out + pVideo = nullptr; nVideoBytes = 0; + int64_t pts = 0; + //nFrameReturned = viddec.decode(pVideo, nVideoBytes, pts); + } while (nFrameReturned); + #endif + std::cout << "info: Video codec format: " << viddec.GetCodecFmtName(viddec.GetCodecId()) << std::endl; + std::cout << "info: Video size: [ " << pSurfInfo->output_width << ", " << pSurfInfo->output_height << " ]" << std::endl; + std::cout << "info: Video surface format: " << viddec.GetSurfaceFmtName(pSurfInfo->surface_format) << std::endl; + std::cout << "info: Video Bit depth: " << pSurfInfo->bit_depth << std::endl; + std::cout << "info: Total frame decoded: " << nFrame << std::endl; + if (!dumpOutputFrames) { + std::cout << "info: avg decoding time per frame (ms): " << totalDecTime / nFrame << std::endl; + std::cout << "info: avg FPS: " << (nFrame / totalDecTime) * 1000 << std::endl; + } + }catch (const std::exception &ex) { + std::cout << ex.what() << std::endl; + exit(1); } return 0; diff --git a/utils/rocvideodecode/roc_video_dec.cpp b/utils/rocvideodecode/roc_video_dec.cpp index 8bfe24f3ca..ee62592390 100644 --- a/utils/rocvideodecode/roc_video_dec.cpp +++ b/utils/rocvideodecode/roc_video_dec.cpp @@ -254,7 +254,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *pVideoFormat) { ROCDEC_API_CALL(rocDecGetDecoderCaps(&decode_caps)); if(!decode_caps.bIsSupported){ - THROW("Rocdec:: Codec not supported on this GPU: " + TOSTR(ROCDEC_NOT_SUPPORTED)); + ROCDEC_THROW("Rocdec:: Codec not supported on this GPU: ", ROCDEC_NOT_SUPPORTED); return 0; } @@ -268,8 +268,8 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *pVideoFormat) { << "Resolution not supported on this GPU "; const std::string cErr = errorString.str(); - THROW(cErr+ TOSTR(ROCDEC_NOT_SUPPORTED)); - return nDecodeSurface; + ROCDEC_THROW(cErr, ROCDEC_NOT_SUPPORTED); + return 0; } if (width_ && height_ && chroma_height_) { @@ -304,7 +304,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *pVideoFormat) { else if (decode_caps.nOutputFormatMask & (1 << rocDecVideoSurfaceFormat_YUV444_16Bit)) video_surface_format_ = rocDecVideoSurfaceFormat_YUV444_16Bit; else - THROW("No supported output format found" + TOSTR(ROCDEC_NOT_SUPPORTED)); + ROCDEC_THROW("No supported output format found", ROCDEC_NOT_SUPPORTED); } video_format_ = *pVideoFormat; @@ -394,7 +394,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *pVideoFormat) { int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *pVideoFormat) { - THROW("ReconfigureDecoder is not supported in this version: " + TOSTR(ROCDEC_NOT_SUPPORTED)); + ROCDEC_THROW("ReconfigureDecoder is not supported in this version: ", ROCDEC_NOT_SUPPORTED); return ROCDEC_NOT_SUPPORTED; } @@ -407,8 +407,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *pVideoFormat) { int RocVideoDecoder::HandlePictureDecode(RocdecPicParams *pPicParams) { if (!roc_decoder_) { - THROW("Decoder not initialized: failed with ErrCode: " + TOSTR(ROCDEC_NOT_INITIALIZED)); - return false; + THROW("RocDecoder not initialized: failed with ErrCode: " + TOSTR(ROCDEC_NOT_INITIALIZED)); } pic_num_in_dec_order_[pPicParams->CurrPicIdx] = decode_poc_++; ROCDEC_API_CALL(rocDecDecodeFrame(roc_decoder_, pPicParams)); diff --git a/utils/rocvideodecode/roc_video_dec.h b/utils/rocvideodecode/roc_video_dec.h index adfa9f5d6f..6281a568e3 100644 --- a/utils/rocvideodecode/roc_video_dec.h +++ b/utils/rocvideodecode/roc_video_dec.h @@ -64,23 +64,27 @@ typedef enum { class rocVideoDecodeException : public std::exception { public: - explicit rocVideoDecodeException(const std::string& message):_message(message){} + explicit rocVideoDecodeException(const std::string& message, const int errCode):_message(message), _err_code(errCode) {} + explicit rocVideoDecodeException(const std::string& message):_message(message), _err_code(-1) {} virtual const char* what() const throw() override { return _message.c_str(); } + int getErrorCode() const { return _err_code; } private: std::string _message; + int _err_code; }; -#define THROW(X) throw rocVideoDecodeException(" { "+std::string(__func__)+" } " + X); +#define ROCDEC_THROW(X, CODE) throw rocVideoDecodeException(" { " + std::string(__func__) + " } " + X , CODE); +#define THROW(X) throw rocVideoDecodeException(" { " + std::string(__func__) + " } " + X); #define ROCDEC_API_CALL( rocDecAPI ) \ do { \ rocDecStatus errorCode = rocDecAPI; \ if( errorCode != ROCDEC_SUCCESS) { \ std::ostringstream errorLog; \ - errorLog << #rocDecAPI << " returned error " << errorCode; \ - THROW(errorLog.str() + TOSTR(errorCode)); \ + errorLog << #rocDecAPI << " returned err " << errorCode << " at " <<__FILE__ <<":" << __LINE__; \ + ROCDEC_THROW(errorLog.str(), errorCode); \ } \ } while (0) @@ -92,7 +96,7 @@ private: szErrName = hipGetErrorName(hip_status); \ std::ostringstream errorLog; \ errorLog << "hip API error " << szErrName ; \ - THROW(errorLog.str()); \ + ROCDEC_THROW(errorLog.str(), hip_status); \ } \ } \ while (0)