Skip to content
Snippets Groups Projects
Commit dcde170a authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Decoder no longer uses definition field

parent 4219be8a
No related branches found
No related tags found
1 merge request!311Resolves #296 removal of NvPipe
...@@ -66,18 +66,15 @@ bool NvidiaDecoder::_create(const ftl::codecs::Packet &pkt) { ...@@ -66,18 +66,15 @@ bool NvidiaDecoder::_create(const ftl::codecs::Packet &pkt) {
bool is_float_frame = pkt.flags & ftl::codecs::kFlagFloat; bool is_float_frame = pkt.flags & ftl::codecs::kFlagFloat;
// Check existing decoder is valid first and remove if not // Check existing decoder is valid first and remove if not
if (nv_decoder_ != nullptr && (last_definition_ != pkt.definition || if (nv_decoder_ != nullptr && (last_codec_ != pkt.codec || is_float_channel_ != is_float_frame)) {
last_codec_ != pkt.codec || is_float_channel_ != is_float_frame || //width_ != last_width_ || height_ != last_height_)) {
width_ != last_width_ || height_ != last_height_)) {
delete nv_decoder_; delete nv_decoder_;
nv_decoder_ = nullptr; nv_decoder_ = nullptr;
} }
if (!nv_decoder_) { if (!nv_decoder_) {
// Ensure we have a CUDA context // Ensure we have a CUDA context
LOG(INFO) << "Getting cuda context...";
cudaSafeCall(cudaDeviceSynchronize()); cudaSafeCall(cudaDeviceSynchronize());
LOG(INFO) << "Have cuda context.";
CUcontext cudaContext; CUcontext cudaContext;
cuCtxGetCurrent(&cudaContext); cuCtxGetCurrent(&cudaContext);
...@@ -124,11 +121,6 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out ...@@ -124,11 +121,6 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
bool islossless = ((pkt.codec == ftl::codecs::codec_t::HEVC || pkt.codec == ftl::codecs::codec_t::H264) && is_float_frame && bool islossless = ((pkt.codec == ftl::codecs::codec_t::HEVC || pkt.codec == ftl::codecs::codec_t::H264) && is_float_frame &&
!(pkt.flags & 0x2)) || pkt.codec == ftl::codecs::codec_t::HEVC_LOSSLESS || pkt.codec == ftl::codecs::codec_t::H264_LOSSLESS; !(pkt.flags & 0x2)) || pkt.codec == ftl::codecs::codec_t::HEVC_LOSSLESS || pkt.codec == ftl::codecs::codec_t::H264_LOSSLESS;
/*if (is_float_frame && !islossless && out.type() != CV_16UC4) {
LOG(ERROR) << "Invalid buffer for lossy float frame";
return false;
}*/
if (is_float_frame && out.type() != CV_32F) { if (is_float_frame && out.type() != CV_32F) {
LOG(ERROR) << "Invalid buffer for float frame"; LOG(ERROR) << "Invalid buffer for float frame";
return false; return false;
...@@ -139,51 +131,10 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out ...@@ -139,51 +131,10 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
return false; return false;
} }
int width = ftl::codecs::getWidth(pkt.definition);
int height = ftl::codecs::getHeight(pkt.definition);
auto [tx,ty] = ftl::codecs::chooseTileConfig(pkt.frame_count);
//int exp_height = (is_float_frame && !islossless) ? ty*height+((ty*height)/2) : ty*height;
if (tx*width != out.cols || ty*height != out.rows) {
LOG(ERROR) << "Received frame whose size does not match buffer";
return false;
}
// Is the previous decoder still valid for current resolution and type?
//if (nv_decoder_ != nullptr && (last_definition_ != pkt.definition || last_codec_ != pkt.codec || is_float_channel_ != is_float_frame)) {
// NvPipe_Destroy(nv_decoder_);
// nv_decoder_ = nullptr;
//}
// Create an appropriate NvDecoder instance
width_ = tx*width;
height_ = ty*height;
//if (islossless && is_float_frame) width_ *= 2; // 16bit = double width 8 bit
_create(pkt); _create(pkt);
is_float_channel_ = is_float_frame; is_float_channel_ = is_float_frame;
last_definition_ = pkt.definition;
last_codec_ = pkt.codec; last_codec_ = pkt.codec;
last_width_ = width_;
last_height_ = height_;
// Build a decoder instance of the correct kind
/*if (nv_decoder_ == nullptr) {
nv_decoder_ = NvPipe_CreateDecoder(
(is_float_frame) ? (islossless) ? NVPIPE_UINT16 : NVPIPE_NV12_10bit : NVPIPE_RGBA32,
(pkt.codec == codec_t::HEVC || pkt.codec == ftl::codecs::codec_t::HEVC_LOSSLESS) ? NVPIPE_HEVC : NVPIPE_H264,
out.cols,
out.rows);
if (!nv_decoder_) {
//LOG(INFO) << "Bitrate=" << (int)bitrate << " width=" << ABRController::getColourWidth(bitrate);
LOG(FATAL) << "Could not create decoder: " << NvPipe_GetError(NULL);
}
seen_iframe_ = false;
}*/
//tmp_.create(cv::Size(ftl::codecs::getWidth(pkt.definition),ftl::codecs::getHeight(pkt.definition)), (!is_float_frame) ? CV_8UC4 : (islossless) ? CV_16U : CV_16UC4);
// Final checks for validity // Final checks for validity
if (pkt.data.size() == 0) { // || !ftl::codecs::hevc::validNAL(pkt.data)) { if (pkt.data.size() == 0) { // || !ftl::codecs::hevc::validNAL(pkt.data)) {
...@@ -212,21 +163,22 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out ...@@ -212,21 +163,22 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
} }
decodedPtr = _decode(ptr, size); decodedPtr = _decode(ptr, size);
//rc = NvPipe_Decode(nv_decoder_, ptr, size, out.data, tx*width, ty*height, out.step);
//if (rc == 0) LOG(ERROR) << "NvPipe decode error: " << NvPipe_GetError(nv_decoder_);
ptr += size; ptr += size;
} }
//LOG(WARNING) << "Decode of multiple frames: " << count;
} else { } else {
if (!_checkIFrame(pkt.codec, pkt.data.data(), pkt.data.size())) { if (!_checkIFrame(pkt.codec, pkt.data.data(), pkt.data.size())) {
LOG(WARNING) << "P-Frame without I-Frame in decoder: " << pkt.data.size(); LOG(WARNING) << "P-Frame without I-Frame in decoder: " << pkt.data.size();
return false; return false;
} }
decodedPtr = _decode(pkt.data.data(), pkt.data.size()); decodedPtr = _decode(pkt.data.data(), pkt.data.size());
//LOG(INFO) << "Decoded size = " << nv_decoder_->GetWidth() << "x" << nv_decoder_->GetHeight() << " - " << nv_decoder_->GetBPP(); }
//rc = NvPipe_Decode(nv_decoder_, pkt.data.data(), pkt.data.size(), out.data, tx*width, ty*height, out.step);
//if (rc == 0) LOG(ERROR) << "NvPipe decode error: " << NvPipe_GetError(nv_decoder_); width_ = nv_decoder_->GetWidth();
height_ = nv_decoder_->GetHeight();
if (out.cols != ((is_float_frame && islossless) ? width_/2 : width_) || out.rows != height_) {
LOG(ERROR) << "Decoded frame not same size as buffer";
return false;
} }
// OpenCV GpuMat for YCbCr 4:2:0 // OpenCV GpuMat for YCbCr 4:2:0
...@@ -241,21 +193,16 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out ...@@ -241,21 +193,16 @@ bool NvidiaDecoder::decode(const ftl::codecs::Packet &pkt, cv::cuda::GpuMat &out
if (!islossless) { if (!islossless) {
cv::cuda::GpuMat sroi = surface(cv::Rect(0,0,width_, height_)); cv::cuda::GpuMat sroi = surface(cv::Rect(0,0,width_, height_));
cv::cuda::GpuMat csroi = surface(cv::Rect(0,height_,width_, height_/2)); cv::cuda::GpuMat csroi = surface(cv::Rect(0,height_,width_, height_/2));
//cv::cuda::cvtColor(tmp_, tmp_, cv::COLOR_RGB2YUV, 4, stream_);
//LOG(INFO) << "Depth convert: " << out.cols << ", " << out.rows << ", " << out.type();
//ftl::cuda::vuya_to_depth(out, tmp_, 16.0f, stream_);
ftl::cuda::vuya_to_depth(out, sroi, csroi, 16.0f, cvstream); ftl::cuda::vuya_to_depth(out, sroi, csroi, 16.0f, cvstream);
} else { } else {
//tmp_.convertTo(out, CV_32FC1, 1.0f/1000.0f, stream_);
ftl::cuda::nv12_to_float(decodedPtr, width_*2, (float*)out.data, out.step1(), width_, height_, stream_); ftl::cuda::nv12_to_float(decodedPtr, width_*2, (float*)out.data, out.step1(), width_, height_, stream_);
} }
} else { } else {
// Flag 0x1 means frame is in RGB so needs conversion to BGR // Flag 0x1 means frame is in RGB so needs conversion to BGR
if (pkt.flags & 0x1) { if (pkt.flags & 0x1) {
//cv::cuda::cvtColor(surface, out, cv::COLOR_YUV2BGRA_NV12, 0, cvstream);
Nv12ToColor32<BGRA32>(decodedPtr, width_, out.data, out.step1(), width_, height_, 0, stream_); Nv12ToColor32<BGRA32>(decodedPtr, width_, out.data, out.step1(), width_, height_, 0, stream_);
} else { } else {
//cv::cuda::cvtColor(surface, out, cv::COLOR_YUV2RGBA_NV12, 0, cvstream);
Nv12ToColor32<RGBA32>(decodedPtr, width_, out.data, out.step1(), width_, height_, 0, stream_); Nv12ToColor32<RGBA32>(decodedPtr, width_, out.data, out.step1(), width_, height_, 0, stream_);
} }
} }
......
...@@ -371,6 +371,24 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) { ...@@ -371,6 +371,24 @@ TEST_CASE( "NvidiaDecoder::decode() - corrupted packet" ) {
pkt.definition = definition_t::HD1080; pkt.definition = definition_t::HD1080;
REQUIRE( r );
REQUIRE( decoder.decode(pkt, out) );
}
SECTION("Bad output size") {
in = cv::cuda::GpuMat(cv::Size(2560,720), CV_8UC4, cv::Scalar(255,0,0,0));
out = cv::cuda::GpuMat(cv::Size(2500,720), CV_8UC4, cv::Scalar(0,0,0,0));
ftl::codecs::Packet pkt;
pkt.codec = codec_t::Any;
pkt.bitrate = 255;
pkt.definition = definition_t::Any;
pkt.frame_count = 2;
pkt.flags = 0;
bool r = encoder.encode(in, pkt);
pkt.definition = definition_t::HD1080;
REQUIRE( r ); REQUIRE( r );
REQUIRE( !decoder.decode(pkt, out) ); REQUIRE( !decoder.decode(pkt, out) );
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment