puhitaku / mtplvcap

Nikon to USB Webcam. Supports older models that Nikon WU does not. Windows/macOS/Linux. No HDMI capture dongle is needed. Ask me on Twitter @puhitaku
https://twitter.com/puhitaku
Other
258 stars 19 forks source link

Not working on D5000 #6

Closed puhitaku closed 4 years ago

puhitaku commented 4 years ago

D5000, macOS 10.15.6 で無限に WARN lv: workerLV: failed to start live view: InvalidStatus (battery level is low?) が出ちゃう

D5000 is similar to D90: https://github.com/dukus/digiCamControl/blob/93a3634459915a66c448a1f20301536004e02781/CameraControl.Devices/CameraDeviceManager.cs#L169

The difference is the header size only: https://github.com/dukus/digiCamControl/blob/master/CameraControl.Devices/Nikon/NikonD90.cs#L57

puhitaku commented 4 years ago

The header size is fixed for now: https://github.com/puhitaku/mtplvcap/blob/master/mtp/nikon.go#L10

puhitaku commented 4 years ago

mtplvcap does not check if the camera is ready or not. A reference implementation is here: https://github.com/dukus/digiCamControl/blob/master/CameraControl.Devices/Nikon/NikonBase.cs#L2414

Perhaps it tells us what is happening.

rch850 commented 4 years ago

I added log as shown below:

func (s *LVServer) startLiveView() error {
    s.mtpLock.Lock()
    defer s.mtpLock.Unlock()

    const CONST_CMD_DeviceReady = 0x90C8

    err2 := s.dev.RunTransactionWithNoParams(CONST_CMD_DeviceReady)
    log.LV.Infof("deviceReady: %v", err2)

It just prints INFO lv: deviceReady: <nil>.

puhitaku commented 4 years ago

@rch850 Thanks! At least D5000 seems to be ready to do something.

I've found that there's a more detailed read operation: https://github.com/dukus/digiCamControl/blob/master/CameraControl.Devices/Nikon/NikonBase.cs#L2512

I've pushed a new branch fix/d5000 that includes DeviceReady check you suggested and reason investigation ported from above. Take a look and please try running it.

puhitaku commented 4 years ago

Memo: an interface like Camera should be introduced to deal with the difference between models

rch850 commented 4 years ago

Thank you for the great branch! It prints following logs:

[0001] ERROR lv: failed to start live view (InvalidStatus). Investigating the reason...
[0001]  WARN lv: workerLV: failed to start live view, reason: recording destination is the card
puhitaku commented 4 years ago

According to the digiCamControl forum, recording destination is the card means what it says -- captured frames will be saved in an SD card, which might not be available at present in your D5000.

I did some experiments to reproduce the error:

None of them reproduced the recording destination is the card error.

Meanwhile in digiCamControl, it tells the camera where to save the frames in 1. the card, or 2. the RAM. I think that D5300 fallbacks to RAM capture when the SD card is not available, while D5000 does not.

So I've pushed yet another improvement that ensures the recording destination. startLiveView() will switch from SD to RAM explicitly. After switching it, the camera LCD will show "PC" instead of the available capacity of the SD card.

Screenshot_20200806_020202

Please pull fix/d5000 and try it!

rch850 commented 4 years ago

Thanks again! Finally my shutter opened!

https://twitter.com/rch850/status/1291067408635924480?s=20

image

However, it does not appear as a virtual camera yet. I saw this error ERROR mtp: fatal error LIBUSB_ERROR_TIMEOUT; closing connection.

To get details, I have changed this line;

https://github.com/puhitaku/mtplvcap/blob/a8ecd9de3d74479d12a6bf80af7e1bf6a2d8a059/mtp/device_direct.go#L275

into following;

            log.MTP.Errorf("fatal error %v while running operation %v; closing connection.", err, OC_names[int(req.Code)])

Logs are following:

[0000]  INFO main: started
[0002] ERROR mtp: fatal error LIBUSB_ERROR_TIMEOUT while running operation MTP_WMPPD_ReportAddedDeletedItems; closing connection.
[0002]  WARN lv: workerLV: failed to start live view: LIBUSB_ERROR_TIMEOUT
[0002]  WARN lv: workerLV: failed to get live view status: mtp: cannot run operation GetDevicePropValue, device is not open
[0002]  WARN lv: frameCaptor: failed to obtain an image: mtp: cannot run operation MTP_WMPPD_PlaylistObjectPref, device is not open
[0003]  WARN lv: workerLV: failed to get live view status: mtp: cannot run operation GetDevicePropValue, device is not open
[0003]  WARN lv: frameCaptor: failed to obtain an image: mtp: cannot run operation MTP_WMPPD_PlaylistObjectPref, device is not open

MTP_WMPPD_ReportAddedDeletedItems is 0x9201 so it seems to be OC_NIKON_StartLiveView.

Oh it's time to sleep... see you again 😪

puhitaku commented 4 years ago

Yay! 👏

Suspicious timeout

It seems that the camera takes a long time (longer than D5300) to open the shutter. (Thanks for the video! It's really helpful.) I suspect that the timeout of USB communication is too short.

https://github.com/puhitaku/mtplvcap/blob/db06e9feb6ff8defc6a23ad3af969a242962fce4/mtp/select.go#L185

The unit is milliseconds.

How about increasing it like:

--- a/mtp/select.go
+++ b/mtp/select.go
@@ -182,6 +182,6 @@ func SelectDeviceDirect(vid, pid uint16) (*DeviceDirect, error) {
                }
        }

-       dev.Timeout = 1000
+       dev.Timeout = 3000
        return dev, nil
 }

Another improvement

BTW I've pushed more commits to identify camera models. Previously, the header size of the live view frame was constant (384 bytes) and unable to parse the frames of D5000. Now it's variable and it'll be 128 bytes for D5000. Please watch the debug log -debug server and ensure it detects your camera.

puhitaku commented 4 years ago

@rch850 any update? I'd like to know if it works 👀

rch850 commented 4 years ago

It worked finally 🎉

mtplvcap-d5000

Model detection seems to be working too.

[0000] DEBUG lv: manufacturer = NIKON, product = NIKON DSC D5000, serialnumber = ***masked****
[0000] DEBUG lv: model matched: D5000
[0001] DEBUG lv: current recording media: SDRAM

Thanks a lot!

puhitaku commented 4 years ago

やった〜〜〜〜〜〜 🎉 🎉 🎉 🎉 🎉

I'm surprised at the resolution it reports. Could you check if the incoming images are really 4288 x 2848 or not? And let me know what's the real resolution of them.

rch850 commented 4 years ago

It is 620x426.

image

puhitaku commented 4 years ago

OK, thank you for cooperating with me! I've opened a PR #7 and now closing this.