mirror of
				https://github.com/Tha14/toxic.git
				synced 2025-11-04 16:16:52 +01:00 
			
		
		
		
	Refactoring and fix related to invite callback not being fired
This commit is contained in:
		@@ -1,20 +1,12 @@
 | 
			
		||||
# Variables for audio call support
 | 
			
		||||
AUDIO_LIBS = libtoxav openal
 | 
			
		||||
VIDEO_LIBS = libtoxav opencv
 | 
			
		||||
AUDIO_CFLAGS = -DAUDIO
 | 
			
		||||
VIDEO_CFLAGS = -DVIDEO
 | 
			
		||||
ifneq (, $(findstring audio_device.o, $(OBJ)))
 | 
			
		||||
    AUDIO_OBJ = audio_call.o
 | 
			
		||||
else
 | 
			
		||||
    AUDIO_OBJ = audio_call.o audio_device.o
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq (, $(findstring video_device.o, $(OBJ)))
 | 
			
		||||
	VIDEO_OBJ = video_call.o
 | 
			
		||||
else
 | 
			
		||||
	VIDEO_OBJ = video_call.o video_device.o
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Check if we can build audio support
 | 
			
		||||
CHECK_AUDIO_LIBS = $(shell pkg-config --exists $(AUDIO_LIBS) || echo -n "error")
 | 
			
		||||
ifneq ($(CHECK_AUDIO_LIBS), error)
 | 
			
		||||
@@ -26,17 +18,4 @@ else ifneq ($(MAKECMDGOALS), clean)
 | 
			
		||||
    $(warning WARNING -- Toxic will be compiled without audio support)
 | 
			
		||||
    $(warning WARNING -- You need these libraries for audio support)
 | 
			
		||||
    $(warning WARNING -- $(MISSING_AUDIO_LIBS))
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Check if we can build video support
 | 
			
		||||
CHECK_VIDEO_LIBS = $(shell pkg-config --exists $VIDEO_LIBS) || echo -n "error")
 | 
			
		||||
ifneq ($(CHECK_VIDEO_LIBS), error)
 | 
			
		||||
    LIBS += $(VIDEO_LIBS)
 | 
			
		||||
    CFLAGS += $(VIDEO_CFLAGS)
 | 
			
		||||
    OBJ += $(VIDEO_OBJ)
 | 
			
		||||
else ifneq ($(MAKECMDGOALS), clean)
 | 
			
		||||
    MISSING_VIDEO_LIBS = $(shell for lib in $(VIDEO_LIBS) ; do if ! pkg-config --exists $$lib ; then echo $$lib ; fi ; done)
 | 
			
		||||
    $(warning WARNING -- Toxic will be compiled without video support)
 | 
			
		||||
    $(warning WARNING -- You need these libraries for video support)
 | 
			
		||||
    $(warning WARNING -- $(MISSING_VIDEO_LIBS))
 | 
			
		||||
endif
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
CC=gcc
 | 
			
		||||
 | 
			
		||||
capture_playback: capture_playback.c
 | 
			
		||||
	$(CC) -o capture_playback capture_playback.c -lopencv_core -lopencv_highgui
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -f capture_playback *.o
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
gcc -o example.exe -I C:/opencv/build/include -L C:/opencv/build/x86/vc12/lib capture_playback.c -lopencv_core2411d -lopencv_highgui2411d -luuid -strmiids -lole32 -loleaut32
 | 
			
		||||
@@ -1,156 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <opencv2/core/core.hpp>
 | 
			
		||||
#include <opencv2/highgui/highgui.hpp>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <linux/videodev2.h>
 | 
			
		||||
#endif /* __linux __ */
 | 
			
		||||
 | 
			
		||||
#ifdef __WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <dshow.h>
 | 
			
		||||
 | 
			
		||||
#pragma comment(lib, "strmiids.lib")
 | 
			
		||||
#endif /* __WIN32 */
 | 
			
		||||
 | 
			
		||||
