diff options
| author | 2015-05-21 23:27:48 -0300 | |
|---|---|---|
| committer | 2015-05-22 17:57:21 -0300 | |
| commit | 9108482888ae66644e253fb104411746dc82b635 (patch) | |
| tree | b7d6cb64c69e069e89616e58c0e5ea6ba6a9cfc1 /src | |
| parent | Merge pull request #794 from linkmauve/resource-limit (diff) | |
| download | yuzu-9108482888ae66644e253fb104411746dc82b635.tar.gz yuzu-9108482888ae66644e253fb104411746dc82b635.tar.xz yuzu-9108482888ae66644e253fb104411746dc82b635.zip | |
Service::Y2R: Support for grayscale decoding of specific formats
Implements unrotated planar YUV 4:2:0 -> RGB24 conversions in Y2R.
Currently only the Y (luma) channel is used, so the results don't
contain color. This will be added in a later PR at some point.
This is enough to get all currently know Moflex videos to decode. (Some
don't display on-screen due to seemingly unrelated reasons.)
Thanks to @archshift for doing the initial implementation which I
cleaned up and then fixed the 8x8 block mode.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/logging/backend.cpp | 1 | ||||
| -rw-r--r-- | src/common/logging/log.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/y2r_u.cpp | 300 |
3 files changed, 267 insertions, 35 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index bd2c6a153..6ca8cb78d 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -45,6 +45,7 @@ namespace Log { | |||
| 45 | SUB(Service, DSP) \ | 45 | SUB(Service, DSP) \ |
| 46 | SUB(Service, HID) \ | 46 | SUB(Service, HID) \ |
| 47 | SUB(Service, SOC) \ | 47 | SUB(Service, SOC) \ |
| 48 | SUB(Service, Y2R) \ | ||
| 48 | CLS(HW) \ | 49 | CLS(HW) \ |
| 49 | SUB(HW, Memory) \ | 50 | SUB(HW, Memory) \ |
| 50 | SUB(HW, LCD) \ | 51 | SUB(HW, LCD) \ |
diff --git a/src/common/logging/log.h b/src/common/logging/log.h index fd87ddbe6..d720d7fe0 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h | |||
| @@ -65,6 +65,7 @@ enum class Class : ClassType { | |||
| 65 | Service_DSP, ///< The DSP (DSP control) service | 65 | Service_DSP, ///< The DSP (DSP control) service |
| 66 | Service_HID, ///< The HID (User input) service | 66 | Service_HID, ///< The HID (User input) service |
| 67 | Service_SOC, ///< The SOC (Socket) service | 67 | Service_SOC, ///< The SOC (Socket) service |
| 68 | Service_Y2R, ///< The Y2R (YUV to RGB conversion) service | ||
| 68 | HW, ///< Low-level hardware emulation | 69 | HW, ///< Low-level hardware emulation |
| 69 | HW_Memory, ///< Memory-map and address translation | 70 | HW_Memory, ///< Memory-map and address translation |
| 70 | HW_LCD, ///< LCD register emulation | 71 | HW_LCD, ///< LCD register emulation |
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index edc443611..ce822e990 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp | |||
| @@ -1,85 +1,314 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | 1 | // Copyright 2015 Citra Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | ||
| 6 | |||
| 5 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 6 | 8 | ||
| 7 | #include "core/hle/hle.h" | 9 | #include "core/hle/hle.h" |
| 8 | #include "core/hle/kernel/event.h" | 10 | #include "core/hle/kernel/event.h" |
| 9 | #include "core/hle/service/y2r_u.h" | 11 | #include "core/hle/service/y2r_u.h" |
| 12 | #include "video_core/utils.h" | ||
| 10 | 13 | ||
| 11 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 12 | // Namespace Y2R_U | 15 | // Namespace Y2R_U |
| 13 | 16 | ||
| 14 | namespace Y2R_U { | 17 | namespace Y2R_U { |
| 15 | 18 | ||
| 19 | enum class InputFormat { | ||
| 20 | /// 8-bit input, with YUV components in separate planes and using 4:2:2 subsampling. | ||
| 21 | YUV422_Indiv8 = 0, | ||
| 22 | /// 8-bit input, with YUV components in separate planes and using 4:2:0 subsampling. | ||
| 23 | YUV420_Indiv8 = 1, | ||
| 24 | |||
| 25 | YUV422_INDIV_16 = 2, | ||
| 26 | YUV420_INDIV_16 = 3, | ||
| 27 | YUV422_BATCH = 4, | ||
| 28 | }; | ||
| 29 | |||
| 30 | enum class OutputFormat { | ||
| 31 | Rgb32 = 0, | ||
| 32 | Rgb24 = 1, | ||
| 33 | Rgb16_555 = 2, | ||
| 34 | Rgb16_565 = 3, | ||
| 35 | }; | ||
| 36 | |||
| 37 | enum class Rotation { | ||
| 38 | None = 0, | ||
| 39 | Clockwise_90 = 1, | ||
| 40 | Clockwise_180 = 2, | ||
| 41 | Clockwise_270 = 3, | ||
| 42 | }; | ||
| 43 | |||
| 44 | enum class BlockAlignment { | ||
| 45 | /// Image is output in linear format suitable for use as a framebuffer. | ||
| 46 | Linear = 0, | ||
| 47 | /// Image is output in tiled PICA format, suitable for use as a texture. | ||
| 48 | Block8x8 = 1, | ||
| 49 | }; | ||
| 50 | |||
| 51 | enum class StandardCoefficient { | ||
| 52 | ITU_Rec601 = 0, | ||
| 53 | ITU_Rec709 = 1, | ||
| 54 | ITU_Rec601_Scaling = 2, | ||
| 55 | ITU_Rec709_Scaling = 3, | ||
| 56 | }; | ||
| 57 | |||
| 16 | static Kernel::SharedPtr<Kernel::Event> completion_event; | 58 | static Kernel::SharedPtr<Kernel::Event> completion_event; |
| 17 | 59 | ||
| 18 | /** | 60 | struct ConversionParameters { |
| 19 | * Y2R_U::IsBusyConversion service function | 61 | InputFormat input_format; |
| 20 | * Outputs: | 62 | OutputFormat output_format; |
| 21 | * 1 : Result of function, 0 on success, otherwise error code | 63 | Rotation rotation; |
| 22 | * 2 : Whether the current conversion is of type busy conversion (?) | 64 | BlockAlignment alignment; |
| 23 | */ | 65 | u16 input_line_width; |
| 24 | static void IsBusyConversion(Service::Interface* self) { | 66 | u16 input_lines; |
| 67 | |||
| 68 | // Input parameters for the Y (luma) plane | ||
| 69 | VAddr srcY_address; | ||
| 70 | u32 srcY_image_size; | ||
| 71 | u16 srcY_transfer_unit; | ||
| 72 | u16 srcY_stride; | ||
| 73 | |||
| 74 | // Output parameters for the conversion results | ||
| 75 | VAddr dst_address; | ||
| 76 | u32 dst_image_size; | ||
| 77 | u16 dst_transfer_unit; | ||
| 78 | u16 dst_stride; | ||
| 79 | }; | ||
| 80 | |||
| 81 | static ConversionParameters conversion_params; | ||
| 82 | |||
| 83 | static void SetInputFormat(Service::Interface* self) { | ||
| 25 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 84 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 26 | 85 | ||
| 27 | cmd_buff[1] = RESULT_SUCCESS.raw;; | 86 | conversion_params.input_format = static_cast<InputFormat>(cmd_buff[1]); |
| 28 | cmd_buff[2] = 0; | 87 | LOG_DEBUG(Service_Y2R, "called input_format=%u", conversion_params.input_format); |
| 29 | 88 | ||
| 30 | LOG_WARNING(Service, "(STUBBED) called"); | 89 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 90 | } | ||
| 91 | |||
| 92 | static void SetOutputFormat(Service::Interface* self) { | ||
| 93 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 94 | |||
| 95 | conversion_params.output_format = static_cast<OutputFormat>(cmd_buff[1]); | ||
| 96 | LOG_DEBUG(Service_Y2R, "called output_format=%u", conversion_params.output_format); | ||
| 97 | |||
| 98 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 99 | } | ||
| 100 | |||
| 101 | static void SetRotation(Service::Interface* self) { | ||
| 102 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 103 | |||
| 104 | conversion_params.rotation = static_cast<Rotation>(cmd_buff[1]); | ||
| 105 | LOG_DEBUG(Service_Y2R, "called rotation=%u", conversion_params.rotation); | ||
| 106 | |||
| 107 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 108 | } | ||
| 109 | |||
| 110 | static void SetBlockAlignment(Service::Interface* self) { | ||
| 111 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 112 | |||
| 113 | conversion_params.alignment = static_cast<BlockAlignment>(cmd_buff[1]); | ||
| 114 | LOG_DEBUG(Service_Y2R, "called alignment=%u", conversion_params.alignment); | ||
| 115 | |||
| 116 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 31 | } | 117 | } |
| 32 | 118 | ||
| 33 | /** | 119 | /** |
| 34 | * Y2R_U::GetTransferEndEvent service function | 120 | * Y2R_U::GetTransferEndEvent service function |
| 35 | * Outputs: | 121 | * Outputs: |
| 36 | * 1 : Result of function, 0 on success, otherwise error code | 122 | * 1 : Result of function, 0 on success, otherwise error code |
| 37 | * 3 : The handle of the completion event | 123 | * 3 : The handle of the completion event |
| 38 | */ | 124 | */ |
| 39 | static void GetTransferEndEvent(Service::Interface* self) { | 125 | static void GetTransferEndEvent(Service::Interface* self) { |
| 40 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 126 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 41 | 127 | ||
| 42 | cmd_buff[1] = RESULT_SUCCESS.raw; | 128 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 43 | cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); | 129 | cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); |
| 130 | LOG_DEBUG(Service_Y2R, "called"); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void SetSendingY(Service::Interface* self) { | ||
| 134 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 135 | |||
| 136 | conversion_params.srcY_address = cmd_buff[1]; | ||
| 137 | conversion_params.srcY_image_size = cmd_buff[2]; | ||
| 138 | conversion_params.srcY_transfer_unit = cmd_buff[3]; | ||
| 139 | conversion_params.srcY_stride = cmd_buff[4]; | ||
| 140 | u32 src_process_handle = cmd_buff[6]; | ||
| 141 | LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " | ||
| 142 | "src_process_handle=0x%08X", conversion_params.srcY_image_size, | ||
| 143 | conversion_params.srcY_transfer_unit, conversion_params.srcY_stride, src_process_handle); | ||
| 144 | |||
| 145 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 146 | } | ||
| 147 | |||
| 148 | static void SetReceiving(Service::Interface* self) { | ||
| 149 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 150 | |||
| 151 | conversion_params.dst_address = cmd_buff[1]; | ||
| 152 | conversion_params.dst_image_size = cmd_buff[2]; | ||
| 153 | conversion_params.dst_transfer_unit = cmd_buff[3]; | ||
| 154 | conversion_params.dst_stride = cmd_buff[4]; | ||
| 155 | u32 dst_process_handle = cmd_buff[6]; | ||
| 156 | LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " | ||
| 157 | "dst_process_handle=0x%08X", conversion_params.dst_image_size, | ||
| 158 | conversion_params.dst_transfer_unit, conversion_params.dst_stride, | ||
| 159 | dst_process_handle); | ||
| 160 | |||
| 161 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 162 | } | ||
| 163 | |||
| 164 | static void SetInputLineWidth(Service::Interface* self) { | ||
| 165 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 166 | |||
| 167 | conversion_params.input_line_width = cmd_buff[1]; | ||
| 168 | LOG_DEBUG(Service_Y2R, "input_line_width=%u", conversion_params.input_line_width); | ||
| 169 | |||
| 170 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 171 | } | ||
| 172 | |||
| 173 | static void SetInputLines(Service::Interface* self) { | ||
| 174 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 175 | |||
| 176 | conversion_params.input_lines = cmd_buff[1]; | ||
| 177 | LOG_DEBUG(Service_Y2R, "input_line_number=%u", conversion_params.input_lines); | ||
| 178 | |||
| 179 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 44 | } | 180 | } |
| 45 | 181 | ||
| 46 | /** | ||
| 47 | * Starts a YUV -> RGB conversion | ||
| 48 | */ | ||
| 49 | static void StartConversion(Service::Interface* self) { | 182 | static void StartConversion(Service::Interface* self) { |
| 50 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 183 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 51 | 184 | ||
| 52 | // TODO(bunnei): This is hack to indicate to the game that the conversion has immediately | 185 | const u8* srcY_buffer = Memory::GetPointer(conversion_params.srcY_address); |
| 53 | // completed, even though it's not actually implemented yet. This fixes games that would | 186 | u8* dst_buffer = Memory::GetPointer(conversion_params.dst_address); |
| 54 | // otherwise hang on trying to play moflex videos, which uses the Y2R service. | 187 | |
| 188 | // TODO: support color and other kinds of conversions | ||
| 189 | ASSERT(conversion_params.input_format == InputFormat::YUV422_Indiv8 | ||
| 190 | || conversion_params.input_format == InputFormat::YUV420_Indiv8); | ||
| 191 | ASSERT(conversion_params.output_format == OutputFormat::Rgb24); | ||
| 192 | ASSERT(conversion_params.rotation == Rotation::None); | ||
| 193 | const int bpp = 3; | ||
| 194 | |||
| 195 | switch (conversion_params.alignment) { | ||
| 196 | case BlockAlignment::Linear: | ||
| 197 | { | ||
| 198 | const size_t input_lines = conversion_params.input_lines; | ||
| 199 | const size_t input_line_width = conversion_params.input_line_width; | ||
| 200 | const size_t srcY_stride = conversion_params.srcY_stride; | ||
| 201 | const size_t dst_stride = conversion_params.dst_stride; | ||
| 202 | |||
| 203 | size_t srcY_offset = 0; | ||
| 204 | size_t dst_offset = 0; | ||
| 205 | |||
| 206 | for (size_t line = 0; line < input_lines; ++line) { | ||
| 207 | for (size_t i = 0; i < input_line_width; ++i) { | ||
| 208 | u8 Y = srcY_buffer[srcY_offset]; | ||
| 209 | dst_buffer[dst_offset + 0] = Y; | ||
| 210 | dst_buffer[dst_offset + 1] = Y; | ||
| 211 | dst_buffer[dst_offset + 2] = Y; | ||
| 212 | |||
| 213 | srcY_offset += 1; | ||
| 214 | dst_offset += bpp; | ||
| 215 | } | ||
| 216 | srcY_offset += srcY_stride; | ||
| 217 | dst_offset += dst_stride; | ||
| 218 | } | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | case BlockAlignment::Block8x8: | ||
| 222 | { | ||
| 223 | const size_t input_lines = conversion_params.input_lines; | ||
| 224 | const size_t input_line_width = conversion_params.input_line_width; | ||
| 225 | const size_t srcY_stride = conversion_params.srcY_stride; | ||
| 226 | const size_t dst_transfer_unit = conversion_params.dst_transfer_unit; | ||
| 227 | const size_t dst_stride = conversion_params.dst_stride; | ||
| 228 | |||
| 229 | size_t srcY_offset = 0; | ||
| 230 | size_t dst_tile_line_offs = 0; | ||
| 231 | |||
| 232 | const size_t tile_size = 8 * 8 * bpp; | ||
| 233 | |||
| 234 | for (size_t line = 0; line < input_lines;) { | ||
| 235 | size_t tile_y = line / 8; | ||
| 236 | size_t max_line = line + 8; | ||
| 237 | |||
| 238 | for (; line < max_line; ++line) { | ||
| 239 | for (size_t x = 0; x < input_line_width; ++x) { | ||
| 240 | size_t tile_x = x / 8; | ||
| 241 | |||
| 242 | size_t dst_tile_offs = dst_tile_line_offs + tile_x * tile_size; | ||
| 243 | size_t tile_i = VideoCore::MortonInterleave((u32)x, (u32)line); | ||
| 244 | |||
| 245 | size_t dst_offset = dst_tile_offs + tile_i * bpp; | ||
| 246 | |||
| 247 | u8 Y = srcY_buffer[srcY_offset]; | ||
| 248 | dst_buffer[dst_offset + 0] = Y; | ||
| 249 | dst_buffer[dst_offset + 1] = Y; | ||
| 250 | dst_buffer[dst_offset + 2] = Y; | ||
| 251 | |||
| 252 | srcY_offset += 1; | ||
| 253 | } | ||
| 254 | |||
| 255 | srcY_offset += srcY_stride; | ||
| 256 | } | ||
| 257 | |||
| 258 | dst_tile_line_offs += dst_transfer_unit + dst_stride; | ||
| 259 | } | ||
| 260 | break; | ||
| 261 | } | ||
| 262 | } | ||
| 263 | LOG_DEBUG(Service_Y2R, "called"); | ||
| 55 | completion_event->Signal(); | 264 | completion_event->Signal(); |
| 56 | 265 | ||
| 57 | LOG_WARNING(Service, "(STUBBED) called, expect blank video (MOFLEX) output!"); | 266 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 267 | } | ||
| 268 | |||
| 269 | /** | ||
| 270 | * Y2R_U::IsBusyConversion service function | ||
| 271 | * Outputs: | ||
| 272 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 273 | * 2 : 1 if there's a conversion running, otherwise 0. | ||
| 274 | */ | ||
| 275 | static void IsBusyConversion(Service::Interface* self) { | ||
| 276 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 58 | 277 | ||
| 59 | cmd_buff[1] = RESULT_SUCCESS.raw; | 278 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| 279 | cmd_buff[2] = 0; // StartConversion always finishes immediately | ||
| 280 | LOG_DEBUG(Service_Y2R, "called"); | ||
| 281 | } | ||
| 282 | |||
| 283 | static void PingProcess(Service::Interface* self) { | ||
| 284 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 285 | |||
| 286 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 287 | cmd_buff[2] = 0; | ||
| 288 | LOG_WARNING(Service_Y2R, "(STUBBED) called"); | ||
| 60 | } | 289 | } |
| 61 | 290 | ||
| 62 | const Interface::FunctionInfo FunctionTable[] = { | 291 | const Interface::FunctionInfo FunctionTable[] = { |
| 63 | {0x00010040, nullptr, "SetInputFormat"}, | 292 | {0x00010040, SetInputFormat, "SetInputFormat"}, |
| 64 | {0x00030040, nullptr, "SetOutputFormat"}, | 293 | {0x00030040, SetOutputFormat, "SetOutputFormat"}, |
| 65 | {0x00050040, nullptr, "SetRotation"}, | 294 | {0x00050040, SetRotation, "SetRotation"}, |
| 66 | {0x00070040, nullptr, "SetBlockAlignment"}, | 295 | {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, |
| 67 | {0x000D0040, nullptr, "SetTransferEndInterrupt"}, | 296 | {0x000D0040, nullptr, "SetTransferEndInterrupt"}, |
| 68 | {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, | 297 | {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, |
| 69 | {0x00100102, nullptr, "SetSendingY"}, | 298 | {0x00100102, SetSendingY, "SetSendingY"}, |
| 70 | {0x00110102, nullptr, "SetSendingU"}, | 299 | {0x00110102, nullptr, "SetSendingU"}, |
| 71 | {0x00120102, nullptr, "SetSendingV"}, | 300 | {0x00120102, nullptr, "SetSendingV"}, |
| 72 | {0x00180102, nullptr, "SetReceiving"}, | 301 | {0x00180102, SetReceiving, "SetReceiving"}, |
| 73 | {0x001A0040, nullptr, "SetInputLineWidth"}, | 302 | {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, |
| 74 | {0x001C0040, nullptr, "SetInputLines"}, | 303 | {0x001C0040, SetInputLines, "SetInputLines"}, |
| 75 | {0x00200040, nullptr, "SetStandardCoefficient"}, | 304 | {0x00200040, nullptr, "SetStandardCoefficient"}, |
| 76 | {0x00220040, nullptr, "SetAlpha"}, | 305 | {0x00220040, nullptr, "SetAlpha"}, |
| 77 | {0x00260000, StartConversion, "StartConversion"}, | 306 | {0x00260000, StartConversion, "StartConversion"}, |
| 78 | {0x00270000, nullptr, "StopConversion"}, | 307 | {0x00270000, nullptr, "StopConversion"}, |
| 79 | {0x00280000, IsBusyConversion, "IsBusyConversion"}, | 308 | {0x00280000, IsBusyConversion, "IsBusyConversion"}, |
| 80 | {0x002A0000, nullptr, "PingProcess"}, | 309 | {0x002A0000, PingProcess, "PingProcess"}, |
| 81 | {0x002B0000, nullptr, "DriverInitialize"}, | 310 | {0x002B0000, nullptr, "DriverInitialize"}, |
| 82 | {0x002C0000, nullptr, "DriverFinalize"} | 311 | {0x002C0000, nullptr, "DriverFinalize"}, |
| 83 | }; | 312 | }; |
| 84 | 313 | ||
| 85 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 314 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -87,8 +316,9 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 87 | 316 | ||
| 88 | Interface::Interface() { | 317 | Interface::Interface() { |
| 89 | completion_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "Y2R:Completed"); | 318 | completion_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "Y2R:Completed"); |
| 319 | std::memset(&conversion_params, 0, sizeof(conversion_params)); | ||
| 90 | 320 | ||
| 91 | Register(FunctionTable); | 321 | Register(FunctionTable); |
| 92 | } | 322 | } |
| 93 | 323 | ||
| 94 | } // namespace | 324 | } // namespace |