mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-30 19:22:55 +00:00
[video_core/host1x] VP9 Video Playback Fixes (#4590)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- https://git.eden-emu.dev/eden-emu/eden/pulls/4542 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4590 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: John <john@eden-emu.dev>
This commit is contained in:
@@ -312,6 +312,10 @@ struct Vp9PictureInfo {
|
|||||||
bool allow_high_precision_mv;
|
bool allow_high_precision_mv;
|
||||||
bool segment_enabled;
|
bool segment_enabled;
|
||||||
bool mode_ref_delta_enabled;
|
bool mode_ref_delta_enabled;
|
||||||
|
|
||||||
|
Segmentation segmentation;
|
||||||
|
std::array<u8, 7> seg_tree_probs;
|
||||||
|
std::array<u8, 3> seg_pred_probs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vp9FrameContainer {
|
struct Vp9FrameContainer {
|
||||||
@@ -377,6 +381,10 @@ struct PictureInfo {
|
|||||||
.allow_high_precision_mv = allow_high_precision_mv != 0,
|
.allow_high_precision_mv = allow_high_precision_mv != 0,
|
||||||
.segment_enabled = segmentation.enabled != 0,
|
.segment_enabled = segmentation.enabled != 0,
|
||||||
.mode_ref_delta_enabled = loop_filter.mode_ref_delta_enabled != 0,
|
.mode_ref_delta_enabled = loop_filter.mode_ref_delta_enabled != 0,
|
||||||
|
|
||||||
|
.segmentation = segmentation,
|
||||||
|
.seg_tree_probs = {},
|
||||||
|
.seg_pred_probs = {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -331,19 +331,16 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VP9::WriteSegmentation(VpxBitStreamWriter& writer) {
|
void VP9::WriteSegmentation(VpxBitStreamWriter& writer) {
|
||||||
bool enabled = current_picture_info.segmentation.enabled != 0;
|
bool enabled = current_frame_info.segmentation.enabled != 0;
|
||||||
writer.WriteBit(enabled);
|
writer.WriteBit(enabled);
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto update_map = current_picture_info.segmentation.update_map != 0;
|
auto update_map = current_frame_info.segmentation.update_map != 0;
|
||||||
writer.WriteBit(update_map);
|
writer.WriteBit(update_map);
|
||||||
|
|
||||||
if (update_map) {
|
if (update_map) {
|
||||||
EntropyProbs entropy_probs{};
|
|
||||||
host1x.gmmu_manager.ReadBlock(regs.vp9_prob_tab_buffer_offset.Address(), &entropy_probs, sizeof(entropy_probs));
|
|
||||||
|
|
||||||
auto WriteProb = [&](u8 prob) {
|
auto WriteProb = [&](u8 prob) {
|
||||||
bool coded = prob != 255;
|
bool coded = prob != 255;
|
||||||
writer.WriteBit(coded);
|
writer.WriteBit(coded);
|
||||||
@@ -352,55 +349,55 @@ void VP9::WriteSegmentation(VpxBitStreamWriter& writer) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < entropy_probs.mb_segment_tree_probs.size(); i++) {
|
for (size_t i = 0; i < current_frame_info.seg_tree_probs.size(); i++) {
|
||||||
WriteProb(entropy_probs.mb_segment_tree_probs[i]);
|
WriteProb(current_frame_info.seg_tree_probs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto temporal_update = current_picture_info.segmentation.temporal_update != 0;
|
auto temporal_update = current_frame_info.segmentation.temporal_update != 0;
|
||||||
writer.WriteBit(temporal_update);
|
writer.WriteBit(temporal_update);
|
||||||
|
|
||||||
if (temporal_update) {
|
if (temporal_update) {
|
||||||
for (s32 i = 0; i < 3; i++) {
|
for (s32 i = 0; i < 3; i++) {
|
||||||
WriteProb(entropy_probs.segment_pred_probs[i]);
|
WriteProb(current_frame_info.seg_pred_probs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_segmentation == current_picture_info.segmentation) {
|
if (last_segmentation == current_frame_info.segmentation) {
|
||||||
writer.WriteBit(false);
|
writer.WriteBit(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_segmentation = current_picture_info.segmentation;
|
last_segmentation = current_frame_info.segmentation;
|
||||||
writer.WriteBit(true);
|
writer.WriteBit(true);
|
||||||
writer.WriteBit(current_picture_info.segmentation.abs_delta != 0);
|
writer.WriteBit(current_frame_info.segmentation.abs_delta != 0);
|
||||||
|
|
||||||
constexpr s32 MAX_SEGMENTS = 8;
|
constexpr s32 MAX_SEGMENTS = 8;
|
||||||
constexpr std::array SegmentationFeatureBits = {8, 6, 2, 0};
|
constexpr std::array SegmentationFeatureBits = {8, 6, 2, 0};
|
||||||
|
|
||||||
for (s32 i = 0; i < MAX_SEGMENTS; i++) {
|
for (s32 i = 0; i < MAX_SEGMENTS; i++) {
|
||||||
auto q_enabled = current_picture_info.segmentation.feature_enabled[i][0] != 0;
|
auto q_enabled = current_frame_info.segmentation.feature_enabled[i][0] != 0;
|
||||||
writer.WriteBit(q_enabled);
|
writer.WriteBit(q_enabled);
|
||||||
if (q_enabled) {
|
if (q_enabled) {
|
||||||
writer.WriteS(current_picture_info.segmentation.feature_data[i][0],
|
writer.WriteS(current_frame_info.segmentation.feature_data[i][0],
|
||||||
SegmentationFeatureBits[0]);
|
SegmentationFeatureBits[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lf_enabled = current_picture_info.segmentation.feature_enabled[i][1] != 0;
|
auto lf_enabled = current_frame_info.segmentation.feature_enabled[i][1] != 0;
|
||||||
writer.WriteBit(lf_enabled);
|
writer.WriteBit(lf_enabled);
|
||||||
if (lf_enabled) {
|
if (lf_enabled) {
|
||||||
writer.WriteS(current_picture_info.segmentation.feature_data[i][1],
|
writer.WriteS(current_frame_info.segmentation.feature_data[i][1],
|
||||||
SegmentationFeatureBits[1]);
|
SegmentationFeatureBits[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ref_enabled = current_picture_info.segmentation.feature_enabled[i][2] != 0;
|
auto ref_enabled = current_frame_info.segmentation.feature_enabled[i][2] != 0;
|
||||||
writer.WriteBit(ref_enabled);
|
writer.WriteBit(ref_enabled);
|
||||||
if (ref_enabled) {
|
if (ref_enabled) {
|
||||||
writer.WriteU(current_picture_info.segmentation.feature_data[i][2],
|
writer.WriteU(current_frame_info.segmentation.feature_data[i][2],
|
||||||
SegmentationFeatureBits[2]);
|
SegmentationFeatureBits[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto skip_enabled = current_picture_info.segmentation.feature_enabled[i][3] != 0;
|
auto skip_enabled = current_frame_info.segmentation.feature_enabled[i][3] != 0;
|
||||||
writer.WriteBit(skip_enabled);
|
writer.WriteBit(skip_enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,6 +408,14 @@ Vp9PictureInfo VP9::GetVp9PictureInfo() {
|
|||||||
|
|
||||||
InsertEntropy(regs.vp9_prob_tab_buffer_offset.Address(), vp9_info.entropy);
|
InsertEntropy(regs.vp9_prob_tab_buffer_offset.Address(), vp9_info.entropy);
|
||||||
|
|
||||||
|
EntropyProbs entropy_probs{};
|
||||||
|
host1x.gmmu_manager.ReadBlock(regs.vp9_prob_tab_buffer_offset.Address(),
|
||||||
|
&entropy_probs, sizeof(entropy_probs));
|
||||||
|
|
||||||
|
vp9_info.seg_tree_probs = entropy_probs.mb_segment_tree_probs;
|
||||||
|
vp9_info.seg_pred_probs = entropy_probs.segment_pred_probs;
|
||||||
|
|
||||||
|
|
||||||
// surface_luma_offset[0:3] contains the address of the reference frame offsets in the following
|
// surface_luma_offset[0:3] contains the address of the reference frame offsets in the following
|
||||||
// order: last, golden, altref, current.
|
// order: last, golden, altref, current.
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user