#define MAX_DEVICES 32
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    const char *device_names[MAX_DEVICES];
 | 
			
		||||
    int amt_cameras = 0;
 | 
			
		||||
    int i = 0;
 | 
			
		||||
 | 
			
		||||
    #ifdef __linux__
 | 
			
		||||
    // Enumerate video capture devices
 | 
			
		||||
    while(i <= MAX_DEVICES)
 | 
			
		||||
    {
 | 
			
		||||
        int fd;
 | 
			
		||||
        struct v4l2_capability video_cap;
 | 
			
		||||
        char device_address[256];
 | 
			
		||||
        snprintf(device_address, sizeof device_address, "/dev/video%d",i);
 | 
			
		||||
 | 
			
		||||
        if((fd = open(device_address, O_RDONLY)) == -1) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            // Query capture device information
 | 
			
		||||
            if(ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1)
 | 
			
		||||
                perror("cam_info: Can't get capabilities");
 | 
			
		||||
            else {
 | 
			
		||||
                //printf("Card:\t\t '%s'\n", video_cap.card);
 | 
			
		||||
                int name_length = sizeof(video_cap.card);
 | 
			
		||||
                char* name = (char*)malloc(name_length+1);
 | 
			
		||||
                name = video_cap.card;
 | 
			
		||||
                device_names[i] = name;
 | 
			
		||||
            }
 | 
			
		||||
            close(fd);
 | 
			
		||||
            amt_cameras = i;
 | 
			
		||||
        }
 | 
			
		||||
        ++i;
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* __linux__ */
 | 
			
		||||
    
 | 
			
		||||
    #ifdef __WIN32
 | 
			
		||||
    HRESULT hr;
 | 
			
		||||
    CoInitialize(NULL);
 | 
			
		||||
    ICreateDevEnum *pSysDevEnum = NULL;
 | 
			
		||||
    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum, (void**)&pSysDevEnum);
 | 
			
		||||
    if(FAILED(hr)) {
 | 
			
		||||
        printf("CoCreateInstance failed()\n");
 | 
			
		||||
    }
 | 
			
		||||
    // Obtain a class enumerator for the video compressor category.
 | 
			
		||||
    IEnumMoniker *pEnumCat = NULL;
 | 
			
		||||
    hr = pSysDevEnum->lpVtbl->CreateClassEnumerator(pSysDevEnum, &CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
 | 
			
		||||
    if(hr != S_OK) {
 | 
			
		||||
        pSysDevEnum->lpVtbl->Release(pSysDevEnum);
 | 
			
		||||
        printf("CreateClassEnumerator failed()\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IMoniker *pMoniker = NULL;
 | 
			
		||||
 | 
			
		||||
    ULONG cFetched;
 | 
			
		||||
    while(pEnumCat->lpVtbl->Next(pEnumCat, 1, &pMoniker, &cFetched) == S_OK && i <= MAX_DEVICES) {
 | 
			
		||||
        IPropertyBag *pPropBag;
 | 
			
		||||
        hr = pMoniker->lpVtbl->BindToStorage(pMoniker, 0, 0, &IID_IPropertyBag, (void **)&pPropBag);
 | 
			
		||||
        if(SUCCEEDED(hr)) {
 | 
			
		||||
            // To retrieve the filter's friendly name, do the following:
 | 
			
		||||
            VARIANT varName;
 | 
			
		||||
            VariantInit(&varName);
 | 
			
		||||
            hr = pPropBag->lpVtbl->Read(pPropBag, L"FriendlyName", &varName, 0);
 | 
			
		||||
            if (SUCCEEDED(hr)) {
 | 
			
		||||
                if(varName.vt == VT_BSTR) {
 | 
			
		||||
                    //printf("friendly name: %ls\n", varName.bstrVal);
 | 
			
		||||
                    int name_length = wcslen(varName.bstrVal);
 | 
			
		||||
                    char* name = (char*)malloc(name_length + 1);
 | 
			
		||||
                    wcstombs(name, varName.bstrVal, name_length + 1);
 | 
			
		||||
                    device_names[i] = name;
 | 
			
		||||
                    //free(name);
 | 
			
		||||
                } else {
 | 
			
		||||
                    //printf("unfriendly name\n");
 | 
			
		||||
                    device_names[i] = "Unknown Device";
 | 
			
		||||
                }
 | 
			
		||||
                ++i;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            VariantClear(&varName);
 | 
			
		||||
            pPropBag->lpVtbl->Release(pPropBag);
 | 
			
		||||
        }
 | 
			
		||||
        pMoniker->lpVtbl->Release(pMoniker);
 | 
			
		||||
    }
 | 
			
		||||
    amt_cameras = i-1;
 | 
			
		||||
    pEnumCat->lpVtbl->Release(pEnumCat);
 | 
			
		||||
    pSysDevEnum->lpVtbl->Release(pSysDevEnum);
 | 
			
		||||
    
 | 
			
		||||
    #endif /* __WIN32 */
 | 
			
		||||
 | 
			
		||||
    // TODO: Windows video capture enumeration
 | 
			
		||||
 | 
			
		||||
    // Obtain user camera selection
 | 
			
		||||
    int select_camera = -1;
 | 
			
		||||
    while(select_camera < 0 || select_camera > amt_cameras || select_camera >= MAX_DEVICES) {
 | 
			
		||||
        printf("Select a camera from %d cameras...\n", amt_cameras+1);
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        // Print all collected devices
 | 
			
		||||
        while(i <= amt_cameras)
 | 
			
		||||
        {
 | 
			
		||||
            printf("%d: %s\n", i, device_names[i]);
 | 
			
		||||
            ++i;
 | 
			
		||||
        }
 | 
			
		||||
        printf("\nCamera #:");
 | 
			
		||||
        scanf(" %d", &select_camera);
 | 
			
		||||
    }
 | 
			
		||||
    printf("\nPress spacebar to exit.\n\n");
 | 
			
		||||
 | 
			
		||||
    // Initialize window
 | 
			
		||||
    cvNamedWindow("Camera", 1);
 | 
			
		||||
    // Initialize camera
 | 
			
		||||
    CvCapture* capture = cvCreateCameraCapture(select_camera);
 | 
			
		||||
    char key = 0;
 | 
			
		||||
    // Run until spacebar is pressed
 | 
			
		||||
    while(key != 32 && capture != NULL) {
 | 
			
		||||
        // Obtains frame from camera and show it on window
 | 
			
		||||
        IplImage* frame = cvQueryFrame(capture);
 | 
			
		||||
        cvShowImage("Camera", frame);
 | 
			
		||||
        key = cvWaitKey(10);
 | 
			
		||||
    } 
 | 
			
		||||
    
 | 
			
		||||
    // Free device list allocations
 | 
			
		||||
    i = 0;
 | 
			
		||||
    while(i <= amt_cameras)
 | 
			
		||||
    {
 | 
			
		||||
        free(device_names[i]);
 | 
			
		||||
        ++i;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Collapse camera and window
 | 
			
		||||
    cvReleaseCapture(&capture);
 | 
			
		||||
    cvDestroyWindow("Camera");
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -137,7 +137,7 @@ static void print_err (ToxWindow *self, const char *error_str)
 | 
			
		||||
ToxAV *init_audio(ToxWindow *self, Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    TOXAV_ERR_NEW error;
 | 
			
		||||
 | 
			
		||||
    CallContrl.errors = ae_None;
 | 
			
		||||
    CallContrl.window = self;
 | 
			
		||||
 | 
			
		||||
    CallContrl.audio_enabled = true;
 | 
			
		||||
@@ -150,8 +150,6 @@ ToxAV *init_audio(ToxWindow *self, Tox *tox)
 | 
			
		||||
    CallContrl.video_frame_duration = 0;
 | 
			
		||||
    CallContrl.audio_channels = 1;
 | 
			
		||||
 | 
			
		||||
    CallContrl.errors = ae_None;
 | 
			
		||||
 | 
			
		||||
    memset(CallContrl.calls, 0, sizeof(CallContrl.calls));
 | 
			
		||||
 | 
			
		||||
    /* Streaming stuff from core */
 | 
			
		||||
@@ -313,16 +311,16 @@ void callstate_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_
 | 
			
		||||
            CallContrl.pending_call = false;
 | 
			
		||||
            callback_call_rejected(CallContrl.av, friend_number, &CallContrl);
 | 
			
		||||
        } else {
 | 
			
		||||
            callback_call_ended(CallContrl.av, friend_number, &CallContrl);
 | 
			
		||||
            callback_call_ended(av, friend_number, &CallContrl);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if( state == TOXAV_FRIEND_CALL_STATE_ERROR ) {
 | 
			
		||||
            line_info_add(window, NULL, NULL, NULL, SYS_MSG, 0, 0, "ToxAV callstate error!");
 | 
			
		||||
            CallContrl.pending_call = false;
 | 
			
		||||
            callback_call_ended(CallContrl.av, friend_number, &CallContrl);
 | 
			
		||||
            callback_call_ended(av, friend_number, &CallContrl);
 | 
			
		||||
        } else {
 | 
			
		||||
            CallContrl.pending_call = false;
 | 
			
		||||
            callback_call_started(CallContrl.av, friend_number, &CallContrl);
 | 
			
		||||
            callback_call_started(av, friend_number, &CallContrl);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -378,7 +376,7 @@ void callback_recv_invite ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onInvite != NULL && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onInvite(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onInvite(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -391,7 +389,7 @@ void callback_recv_ringing ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onRinging != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onRinging(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onRinging(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
void callback_recv_starting ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
@@ -402,7 +400,7 @@ void callback_recv_starting ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onStarting != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onStarting(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onStarting(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
            if ( 0 != start_transmission(&windows[i], &CallContrl.calls[friend_number])) {/* YEAH! */
 | 
			
		||||
                line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0 , "Error starting transmission!");
 | 
			
		||||
            }
 | 
			
		||||
@@ -418,7 +416,7 @@ void callback_recv_ending ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onEnding != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onEnding(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onEnding(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    stop_transmission(&CallContrl.calls[friend_number], friend_number);
 | 
			
		||||
@@ -432,7 +430,7 @@ void callback_call_started ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onStart != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onStart(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onStart(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
            if ( 0 != start_transmission(&windows[i], &CallContrl.calls[friend_number]) ) {/* YEAH! */
 | 
			
		||||
                line_info_add(&windows[i], NULL, NULL, NULL, SYS_MSG, 0, 0, "Error starting transmission!");
 | 
			
		||||
                return;
 | 
			
		||||
@@ -448,7 +446,7 @@ void callback_call_canceled ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onCancel != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onCancel(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onCancel(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /* In case call is active */
 | 
			
		||||
@@ -464,7 +462,7 @@ void callback_call_rejected ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onReject != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onReject(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onReject(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -477,7 +475,7 @@ void callback_call_ended ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onEnd != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onEnd(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onEnd(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    stop_transmission(&CallContrl.calls[friend_number], friend_number);
 | 
			
		||||
@@ -492,7 +490,7 @@ void callback_requ_timeout ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onRequestTimeout != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onRequestTimeout(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onRequestTimeout(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
void callback_peer_timeout ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
@@ -504,7 +502,7 @@ void callback_peer_timeout ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
    int i;
 | 
			
		||||
    for (i = 0; i < MAX_WINDOWS_NUM; ++i)
 | 
			
		||||
        if (windows[i].onPeerTimeout != NULL && windows[i].is_call && windows[i].num == friend_number) {
 | 
			
		||||
            windows[i].onPeerTimeout(&windows[i], cc->av, friend_number, cc->call_state);
 | 
			
		||||
            windows[i].onPeerTimeout(&windows[i], av, friend_number, cc->call_state);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    stop_transmission(&CallContrl.calls[friend_number], friend_number);
 | 
			
		||||
@@ -512,7 +510,7 @@ void callback_peer_timeout ( void* av, uint32_t friend_number, void* arg )
 | 
			
		||||
     * actions that one can possibly take on timeout
 | 
			
		||||
     */
 | 
			
		||||
    TOXAV_ERR_CALL_CONTROL error;
 | 
			
		||||
    bool call_running = toxav_call_control(cc->av, friend_number, TOXAV_CALL_CONTROL_CANCEL, &error);
 | 
			
		||||
    bool call_running = toxav_call_control(av, friend_number, TOXAV_CALL_CONTROL_CANCEL, &error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// void callback_media_change(void* av, int32_t friend_number, void* arg)
 | 
			
		||||
@@ -584,7 +582,7 @@ void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
 | 
			
		||||
        goto on_error;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool call_running = toxav_answer(CallContrl.av, self->num, 48, 0, &error);
 | 
			
		||||
    bool call_running = toxav_answer(CallContrl.av, self->num, CallContrl.audio_bit_rate, CallContrl.video_bit_rate, &error);
 | 
			
		||||
 | 
			
		||||
    if ( !call_running ) {
 | 
			
		||||
        if ( error == TOXAV_ERR_ANSWER_FRIEND_NOT_CALLING ) error_str = "No incoming call!";
 | 
			
		||||
@@ -671,7 +669,6 @@ void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
 | 
			
		||||
        call_running = toxav_call_control(CallContrl.av, self->num, TOXAV_CALL_CONTROL_CANCEL, &error);
 | 
			
		||||
        callback_call_ended(CallContrl.av, self->num, &CallContrl);
 | 
			
		||||
    }
 | 
			
		||||
    self->is_call = call_running;
 | 
			
		||||
 | 
			
		||||
    if ( error != TOXAV_ERR_CALL_CONTROL_OK ) {
 | 
			
		||||
        if ( error == TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION ) error_str = "Cannot hangup in invalid state!";
 | 
			
		||||
 
 | 
			
		||||
@@ -101,12 +101,6 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
 | 
			
		||||
    { "/mute"       },
 | 
			
		||||
    { "/sense"      },
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
 | 
			
		||||
    { "/enablevid"      },
 | 
			
		||||
    { "/disablevid"     },
 | 
			
		||||
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,10 +41,6 @@ void cmd_cancel(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZ
 | 
			
		||||
void cmd_ccur_device(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
 | 
			
		||||
void cmd_mute(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
 | 
			
		||||
void cmd_sense(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
void cmd_enablevid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
 | 
			
		||||
void cmd_disablevid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
 | 
			
		||||
#endif /* #define CHAT_COMMANDS_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -77,10 +77,6 @@ static struct cmd_func chat_commands[] = {
 | 
			
		||||
    { "/hangup",    cmd_hangup      },
 | 
			
		||||
    { "/mute",      cmd_mute        },
 | 
			
		||||
    { "/sense",     cmd_sense       },
 | 
			
		||||
//#ifdef VIDEO
 | 
			
		||||
    //{ "/enablevid", cmd_enablevid   },
 | 
			
		||||
    //{ "/disablevid",cmd_disablevid  },
 | 
			
		||||
//#endif /* VIDEO */
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
    { NULL,         NULL            },
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1054,10 +1054,9 @@ static void friendlist_onAV(ToxWindow *self, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    Tox *m = toxav_get_tox(av);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (Friends.list[friend_number].chatwin == -1) {
 | 
			
		||||
        if (get_num_active_windows() < MAX_WINDOWS_NUM) {
 | 
			
		||||
            //line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "List number %d", Friends.list[friend_number].num);
 | 
			
		||||
            if(state != TOXAV_FRIEND_CALL_STATE_FINISHED) {
 | 
			
		||||
                Friends.list[friend_number].chatwin = add_window(m, new_chat(m, Friends.list[friend_number].num));
 | 
			
		||||
                set_active_window(Friends.list[friend_number].chatwin);
 | 
			
		||||
@@ -1108,7 +1107,6 @@ ToxWindow new_friendlist(void)
 | 
			
		||||
    ret.onRequestTimeout = &friendlist_onAV;
 | 
			
		||||
    ret.onPeerTimeout = &friendlist_onAV;
 | 
			
		||||
 | 
			
		||||
    //ret.num = -1;
 | 
			
		||||
    ret.is_call = false;
 | 
			
		||||
    ret.device_selection[0] = ret.device_selection[1] = -1;
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								src/toxic.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/toxic.c
									
									
									
									
									
								
							@@ -55,7 +55,6 @@
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "notify.h"
 | 
			
		||||
#include "audio_device.h"
 | 
			
		||||
#include "video_device.h"
 | 
			
		||||
#include "message_queue.h"
 | 
			
		||||
#include "execute.h"
 | 
			
		||||
#include "term_mplex.h"
 | 
			
		||||
@@ -66,9 +65,6 @@
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO
 | 
			
		||||
#include "audio_call.h"
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
#include "video_call.h"
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
ToxAV *av;
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
 | 
			
		||||
@@ -135,10 +131,6 @@ void exit_toxic_success(Tox *m)
 | 
			
		||||
    terminate_audio();
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
    terminate_video();
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
 | 
			
		||||
    free(DATA_FILE);
 | 
			
		||||
    free(BLOCK_FILE);
 | 
			
		||||
    free(user_settings);
 | 
			
		||||
@@ -848,7 +840,7 @@ void *thread_audio(void *data)
 | 
			
		||||
        toxav_iterate(av);
 | 
			
		||||
        pthread_mutex_unlock(&Winthread.lock);
 | 
			
		||||
 | 
			
		||||
        usleep(2 * 1000);
 | 
			
		||||
        usleep(toxav_iteration_interval(av) * 1000);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
#endif  /* AUDIO */
 | 
			
		||||
@@ -1139,11 +1131,6 @@ int main(int argc, char *argv[])
 | 
			
		||||
#ifdef AUDIO
 | 
			
		||||
 | 
			
		||||
    av = init_audio(prompt, m);
 | 
			
		||||
    
 | 
			
		||||
//#ifdef VIDEO
 | 
			
		||||
//   av = init_video(prompt, m, av);
 | 
			
		||||
//
 | 
			
		||||
//#endif /* VIDEO*/
 | 
			
		||||
 | 
			
		||||
    /* audio thread */
 | 
			
		||||
    if (pthread_create(&audio_thread.tid, NULL, thread_audio, (void *) av) != 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
/*  video_call.c
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014 Toxic All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of Toxic.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "toxic.h"
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
#include "video_call.h"
 | 
			
		||||
#include "video_device.h"
 | 
			
		||||
#include "chat_commands.h"
 | 
			
		||||
#include "global_commands.h"
 | 
			
		||||
#include "line_info.h"
 | 
			
		||||
#include "notify.h"
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <curses.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define cbend pthread_exit(NULL)
 | 
			
		||||
 | 
			
		||||
#define MAX_CALLS 10
 | 
			
		||||
 | 
			
		||||
ToxAV *init_video(ToxWindow *self, Tox *tox, ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void terminate_video()
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int start_video_transmission(ToxWindow *self, Call *call)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int stop_video_transmission(Call *call, int friend_number)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Commands from chat_commands.h
 | 
			
		||||
 */
 | 
			
		||||
void cmd_enablevid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
 | 
			
		||||
{
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmd_disablevid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
 | 
			
		||||
{
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
/*  video_call.h
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014 Toxic All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of Toxic.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef VIDEO_H
 | 
			
		||||
#define VIDEO_H
 | 
			
		||||
 | 
			
		||||
#include <tox/toxav.h>
 | 
			
		||||
 | 
			
		||||
#include "audio_call.h"
 | 
			
		||||
#include "video_device.h"
 | 
			
		||||
 | 
			
		||||
typedef enum _VideoError {
 | 
			
		||||
    ve_None = 0,
 | 
			
		||||
    ve_StartingCaptureDevice = 1 << 0,
 | 
			
		||||
    ve_StartingOutputDevice = 1 << 1,
 | 
			
		||||
    ve_StartingCoreVideo = 1 << 2
 | 
			
		||||
} VideoError;
 | 
			
		||||
 | 
			
		||||
/* You will have to pass pointer to first member of 'windows' declared in windows.c */
 | 
			
		||||
ToxAV *init_video(ToxWindow *self, Tox *tox, ToxAV *av);
 | 
			
		||||
void terminate_video();
 | 
			
		||||
int start_video_transmission(ToxWindow *self, Call *call);
 | 
			
		||||
int stop_video_transmission(Call *call, int friend_number);
 | 
			
		||||
void stop_current_video_call(ToxWindow *self);
 | 
			
		||||
 | 
			
		||||
 #endif /* VIDEO_H */
 | 
			
		||||
@@ -1,274 +0,0 @@
 | 
			
		||||
/*  video_device.c
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014 Toxic All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of Toxic.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "video_device.h"
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
#include "video_call.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "line_info.h"
 | 
			
		||||
#include "settings.h"
 | 
			
		||||
 | 
			
		||||
#include <opencv2/core/core.hpp>
 | 
			
		||||
#include <opencv2/highgui/highgui.hpp>
 | 
			
		||||
#include <vpx/vpx_image.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <linux/videodev2.h>
 | 
			
		||||
#endif /* __linux __ */
 | 
			
		||||
 | 
			
		||||
#ifdef __WIN32
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#include <dshow.h>
 | 
			
		||||
 | 
			
		||||
#pragma comment(lib, "strmiids.lib")
 | 
			
		||||
#endif /* __WIN32 */
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#define inline__ inline __attribute__((always_inline))
 | 
			
		||||
 | 
			
		||||
extern struct user_settings *user_settings;
 | 
			
		||||
 | 
			
		||||
 typedef struct VideoDevice {
 | 
			
		||||
    CvCapture* dhndl;
 | 
			
		||||
    char* window;
 | 
			
		||||
    IplImage* frame;
 | 
			
		||||
    int32_t call_idx;
 | 
			
		||||
 | 
			
		||||
    uint32_t ref_count;
 | 
			
		||||
    int32_t selection;
 | 
			
		||||
    pthread_mutex_t mutex[1];
 | 
			
		||||
    uint16_t frame_width;
 | 
			
		||||
    uint16_t frame_height;
 | 
			
		||||
 } VideoDevice;
 | 
			
		||||
 | 
			
		||||
const char *default_video_device_names[2];
 | 
			
		||||
const char *video_device_names[2][MAX_DEVICES];
 | 
			
		||||
static int video_device_size[2];
 | 
			
		||||
VideoDevice *video_device_running[2][MAX_DEVICES] = {{NULL}};
 | 
			
		||||
uint32_t primary_video_device[2];
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
static ToxAV* av = NULL;
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
 | 
			
		||||
pthread_mutex_t video_mutex;
 | 
			
		||||
 | 
			
		||||
bool video_thread_running = true,
 | 
			
		||||
      video_thread_paused =  true;
 | 
			
		||||
 | 
			
		||||
void* video_thread_poll(void*);
 | 
			
		||||
/* Meet devices */
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
VideoDeviceError init_video_devices(ToxAV* av_)
 | 
			
		||||
#else
 | 
			
		||||
VideoDeviceError init_video_devices()
 | 
			
		||||
#endif /* AUDIO */
 | 
			
		||||
{
 | 
			
		||||
    video_device_size[input] = 0;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    /* Enumerate video capture devices using v4l */
 | 
			
		||||
    for(i = 0; i <= MAX_DEVICES; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        int fd;
 | 
			
		||||
        struct v4l2_capability video_cap;
 | 
			
		||||
        char device_address[256];
 | 
			
		||||
        snprintf(device_address, sizeof device_address, "/dev/video%d",i);
 | 
			
		||||
 | 
			
		||||
        if((fd = open(device_address, O_RDONLY)) == -1) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            // Query capture device information
 | 
			
		||||
            if(ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1)
 | 
			
		||||
                perror("cam_info: Can't get capabilities");
 | 
			
		||||
            else {
 | 
			
		||||
                int name_length = sizeof(video_cap.card);
 | 
			
		||||
                char* name = (char*)malloc(name_length+1);
 | 
			
		||||
                name = video_cap.card;
 | 
			
		||||
                video_device_names[input][i] = name;
 | 
			
		||||
            }
 | 
			
		||||
            close(fd);
 | 
			
		||||
            video_device_size[input] = i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* __linux__ */
 | 
			
		||||
    
 | 
			
		||||
    /* Start poll thread */
 | 
			
		||||
    if (pthread_mutex_init(&video_mutex, NULL) != 0)
 | 
			
		||||
        return vde_InternalError;
 | 
			
		||||
    
 | 
			
		||||
    pthread_t thread_id;
 | 
			
		||||
    if ( pthread_create(&thread_id, NULL, video_thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0) 
 | 
			
		||||
        return vde_InternalError;    
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
    av = av_;
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
 | 
			
		||||
    return (VideoDeviceError) vde_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VideoDeviceError terminate_video_devices()
 | 
			
		||||
{
 | 
			
		||||
    /* Cleanup if needed */
 | 
			
		||||
    video_thread_running = false;
 | 
			
		||||
    usleep(20000);
 | 
			
		||||
    
 | 
			
		||||
    if (pthread_mutex_destroy(&video_mutex) != 0)
 | 
			
		||||
        return (VideoDeviceError) vde_InternalError;
 | 
			
		||||
    
 | 
			
		||||
    return (VideoDeviceError) vde_None;    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* video_thread_poll(void* arg)
 | 
			
		||||
{
 | 
			
		||||
    (void)arg;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    while(video_thread_running)
 | 
			
		||||
    {
 | 
			
		||||
        if (video_thread_paused) usleep(10000); /* Wait for unpause. */
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            for (i = 0; i < video_device_size[input]; ++i)
 | 
			
		||||
            {
 | 
			
		||||
                pthread_mutex_lock(&video_mutex);
 | 
			
		||||
 | 
			
		||||
                if (video_device_running[input][i] != NULL)
 | 
			
		||||
                {
 | 
			
		||||
                    /* Capture video frame data of input device */
 | 
			
		||||
                    video_device_running[input][i]->frame = cvQueryFrame(video_device_running[input][i]->dhndl);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
            }
 | 
			
		||||
            usleep(5000);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_exit(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VideoDeviceError set_primary_video_device(DeviceType type, int32_t selection)
 | 
			
		||||
{
 | 
			
		||||
    if (video_device_size[type] <= selection || selection < 0) return (VideoDeviceError) vde_InvalidSelection;
 | 
			
		||||
    primary_video_device[type] = selection;
 | 
			
		||||
    
 | 
			
		||||
    return (VideoDeviceError) vde_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VideoDeviceError open_video_device(DeviceType type, int32_t selection, uint32_t* device_idx)
 | 
			
		||||
{
 | 
			
		||||
    if (video_device_size[type] <= selection || selection < 0) return vde_InvalidSelection;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&video_mutex);
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    for (i = 0; i < MAX_DEVICES; ++i) { /* Check if any device has the same selection */
 | 
			
		||||
        if ( video_device_running[type][i] && video_device_running[type][i]->selection == selection ) {
 | 
			
		||||
 | 
			
		||||
            video_device_running[type][*device_idx] = video_device_running[type][i];
 | 
			
		||||
            video_device_running[type][i]->ref_count++;
 | 
			
		||||
 | 
			
		||||
            pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
            return vde_None;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VideoDevice* device = video_device_running[type][*device_idx] = calloc(1, sizeof(VideoDevice));
 | 
			
		||||
    device->selection = selection;
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_init(device->mutex, NULL) != 0) {
 | 
			
		||||
        free(device);
 | 
			
		||||
        pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
        return vde_InternalError;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (type  == input) {
 | 
			
		||||
        device->window = video_device_names[input][selection];
 | 
			
		||||
        cvNamedWindow(device->window, 1);
 | 
			
		||||
        device->dhndl = cvCreateCameraCapture(selection);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        device->dhndl = NULL;
 | 
			
		||||
        device->window = video_device_names[output][selection];
 | 
			
		||||
        if ( device->dhndl || !device->window ) {
 | 
			
		||||
            free(device);
 | 
			
		||||
            video_device_running[type][*device_idx] = NULL;
 | 
			
		||||
            pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
            return vde_FailedStart;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        cvNamedWindow(device->window,1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (type == input) {
 | 
			
		||||
        video_thread_paused = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
    return vde_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VideoDeviceError close_video_device(DeviceType type, uint32_t device_idx)
 | 
			
		||||
{
 | 
			
		||||
    if (device_idx >= MAX_DEVICES) return vde_InvalidSelection;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&video_mutex);
 | 
			
		||||
    VideoDevice* device = video_device_running[type][device_idx];
 | 
			
		||||
    VideoDeviceError rc = de_None;
 | 
			
		||||
 | 
			
		||||
    if (!device) {
 | 
			
		||||
        pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
        return vde_DeviceNotActive;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    video_device_running[type][device_idx] = NULL;
 | 
			
		||||
 | 
			
		||||
    if ( !device->ref_count ) {
 | 
			
		||||
        if (type == input) {
 | 
			
		||||
            cvReleaseCapture(&device->dhndl);
 | 
			
		||||
            cvDestroyWindow(device->window);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            cvDestroyWindow(device->window);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        free(device);
 | 
			
		||||
    }
 | 
			
		||||
    else device->ref_count--;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(&video_mutex);
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
/*  video_device.h
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2014 Toxic All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of Toxic.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is free software: you can redistribute it and/or modify
 | 
			
		||||
 *  it under the terms of the GNU General Public License as published by
 | 
			
		||||
 *  the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 *  (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 *  Toxic is distributed in the hope that it will be useful,
 | 
			
		||||
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 *  You should have received a copy of the GNU General Public License
 | 
			
		||||
 *  along with Toxic.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * You can have multiple sources (Input devices) but only one output device.
 | 
			
		||||
 * Pass buffers to output device via write(); 
 | 
			
		||||
 * Read from running input device(s) via select()/callback combo.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef VIDEO_DEVICE_H
 | 
			
		||||
#define VIDEO_DEVICE_H
 | 
			
		||||
 | 
			
		||||
#define MAX_DEVICES 32
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include "windows.h"
 | 
			
		||||
 | 
			
		||||
#include "audio_device.h"
 | 
			
		||||
 | 
			
		||||
typedef enum VideoDeviceError {
 | 
			
		||||
    vde_None,
 | 
			
		||||
    vde_InternalError = -1,
 | 
			
		||||
    vde_InvalidSelection = -2,
 | 
			
		||||
    vde_FailedStart = -3,
 | 
			
		||||
    vde_Busy = -4,
 | 
			
		||||
    vde_AllDevicesBusy = -5,
 | 
			
		||||
    vde_DeviceNotActive = -6,
 | 
			
		||||
    vde_BufferError = -7,
 | 
			
		||||
    vde_UnsupportedMode = -8,
 | 
			
		||||
    vde_OpenCVError = -9,
 | 
			
		||||
} VideoDeviceError;
 | 
			
		||||
 | 
			
		||||
#ifdef VIDEO
 | 
			
		||||
VideoDeviceError init_video_devices(ToxAV* av);
 | 
			
		||||
#else
 | 
			
		||||
VideoDeviceError init_video_devices();
 | 
			
		||||
#endif /* VIDEO */
 | 
			
		||||
 | 
			
		||||
VideoDeviceError terminate_video_devices();
 | 
			
		||||
 | 
			
		||||
VideoDeviceError set_primary_video_device(DeviceType type, int32_t selection);
 | 
			
		||||
VideoDeviceError open_primary_video_device(DeviceType type);
 | 
			
		||||
/* Start device */
 | 
			
		||||
VideoDeviceError open_video_device(DeviceType type, int32_t selection, uint32_t* device_idx);
 | 
			
		||||
/* Stop device */
 | 
			
		||||
VideoDeviceError close_video_device(DeviceType type, uint32_t device_idx);
 | 
			
		||||
 | 
			
		||||
#endif /* VIDEO_DEVICE_H */
 | 
			
		||||
@@ -154,7 +154,7 @@ struct ToxWindow {
 | 
			
		||||
    int active_box; /* For box notify */
 | 
			
		||||
 | 
			
		||||
    char name[TOXIC_MAX_NAME_LENGTH + 1];
 | 
			
		||||
    uint32_t  num;    /* corresponds to friendnumber in chat windows */
 | 
			
		||||
    uint32_t num;    /* corresponds to friendnumber in chat windows */
 | 
			
		||||
    bool active;
 | 
			
		||||
    int x;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user