diff options
Diffstat (limited to 'src/video_core/host1x/codecs/decoder.cpp')
| -rw-r--r-- | src/video_core/host1x/codecs/decoder.cpp | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/src/video_core/host1x/codecs/decoder.cpp b/src/video_core/host1x/codecs/decoder.cpp index c75059db6f..1d6d3e8af6 100644 --- a/src/video_core/host1x/codecs/decoder.cpp +++ b/src/video_core/host1x/codecs/decoder.cpp @@ -20,58 +20,54 @@ Decoder::Decoder(Host1x::Host1x& host1x_, s32 id_, const Host1x::NvdecCommon::Nv Decoder::~Decoder() = default; -void Decoder::Decode() { - if (!initialized) { +void Decoder::SetFrameDimensions(s32 width, s32 height) { + if (width <= 0 || height <= 0) { + frame_dimensions.reset(); return; } + frame_dimensions = FFmpeg::FrameDimensions{width, height}; +} - const auto packet_data = ComposeFrame(); - // Send assembled bitstream to decoder. - if (!decode_api.SendPacket(packet_data)) { +void Decoder::Decode() { + if (!initialized) { return; } - // Only receive/store visible frames. - if (vp9_hidden_frame) { - return; + const auto packet_data = ComposeFrame(); + FFmpeg::FrameOffsets offsets{}; + offsets.hidden = vp9_hidden_frame; + offsets.interlaced = IsInterlaced(); + if (offsets.interlaced) { + std::tie(offsets.luma, offsets.luma_bottom, std::ignore, std::ignore) = + GetInterlacedOffsets(); + } else { + std::tie(offsets.luma, std::ignore) = GetProgressiveOffsets(); } - // Receive output frames from decoder. - auto frame = decode_api.ReceiveFrame(); - - if (!frame) { + // Send assembled bitstream to decoder. + if (!decode_api.SendPacket(packet_data, offsets, GetFrameDimensions())) { return; } - if (IsInterlaced()) { - auto [luma_top, luma_bottom, chroma_top, chroma_bottom] = GetInterlacedOffsets(); - auto frame_copy = frame; - - if (!frame.get()) { - LOG_ERROR(HW_GPU, - "Nvdec {} failed to decode interlaced frame for top {:#X} bottom 0x{:X}", id, - luma_top, luma_bottom); - } - + auto push = [&](u64 luma, std::shared_ptr<FFmpeg::Frame> frame) { if (UsingDecodeOrder()) { - host1x.frame_queue.PushDecodeOrder(id, luma_top, std::move(frame)); - host1x.frame_queue.PushDecodeOrder(id, luma_bottom, std::move(frame_copy)); + host1x.frame_queue.PushDecodeOrder(id, luma, std::move(frame)); } else { - host1x.frame_queue.PushPresentOrder(id, luma_top, std::move(frame)); - host1x.frame_queue.PushPresentOrder(id, luma_bottom, std::move(frame_copy)); + host1x.frame_queue.PushPresentOrder(id, luma, std::move(frame)); } - } else { - auto [luma_offset, chroma_offset] = GetProgressiveOffsets(); + }; - if (!frame.get()) { - LOG_ERROR(HW_GPU, "Nvdec {} failed to decode progressive frame for luma {:#X}", id, - luma_offset); + while (auto result = decode_api.ReceiveFrame()) { + auto& [frame, frame_offsets] = *result; + if (!frame) { + continue; } - - if (UsingDecodeOrder()) { - host1x.frame_queue.PushDecodeOrder(id, luma_offset, std::move(frame)); + if (frame_offsets.interlaced) { + auto frame_copy = frame; + push(frame_offsets.luma, std::move(frame)); + push(frame_offsets.luma_bottom, std::move(frame_copy)); } else { - host1x.frame_queue.PushPresentOrder(id, luma_offset, std::move(frame)); + push(frame_offsets.luma, std::move(frame)); } } } |
