Changes

Jump to navigation Jump to search
3,288 bytes added ,  21:38, 21 October 2019
Line 8: Line 8:  
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
! Cmd || Name || Notes
+
! Cmd || Name
 
|-
 
|-
| 1 || OpenContinuousRecorder || Takes a total of 0x28-bytes of input and a handle, returns an [[#IContinuousRecorder]].
+
| 1 || [[#OpenContinuousRecorder]]
 
|-
 
|-
| 2 || OpenGameMovieTrimmer || Takes an input u64 and a handle, returns an [[#IGameMovieTrimmer]].
+
| 2 || [[#OpenGameMovieTrimmer]]
 
|-
 
|-
| 3 || [5.0.0+] || Takes a total of 0x8-bytes of input and a handle, returns an [[#IOffscreenRecorder]].
+
| 3 || [5.0.0+] [[#OpenOffscreenRecorder]]
 
|-
 
|-
| 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 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".
   −
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 || || No input/output.
+
| 1 || [[#Initialize]]
 
|-
 
|-
| 2 || || Takes an input u32 (must be value 0-1) and a type-0x6 output buffer, returns a total of 0x10-bytes of output.
+
| 2 || [[#Transfer]]
 
|}
 
|}
   −
== Cmd1 ==
+
== Initialize ==
Begins video stream. Can only be called once.
+
No input/output.
   −
== Cmd2 ==
+
Begins video stream. This must not be used more than once, even from a different service session: otherwise the sysmodule will assert.
Retrieves video data. 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>). Official code uses buffer size 0x32000 for video, 0x1000 for audio, and multiple threads to read out both streams at the same time.
+
 
 +
== 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.
    
= IOffscreenRecorder =
 
= IOffscreenRecorder =
Line 163: Line 188:     
== SetAlbumShimLibraryVersion ==
 
== SetAlbumShimLibraryVersion ==
Takes a total of 8-bytes of input, no output.
+
Takes an input u64 [[Capture_services#ShimLibraryVersion|ShimLibraryVersion]], no output.
    
== OpenOffscreenLayer ==
 
== OpenOffscreenLayer ==
Takes an input u64 '''LayerHandle''', returns an output u32.
+
Takes an input u64 '''LayerHandle''', returns an output s32 '''ID'''.
 +
 
 +
This gets the '''ID''' for the [[#IHOSBinderDriver]] returned by [[#CreateVideoProxy]].
    
== CloseOffscreenLayer ==
 
== CloseOffscreenLayer ==
Line 181: 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 189: 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 u32s '''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 200: Line 233:     
== CompleteOffscreenRecordingFinishEx1 ==
 
== CompleteOffscreenRecordingFinishEx1 ==
Takes two input u32s '''width'''/'''height''', an input u64 '''LayerHandle''' and two type-0x5 input buffers, returns a 0x20-byte output struct.
+
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 ==
Takes an input u64 '''LayerHandle''' and a type-0x5 input buffer, returns an output u64.
+
Takes an input u64 '''LayerHandle''' and a type-0x5 input buffer, returns an output u64 '''out_size'''.
   −
== GetOffscreenLayerError ==
+
Official sw enters a loop for handling the user-specified buffer:
Takes an input u64 '''LayerHandle''', no output.
+
* Waits on the Event originally loaded from [[#GetOffscreenLayerAudioEncodeReadyEvent]].
 +
* Uses the cmd with the current buffer_addr+pos and the remaining_size.
 +
* Updates the current pos and remaining_size with the '''out_size'''.
 +
* Repeats the loop until the remaining_size is 0.
    
== GetOffscreenLayerRecordingFinishReadyEvent ==
 
== GetOffscreenLayerRecordingFinishReadyEvent ==
Line 217: Line 256:     
= OffscreenRecordingParameter =
 
= OffscreenRecordingParameter =
This is a 0x80-byte struct.
+
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"
 +
|-
 +
! Offset || Size || Description || Default value
 +
|-
 +
| 0x0 || 0x10 || ? || 0
 +
|-
 +
| 0x10 || 0x4 || Unknown, must match 0x103. || 0x103
 +
|-
 +
| 0x14 || 0x4 || s32 VideoBitRate, 0 is invalid. || 8000000
 +
|-
 +
| 0x18 || 0x4 || s32 VideoWidth, must match 1280 or 1920. || 1280
 +
|-
 +
| 0x1C || 0x4 || s32 VideoHeight, must match 720 or 1080. || 720
 +
|-
 +
| 0x20 || 0x4 || s32 VideoFrameRate, must match 30 or 60. || 30
 +
|-
 +
| 0x24 || 0x4 || s32 VideoKeyFrameInterval, 0 is invalid. || 30
 +
|-
 +
| 0x28 || 0x4 || s32 AudioBitRate || 128000 ([5.0.0-5.1.0] 1536000)
 +
|-
 +
| 0x2C || 0x4 || s32 AudioSampleRate, 0 is invalid. || 48000
 +
|-
 +
| 0x30 || 0x4 || s32 AudioChannelCount, must match 2. || 2
 +
|-
 +
| 0x34 || 0x4 || "nn::audio::SampleFormat" AudioSampleFormat, must match 2. || 2
 +
|-
 +
| 0x38 || 0x4 || "nn::album::ImageOrientation" VideoImageOrientation. || 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).
    
= GameMovieId =
 
= GameMovieId =
 +
This is "nn::grcsrv::GameMovieId".
 +
 +
This is a 0x40-byte struct.
 +
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 226: Line 304:  
| 0x0 || 0x18 || Same as the last 0x18-bytes of [[Capture_services|AlbumEntry]].
 
| 0x0 || 0x18 || Same as the last 0x18-bytes of [[Capture_services|AlbumEntry]].
 
|-
 
|-
| 0x18 || 0x28 || Ignored by Album. Album clears this to 0 for the [[#BeginTrim]] input.
+
| 0x18 || 0x28 || Unused, always zero.
 
|}
 
|}
  −
This is "nn::grcsrv::GameMovieId". This is a 0x40-byte struct.
      
= IHOSBinderDriver =
 
= IHOSBinderDriver =

Navigation menu