dridri / OpenMaxIL-cpp

OpenMax IL C++ wrapper for RaspberryPi
MIT License
23 stars 5 forks source link

How to properly destruct #4

Closed cedricve closed 7 years ago

cedricve commented 7 years ago

Hello @dridri,

I wast just wondering what the proper way is to destruct the created components in this example. https://github.com/dridri/OpenMaxIL-cpp/blob/master/samples/camera_threaded.cpp

Is this enough?

state.running = false;

// -------------------------
// Cancel the record thread.

pthread_join(state.record_thid, NULL);

// -------------------------
// Cancel the preview thread.

pthread_join(state.preview_thid, NULL);

state.camera->SetCapturing( false );
state.camera->SetState(Component::StateIdle);
state.preview_encode->SetState(Component::StateIdle);
state.record_encode->SetState(Component::StateIdle);
delete state.preview_encode;
delete state.record_encode;
delete state.camera;

This is how I do it right now, https://github.com/kerberos-io/machinery/blob/develop/src/kerberos/capture/RaspiCamera.cpp#L236-L265.

It looks like it's working but (sometimes) after a restart, I get the same image all the time.

dridri commented 7 years ago

Indeed, this is the exact way to destroy the components, but I never seen a stall after restarting.. Try to call DestroyTunnel on all tunnels between setting states to Idle and destroying the components

cedricve commented 7 years ago

ok thanks, also I noticed the bcm_host_init();call. I was looking for the bcm_host_deinit();method but apparently that one isn't available. At the moment I'm calling this function at every restart, and that might be an issue as well.

https://github.com/kerberos-io/machinery/blob/develop/src/kerberos/capture/RaspiCamera.cpp#L186-L187

cedricve commented 7 years ago

Sorry for spamming this repo @dridri. I did further investigation with the different states, and after a couple of (2) restarts it gets completely locked, and crashes. When this error occurs I need to restart Raspberry Pi to resolve it. After the first restart everything keeps working as expected.

10/08/2017 08:14:25.841 INFO  [trivial] Starting capture device: RaspiCamera
CopyPort( OMX.broadcom.camera->70, OMX.broadcom.video_encode->200
Port 200: in 1/1 1843200 16 disabled,not pop.,not cont. 1280x960 1280x960 @20fps 20
===> types : 8[200] | 8[71]
Port 71: out 1/1 1843200 16 disabled,not pop.,not cont. 1280x960 1280x960 @20fps 20
Port 200: in 1/1 15360 16 disabled,not pop.,not cont. 160x64 160x64 @30fps 20
[OMX.broadcom.camera]Wating state to be 2
[OMX.broadcom.video_encode]Wating state to be 2
[OMX.broadcom.video_encode]Wating state to be 2
Wating port 70 to be 1
Wating port 200 to be 1
OMX_UseBuffer error 0x80001000 ! (state : 2)

Current flow to destruct goes as follows:

state.running = false;
pthread_join(state.record_thid, nullptr);
pthread_join(state.preview_thid, nullptr);

state.preview_encode->SetState(Component::StateIdle);
state.record_encode->SetState(Component::StateIdle);       
state.preview_encode->SetState(Component::StateInvalid);
state.record_encode->SetState(Component::StateInvalid);

state.camera->SetState(Component::StateIdle);
state.camera->SetState(Component::StateInvalid);
state.camera->DestroyTunnel(71);
state.camera->SetCapturing(false);

delete state.preview_encode;
delete state.record_encode;
delete state.camera;
dridri commented 7 years ago

hmm state.camera->SetCapturing(false) should be just after joining the threads. Except that, I don't see anything that causes this issue, I'm using myself the same code to stop video on my drone, and oftenly stop and restart the program without any problem

cedricve commented 7 years ago

Thanks. hmm, tried that before. I'll try to simulate with your examples.

dridri commented 7 years ago

I suppose that you already have updated to latest firmware and userland for your rpi ?

cedricve commented 7 years ago

yeah indeed, how recent is yours?

dridri commented 7 years ago

Quite old actually, it has two months. Does the same appears on rpi2/rpi3 ?

cedricve commented 7 years ago

Yes, tested on different devices so far RPi1, RPi0 and RPi2. Isn't there a way to simply call the component onexit() method?

cedricve commented 7 years ago

I think the issue I'm having is caused dueto not clearing the buffers.

// Finally, free remaining buffers
for ( OMX_U8* buf : mAllAllocatedBuffers ) {
    vcos_free( buf );
    printf( "Freed static buffer %p\n", buf );
}
mAllAllocatedBuffers.clear();
dridri commented 7 years ago

Here you go 61327ea

cedricve commented 7 years ago

Works as expected. Main issue was caused due to 128MB of GPU mem. Increased it to 196MB and now working as expected.