aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/host1x/codecs/decoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/host1x/codecs/decoder.cpp')
-rw-r--r--src/video_core/host1x/codecs/decoder.cpp66
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));
}
}
}