GRC services: Difference between revisions
(6 intermediate revisions by 2 users not shown) | |||
Line 8: | Line 8: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! Cmd || Name | ! Cmd || Name | ||
|- | |- | ||
| 1 || | | 1 || [[#OpenContinuousRecorder]] | ||
|- | |- | ||
| 2 || | | 2 || [[#OpenGameMovieTrimmer]] | ||
|- | |- | ||
| 3 || [5.0.0+] | | 3 || [5.0.0+] [[#OpenOffscreenRecorder]] | ||
|- | |- | ||
| 101 || [5.0.0+] | | 101 || [5.0.0+] [[#CreateMovieMaker]] | ||
|- | |- | ||
| 9903 || [5.0.0+] | | 9903 || [5.0.0+] [[#SetOffscreenRecordingMarker]] | ||
|} | |} | ||
[5.0.0+] | == OpenContinuousRecorder == | ||
Takes a total of 0x28-bytes of input and a handle, returns an [[#IContinuousRecorder]]. | |||
[5.0.0+] Now takes an additional 0x20-bytes of input. | |||
== OpenGameMovieTrimmer == | |||
Takes an input u64 and a handle, returns an [[#IGameMovieTrimmer]]. | |||
== OpenOffscreenRecorder == | |||
Takes a total of 0x8-bytes of input and a handle, returns an [[#IOffscreenRecorder]]. | |||
== CreateMovieMaker == | |||
Takes a total of 0x10-bytes of input, returns an [[#IMovieMaker]]. | |||
== 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 88: | Line 105: | ||
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 || | | 1 || [[#Initialize]] | ||
|- | |- | ||
| 2 || | | 2 || [[#Transfer]] | ||
|} | |} | ||
== | == 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 185: | Line 208: | ||
== RequestOffscreenRecordingFinishReady == | == RequestOffscreenRecordingFinishReady == | ||
Takes an input u64 '''LayerHandle''', no output. | Takes an input u64 '''LayerHandle''', no output. | ||
This is the first cmd used by official sw when finishing recording. Then it waits on the Event originally loaded from [[#GetOffscreenLayerRecordingFinishReadyEvent]]. Then CompleteOffscreenRecordingFinishEx* is used, depending on the sdk-nso version. On any errors, [[#AbortOffscreenRecording]] is used. | |||
== StartOffscreenRecordingEx == | == StartOffscreenRecordingEx == | ||
Line 193: | Line 218: | ||
Seems to be unused by official user processes, [[#CompleteOffscreenRecordingFinishEx0]] is used instead. | Seems to be unused by official user processes, [[#CompleteOffscreenRecordingFinishEx0]] is used instead. | ||
The input buffer contains the optional ApplicationData for the JPEG thumbnail, size must be <=0x400. | |||
The recorded video will not be accessible via the Album-applet since it's stored separately from other Album data. | |||
== CompleteOffscreenRecordingFinishEx0 == | == CompleteOffscreenRecordingFinishEx0 == | ||
Takes two input s32s '''width'''/'''height''', an input u64 '''LayerHandle''' and 2 type-0x5 input buffers, no output. | Takes two input s32s '''width'''/'''height''', an input u64 '''LayerHandle''' and 2 type-0x5 input buffers, no output. | ||
The input buffers are optional, addr=NULL and size=0 can be used for these. | The input buffers are optional, addr=NULL and size=0 can be used for these. The first buffer is for [[#CompleteOffscreenRecordingFinish|ApplicationData]], the second buffer buffer contains the RGBA8 image thumbnail. | ||
'''width'''/'''height''' must be 1280x720, these fields are unused afterwards. | '''width'''/'''height''' must be 1280x720, these fields are unused afterwards. | ||
Line 206: | Line 235: | ||
Takes two input s32s '''width'''/'''height''', an input u64 '''LayerHandle''' and two type-0x5 input buffers, returns an output [[Capture_services|ApplicationAlbumEntry]]. | Takes two input s32s '''width'''/'''height''', an input u64 '''LayerHandle''' and two type-0x5 input buffers, returns an output [[Capture_services|ApplicationAlbumEntry]]. | ||
Same as [[#CompleteOffscreenRecordingFinishEx0]] except the output struct is returned in the cmdreply. | Same as [[#CompleteOffscreenRecordingFinishEx0]] except the output struct is returned in the cmdreply. Official sw copies the output struct into a "nn::album::AlbumFileEntry". | ||
== GetOffscreenLayerError == | |||
Takes an input u64 '''LayerHandle''', no output. | |||
== EncodeOffscreenLayerAudioSample == | == EncodeOffscreenLayerAudioSample == | ||
Line 216: | Line 248: | ||
* Updates the current pos and remaining_size with the '''out_size'''. | * Updates the current pos and remaining_size with the '''out_size'''. | ||
* Repeats the loop until the remaining_size is 0. | * Repeats the loop until the remaining_size is 0. | ||
== GetOffscreenLayerRecordingFinishReadyEvent == | == GetOffscreenLayerRecordingFinishReadyEvent == | ||
Line 227: | Line 256: | ||
= 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 233: | Line 266: | ||
| 0x0 || 0x10 || ? || 0 | | 0x0 || 0x10 || ? || 0 | ||
|- | |- | ||
| 0x10 || 0x4 || | | 0x10 || 0x4 || Unknown, must match 0x103. || 0x103 | ||
|- | |- | ||
| 0x14 || 0x4 || s32 VideoBitRate || 8000000 | | 0x14 || 0x4 || s32 VideoBitRate, 0 is invalid. || 8000000 | ||
|- | |- | ||
| 0x18 || 0x4 || s32 VideoWidth || 1280 | | 0x18 || 0x4 || s32 VideoWidth, must match 1280 or 1920. || 1280 | ||
|- | |- | ||
| 0x1C || 0x4 || s32 VideoHeight || 720 | | 0x1C || 0x4 || s32 VideoHeight, must match 720 or 1080. || 720 | ||
|- | |- | ||
| 0x20 || 0x4 || s32 VideoFrameRate || 30 | | 0x20 || 0x4 || s32 VideoFrameRate, must match 30 or 60. || 30 | ||
|- | |- | ||
| 0x24 || 0x4 || s32 VideoKeyFrameInterval || 30 | | 0x24 || 0x4 || s32 VideoKeyFrameInterval, 0 is invalid. || 30 | ||
|- | |- | ||
| 0x28 || 0x4 || s32 AudioBitRate || 128000 ([5.0.0-5.1.0] 1536000) | | 0x28 || 0x4 || s32 AudioBitRate || 128000 ([5.0.0-5.1.0] 1536000) | ||
|- | |- | ||
| 0x2C || 0x4 || s32 AudioSampleRate || 48000 | | 0x2C || 0x4 || s32 AudioSampleRate, 0 is invalid. || 48000 | ||
|- | |- | ||
| 0x30 || 0x4 || s32 AudioChannelCount || 2 | | 0x30 || 0x4 || s32 AudioChannelCount, must match 2. || 2 | ||
|- | |- | ||
| 0x34 || 0x4 || "nn::audio::SampleFormat" AudioSampleFormat || 2 | | 0x34 || 0x4 || "nn::audio::SampleFormat" AudioSampleFormat, must match 2. || 2 | ||
|- | |- | ||
| 0x38 || 0x4 || "nn::album::ImageOrientation" VideoImageOrientation. || 0 | | 0x38 || 0x4 || "nn::album::ImageOrientation" VideoImageOrientation. || 0 | ||
Line 257: | Line 290: | ||
| 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 271: | Line 306: | ||
| 0x18 || 0x28 || Unused, always zero. | | 0x18 || 0x28 || Unused, always zero. | ||
|} | |} | ||
= IHOSBinderDriver = | = IHOSBinderDriver = |