diff --git a/include/decord/video_interface.h b/include/decord/video_interface.h index 55516fed..90e7019e 100644 --- a/include/decord/video_interface.h +++ b/include/decord/video_interface.h @@ -89,7 +89,7 @@ class VideoReaderInterface { DECORD_DLL VideoReaderPtr GetVideoReader(std::string fname, DLContext ctx, int width=-1, int height=-1, int nb_thread=0, - int io_type=kNormal); + int io_type=kNormal, std::string fault_tol="-1"); /** * \brief Interface of VideoLoader, pure virtual class diff --git a/src/video/nvcodec/cuda_decoder_impl.cc b/src/video/nvcodec/cuda_decoder_impl.cc index 69c53856..08d2aebe 100644 --- a/src/video/nvcodec/cuda_decoder_impl.cc +++ b/src/video/nvcodec/cuda_decoder_impl.cc @@ -96,15 +96,20 @@ CUVideoDecoderImpl& CUVideoDecoderImpl::operator=(CUVideoDecoderImpl&& other) { int CUVideoDecoderImpl::Initialize(CUVIDEOFORMAT* format) { if (initialized_) { - if ((format->codec != decoder_info_.CodecType) || - (format->coded_width != decoder_info_.ulWidth) || - (format->coded_height != decoder_info_.ulHeight) || - (format->chroma_format != decoder_info_.ChromaFormat)) { - std::cerr << "Encountered a dynamic video format change.\n"; - return 0; + if ((format->codec == decoder_info_.CodecType) && + (format->coded_width == decoder_info_.ulWidth) && + (format->coded_height == decoder_info_.ulHeight) && + (format->chroma_format == decoder_info_.ChromaFormat)) + { + return 1; + } + else //When the video format changes, reinitialize the decoder and continue to decode + { + CHECK_CUDA_CALL(cuvidDestroyDecoder(decoder_)); + std::cerr << "Encountered a dynamic video format change.\n"; + std::cerr << "Reinitialize the decoder\n"; + } } - return 1; - } // DLOG(INFO) << "Hardware Decoder Input Information" << std::endl diff --git a/src/video/video_reader.cc b/src/video/video_reader.cc index af4858d2..4cd3a42c 100644 --- a/src/video/video_reader.cc +++ b/src/video/video_reader.cc @@ -263,10 +263,14 @@ int64_t VideoReader::GetFrameCount() const { int64_t cnt = fmt_ctx_->streams[actv_stm_idx_]->nb_frames; if (cnt < 1) { AVStream *stm = fmt_ctx_->streams[actv_stm_idx_]; - // many formats do not provide accurate frame count, use duration and FPS to approximate - cnt = static_cast(stm->avg_frame_rate.num) / stm->avg_frame_rate.den * fmt_ctx_->duration / AV_TIME_BASE; + if(stm->avg_frame_rate.den == 0) //Reset the total frame count to 0 + cnt = 0; + else + // many formats do not provide accurate frame count, use duration and FPS to approximate + cnt = static_cast(stm->avg_frame_rate.num) / stm->avg_frame_rate.den * fmt_ctx_->duration / AV_TIME_BASE; } if (cnt < 1) { + cnt = 0; LOG(FATAL) << "[" << filename_ << "] Failed to measure duration/frame-count due to broken metadata."; } return cnt; @@ -597,10 +601,15 @@ bool VideoReader::CheckKeyFrame() decoder_->Start(); bool ret = false; int64_t cf = curr_frame_; + int i = 0; while (!ret) { PushNext(); ret = decoder_->Pop(&frame); + i++; + if(i > 60){ // This is going to loop indefinitely when parse some corrupted video + break; + } } if (eof_ && frame.pts == -1){