Changes

Line 8: Line 8:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 +
|-
 +
| 1 || [[#OpenContinuousRecorder]]
 
|-
 
|-
| 1 || OpenContinuousRecorder || Takes a total of 0x28-bytes of input and a handle, returns an [[#IContinuousRecorder]].
+
| 2 || [[#OpenGameMovieTrimmer]]
 
|-
 
|-
| 2 || OpenGameMovieTrimmer || Takes an input u64 and a handle, returns an [[#IGameMovieTrimmer]].
+
| 3 || [5.0.0+] [[#OpenOffscreenRecorder]]
 
|-
 
|-
| 3 || [5.0.0+] || Takes a total of 0x8-bytes of input and a handle, returns an [[#IOffscreenRecorder]].
+
| 10 || [18.0.0+]  
 
|-
 
|-
| 101 || [5.0.0+] || Takes a total of 0x10-bytes of input, returns an [[#IMovieMaker]].
+
| 101 || [5.0.0+] [[#CreateMovieMaker]]
 
|-
 
|-
| 9903 || [5.0.0+] || Takes 8-bytes of input, no output.
+
| 9903 || [5.0.0+] [[#SetOffscreenRecordingMarker]]
 
|}
 
|}
   −
[5.0.0+] OpenContinuousRecorder now takes an additional 0x20-bytes of input.
+
== 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]].
 +
 
 +
== 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 53:  
! Cmd || Name
 
! Cmd || Name
 
|-
 
|-
| 1 ||
+
| 1 || StartRecording
 
|-
 
|-
| 2 ||
+
| 2 || StopRecording
 
|-
 
|-
| 10 ||
+
| 4 || [17.0.0+] UpdateRecordingStartTick
 
|-
 
|-
| 11 ||
+
| 10 || GetNotFlushingEvent
 
|-
 
|-
| 12 ||
+
| 11 || StartFlush
 
|-
 
|-
| 13 ||
+
| 12 || CancelFlush
 
|-
 
|-
| 14 || [5.0.0+]
+
| 13 || ResetFlushTime
 +
|-
 +
| 14 || [5.0.0+] StartFlushWithEvent
 
|}
 
|}
   −
[5.0.0+] Cmd11 now takes a total of 0x40-bytes of input.
+
[5.0.0+] StartFlush now takes in a ContinuousRecordingFlushParameter (0x40 bytes).
   −
[8.0.0+] Cmd11/cmd14 no longer take any rawdata input, these now take a type-0x15 input buffer.
+
[8.0.0+] ContinuousRecordingFlushParameter is now an sf::LargeData type, so StartFlush/StartFlushWithEvent now take in parameter via type-0x15 input buffer.
    
== IGameMovieTrimmer ==
 
== IGameMovieTrimmer ==
Line 88: Line 113:  
This is "nn::grcsrv::IRemoteVideoTransfer".
 
This is "nn::grcsrv::IRemoteVideoTransfer".
   −
Added with [[6.0.0]].
+
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 || Notes
+
! Cmd || Name
 +
|-
 +
| 1 || [[#Initialize]]
 
|-
 
|-
| 1 || || No input/output.
+
| 2 || [[#Transfer]]
 
|-
 
|-
| 2 || || Takes an input u32 (must be value 0-1) and a type-0x6 output buffer, returns a total of 0x10-bytes of output.
+
| 3 || [14.0.0+]
 
|}
 
|}
   −
== Cmd1 ==
+
== 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.
   −
== Cmd2 ==
+
== Transfer ==
Retrieves stream data, from the video recording being done of the currently running game title. Takes u32 "stream" (0: video, 1: audio), returns u32 (num_frames?), u32 data_size, u64 (start_timestamp?). 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.
+
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 116: Line 149:  
! Cmd || Name || Notes
 
! Cmd || Name || Notes
 
|-
 
|-
| 201 || || Takes a total of 0x8-bytes of input, returns a total of 0x8-bytes of output.
+
| 201 || CreateOffscreenLayer || Takes an aruid, returns an 8-byte handle to the layer.
 
|-
 
|-
| 202 || || Takes a total of 0x8-bytes of input, no output.
+
| 202 || DestroyOffscreenLayer || Takes in an 8-byte layer handle previously returned by CreateOffscreenLayer.
 
|}
 
|}
   Line 195: Line 228:     
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 208: Line 245:  
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 ==
 
== GetOffscreenLayerError ==
Line 229: Line 266:     
= 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 235: Line 276:  
| 0x0 || 0x10 || ? || 0
 
| 0x0 || 0x10 || ? || 0
 
|-
 
|-
| 0x10 || 0x4 || ? || 0x103
+
| 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 259: Line 300:  
| 0x3C || 0x44 || ? || 0
 
| 0x3C || 0x44 || ? || 0
 
|}
 
|}
  −
This is "nn::grcsrv::OffscreenRecordingParameter". This is a 0x80-byte struct. "nn::grc::OffscreenRecordingParameter" and "nn::album::MovieMakerMovieParameter" are identical to this.
      
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 273: Line 316:  
| 0x18 || 0x28 || Unused, always zero.
 
| 0x18 || 0x28 || Unused, always zero.
 
|}
 
|}
  −
This is "nn::grcsrv::GameMovieId". This is a 0x40-byte struct.
      
= IHOSBinderDriver =
 
= IHOSBinderDriver =