GRC services: Difference between revisions
(21 intermediate revisions by 3 users not shown) | |||
Line 8: | Line 8: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Cmd || Name || | ! Cmd || Name | ||
|- | |||
| 1 || [[#OpenContinuousRecorder]] | |||
|- | |||
| 2 || [[#OpenGameMovieTrimmer]] | |||
|- | |- | ||
| | | 3 || [5.0.0+] [[#OpenOffscreenRecorder]] | ||
|- | |- | ||
| | | 10 || [18.0.0+] | ||
|- | |- | ||
| | | 101 || [5.0.0+] [[#CreateMovieMaker]] | ||
|- | |- | ||
| | | 110 || [19.0.0+] | ||
|- | |- | ||
| 9903 || [5.0.0+] | | 9903 || [5.0.0+] [[#SetOffscreenRecordingMarker]] | ||
|} | |} | ||
[5.0.0+] | == OpenContinuousRecorder == | ||
Takes a total of 0x28-bytes of input and a TransferMemory handle, returns an [[#IContinuousRecorder]]. | |||
[5.0.0+] Now takes an additional 0x20-bytes of input. | |||
[15.0.0+] Now only takes 0x20-bytes of input. | |||
[18.0.0+] Now takes a total of 0x28 bytes of input. | |||
== OpenGameMovieTrimmer == | |||
Takes an input u64 and a TransferMemory handle, returns an [[#IGameMovieTrimmer]]. | |||
== OpenOffscreenRecorder == | |||
Takes a total of 0x8-bytes of input and a TransferMemory handle, returns an [[#IOffscreenRecorder]]. | |||
== CreateMovieMaker == | |||
Takes a total of 0x10-bytes of input, returns an [[#IMovieMaker]]. | |||
== Cmd110 == | |||
Takes a total of 0x20-bytes of input and a handle. Returns an [[#IMovieWriter]]. | |||
This is stubbed on NX: this just closes the input handle if needed, then returns Result 0xFFED4. | |||
== SetOffscreenRecordingMarker == | |||
Takes an u64 '''marker''' (value from 0 to 14), no output. | |||
Affects the behavior of [[#CompleteOffscreenRecordingFinish]], [[#CompleteOffscreenRecordingFinishEx0]] and [[#CompleteOffscreenRecordingFinishEx1]], forcing them to stop at different stages. | |||
== IContinuousRecorder == | == IContinuousRecorder == | ||
Line 30: | Line 60: | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 1 || | | 1 || StartRecording | ||
|- | |||
| 2 || StopRecording | |||
|- | |||
| 4 || [17.0.0+] UpdateRecordingStartTick | |||
|- | |- | ||
| | | 5 || [20.0.0+] | ||
|- | |- | ||
| 10 || | | 10 || GetNotFlushingEvent | ||
|- | |- | ||
| 11 || | | 11 || StartFlush | ||
|- | |- | ||
| 12 || | | 12 || CancelFlush | ||
|- | |- | ||
| 13 || | | 13 || ResetFlushTime | ||
|- | |- | ||
| 14 || [5.0.0+] | | 14 || [5.0.0+] StartFlushWithEvent | ||
|} | |} | ||
[5.0.0+] | [5.0.0+] StartFlush now takes in a ContinuousRecordingFlushParameter (0x40 bytes). | ||
[8.0.0+] ContinuousRecordingFlushParameter is now an sf::LargeData type, so StartFlush/StartFlushWithEvent now take in parameter via type-0x15 input buffer. | |||
=== Cmd5 === | |||
Takes an input u32, no output. | |||
On NX this is identical to StartRecording, the input u32 is ignored. | |||
== IGameMovieTrimmer == | == IGameMovieTrimmer == | ||
Line 63: | Line 102: | ||
|- | |- | ||
| 20 || [[#SetThumbnailRgba]] | | 20 || [[#SetThumbnailRgba]] | ||
|- | |||
| 21 || [19.0.0+] | |||
|} | |} | ||
Line 84: | Line 125: | ||
'''width''' must be 1280, '''height''' must be 720, and the buffer size must be at least 0x384000. After this validation, this just copies the input buffer to state with size 0x384000 and returns 0. | '''width''' must be 1280, '''height''' must be 720, and the buffer size must be at least 0x384000. After this validation, this just copies the input buffer to state with size 0x384000 and returns 0. | ||
=== Cmd21 === | |||
Takes a total of 8-bytes of input and a type-0x45 input buffer. No output. | |||
On NX this just Aborts with Result 0xFFED4. | |||
= grc:d = | = grc:d = | ||
This is "nn::grcsrv::IRemoteVideoTransfer". | This is "nn::grcsrv::IRemoteVideoTransfer". | ||
This was added with [[6.0.0]]. | |||
The max sessions for this service is 4, and it uses 2 IPC handler threads. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Cmd || Name || | ! Cmd || Name | ||
|- | |||
| 1 || [[#Initialize]] | |||
|- | |- | ||
| | | 2 || [[#Transfer]] | ||
|- | |- | ||
| | | 3 || [14.0.0+] | ||
|} | |} | ||
== | == Initialize == | ||
No input/output. | |||
Begins video stream. This must not be used more than once, even from a different service session: otherwise the sysmodule will assert. | Begins video stream. This must not be used more than once, even from a different service session: otherwise the sysmodule will assert. | ||
== | == Transfer == | ||
Takes an u32 '''stream''' (0: video, 1: audio) and a type-0x6 output buffer, returns 2 u32s '''num_frames''' and '''data_size''' and an u64 '''start_timestamp'''. | |||
Retrieves stream data from the continuous recorder in use. Video stream writes H.264 NAL units to the output buffer (try <code>ffplay -f h264</code>). Audio stream is PCM16, 2 channels, and sample-rate = 48000Hz. Official code uses buffer size 0x32000 for video, 0x1000 for audio, and multiple threads to read out both streams at the same time. | |||
This will block until data is available. This will hang if there is no game title running which has video capture enabled. | This will block until data is available. This will hang if there is no game title running which has video capture enabled. | ||
Line 114: | Line 168: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 201 || | | 201 || [[#CreateOffscreenLayer]] | ||
|- | |- | ||
| 202 || | | 202 || [[#DestroyOffscreenLayer]] | ||
|} | |} | ||
== CreateOffscreenLayer == | |||
Takes an aruid, returns an 8-byte handle to the layer. | |||
== DestroyOffscreenLayer == | |||
Takes in an 8-byte layer handle previously returned by CreateOffscreenLayer. | |||
= IMovieMaker = | = IMovieMaker = | ||
Line 231: | Line 291: | ||
== GetOffscreenLayerAudioEncodeReadyEvent == | == GetOffscreenLayerAudioEncodeReadyEvent == | ||
Takes an input u64 '''LayerHandle''', returns an output event handle with autoclear disabled. | Takes an input u64 '''LayerHandle''', returns an output event handle with autoclear disabled. | ||
= IMovieWriter = | |||
This is "nn::grcsrv::IMovieWriter". | |||
This was added with [19.0.0+]. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Cmd || Name | |||
|- | |||
| 0 || | |||
|- | |||
| 10 || | |||
|- | |||
| 20 || | |||
|- | |||
| 100 || | |||
|- | |||
| 110 || | |||
|- | |||
| 120 || | |||
|- | |||
| 130 || | |||
|} | |||
= OffscreenRecordingParameter = | = OffscreenRecordingParameter = | ||
This is "nn::grcsrv::OffscreenRecordingParameter". | |||
This is a 0x80-byte struct. "nn::grc::OffscreenRecordingParameter" and "nn::album::MovieMakerMovieParameter" are identical to this. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 263: | Line 351: | ||
| 0x3C || 0x44 || ? || 0 | | 0x3C || 0x44 || ? || 0 | ||
|} | |} | ||
The above default values are initialized by the official user-process via sdk-nso funcs "nn::album::MovieMakerMovieParameter::GetDefaultValue()" / "nn::album::MovieMakerMovieParameter::MovieMakerMovieParameter()" (both funcs are identical). | The above default values are initialized by the official user-process via sdk-nso funcs "nn::album::MovieMakerMovieParameter::GetDefaultValue()" / "nn::album::MovieMakerMovieParameter::MovieMakerMovieParameter()" (both funcs are identical). | ||
= GameMovieId = | = GameMovieId = | ||
This is "nn::grcsrv::GameMovieId". | |||
This is a 0x40-byte struct. | |||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
Line 277: | Line 367: | ||
| 0x18 || 0x28 || Unused, always zero. | | 0x18 || 0x28 || Unused, always zero. | ||
|} | |} | ||
= IHOSBinderDriver = | = IHOSBinderDriver = |