Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix some issues #231

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
droidcam*
/droidcam
/droidcam-cli

# vim swap files
*.swp
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# Use at your own risk. See README file for more details.

#
# Variables with ?= can be changed during invocation
# Example:
# APPINDICATOR=ayatana-appindicator3-0.1 make droidcam
Expand All @@ -20,7 +19,7 @@ GTK = `pkg-config --libs --cflags gtk+-3.0` `pkg-config --libs x11`
GTK += `pkg-config --libs --cflags $(APPINDICATOR)`
LIBAV = `pkg-config --libs --cflags libswscale libavutil`
JPEG = `pkg-config --libs --cflags libturbojpeg`
USBMUXD = `pkg-config --libs --cflags libusbmuxd`
USBMUXD = `pkg-config --libs --cflags libusbmuxd-2.0`
LIBS = -lspeex -lasound -lpthread -lm
SRC = src/connection.c src/settings.c src/decoder*.c src/av.c src/usb.c src/queue.c

Expand Down
87 changes: 56 additions & 31 deletions src/av.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@
#include "settings.h"
#include "connection.h"
#include "decoder.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <sys/socket.h>

extern int a_active;
extern int v_active;
extern int a_running;
extern int v_running;
extern int thread_cmd;
extern bool a_running;
extern bool v_running;
extern char thread_cmd;
extern struct settings g_settings;

const char *thread_cmd_val_str;

SOCKET GetConnection(void) {
char *err;
const char *err;
SOCKET socket = INVALID_SOCKET;

if (g_settings.connection == CB_RADIO_IOS) {
Expand All @@ -38,56 +41,81 @@ SOCKET GetConnection(void) {
// Battry Check thread
void *BatteryThreadProc(__attribute__((__unused__)) void *args) {
SOCKET socket = INVALID_SOCKET;
char buf[128] = {0};
char battery_value[32] = {0};
int i, j;
char buf[96];
char battery_value[5];
struct timeval tv = {0};
tv.tv_sec = 1;

dbgprint("Battery Thread Start\n");

while (v_running || a_running) {
if (v_active == 0 && a_active == 0) {
if (!v_active && !a_active) {
usleep(50000);
continue;
}

uint8_t battery_value_pos = 0;
size_t percent_len = 0;

socket = GetConnection();
if (socket == INVALID_SOCKET) {
goto LOOP;
}

if (Send(BATTERY_REQ, CSTR_LEN(BATTERY_REQ), socket) <= 0) {
errprint("error sending battery status request: (%d) '%s'\n",
errno, strerror(errno));
if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv,
sizeof(tv)) == -1) {
goto LOOP;
};

if (!Send(BATTERY_REQ, CSTR_LEN(BATTERY_REQ), socket)) {
errprint("error sending battery status request: (%d) '%s'\n", errno,
strerror(errno));
goto LOOP;
}

memset(buf, 0, sizeof(buf));
memset(battery_value, 0, sizeof(battery_value));
if (RecvAll(buf, sizeof(buf), socket) <= 0) {
goto LOOP;
}

for (i = 0; i < (sizeof(buf)-4); i++) {
if (buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && buf[i+3] == '\n') {
i += 4;
for (uint8_t i = 0; i < (sizeof(buf) - 4); i += 4) {
char *tmp = memchr(&buf[i], '\r', sizeof(buf));
if (!tmp) {
goto LOOP;
}
if (memcmp(tmp + 1, "\n\r\n", 3) == 0) {
battery_value_pos = (tmp - buf) + 4;
break;
}
}
if (!battery_value_pos || battery_value_pos > (sizeof(buf) - (4 + 1)) ||
buf[battery_value_pos] == '0') {
goto LOOP;
}

j = 0;
while (i < sizeof(buf) && j < (sizeof(battery_value)-2) && buf[i] >= '0' && buf[i] <= '9')
battery_value[j++] = buf[i++];
for (uint8_t j = 0; j < 3; j++) {
if (buf[battery_value_pos + j] >= '0' &&
buf[battery_value_pos + j] <= '9') {
battery_value[j] = buf[battery_value_pos + j];
percent_len++;
} else {
break;
}
}

if (j == 0)
battery_value[j++] = '-';
if (percent_len == 0) {
battery_value[0] = '-';
percent_len = 1;
}

battery_value[j++] = '%';
battery_value[j++] = 0;
battery_value[percent_len] = '%';
dbgprint("battery_value: %s\n", battery_value);
UpdateBatteryLabel(battery_value);

LOOP:
disconnect(socket);
for (j = 0; j < 30000 && (v_running || a_running); j++)
for (uint16_t i = 0; i < 30000 && (v_running || a_running); i++)
usleep(1000);
}

Expand All @@ -97,7 +125,7 @@ void *BatteryThreadProc(__attribute__((__unused__)) void *args) {

void *DecodeThreadProc(__attribute__((__unused__)) void *args) {
dbgprint("Decode Thread Start\n");
while (v_running != 0) {
while (v_running) {
JPGFrame *f = pull_ready_jpg_frame();
if (!f) {
usleep(2000);
Expand Down Expand Up @@ -125,8 +153,7 @@ void *VideoThreadProc(void *args) {
}

len = snprintf(buf, sizeof(buf), VIDEO_REQ, decoder_get_video_width(), decoder_get_video_height());
if (Send(buf, len, videoSocket) <= 0){
errprint("send error (%d) '%s'\n", errno, strerror(errno));
if (!Send(buf, len, videoSocket)){
MSG_ERROR("Error sending request, DroidCam might be busy with another client.");
goto early_out;
}
Expand All @@ -143,9 +170,8 @@ void *VideoThreadProc(void *args) {
}

v_active = 1;
while (v_running != 0){
while (v_running) {
if (thread_cmd != 0) {
len = 0;
if (thread_cmd == CB_CONTROL_WB) {
len = snprintf(buf, sizeof(buf), OTHER_REQ_STR, thread_cmd, thread_cmd_val_str);
}
Expand Down Expand Up @@ -246,9 +272,8 @@ void *AudioThreadProc(void *arg) {
return 0;
}

if (Send(AUDIO_REQ, CSTR_LEN(AUDIO_REQ), socket) <= 0) {
if (!Send(AUDIO_REQ, CSTR_LEN(AUDIO_REQ), socket)) {
errprint("send error (audio) (%d) '%s'\n", errno, strerror(errno));
MSG_ERROR("Error sending audio request");
goto early_out;
}

Expand Down Expand Up @@ -276,7 +301,7 @@ void *AudioThreadProc(void *arg) {
bytes_per_packet = CHUNKS_PER_PACKET * DROIDCAM_SPX_CHUNK_BYTES_2;

STREAM:
a_active = 1;
a_active = true;
while (a_running) {
int len = (mode == UDP_STREAM)
? RecvNonBlockUDP(stream_buf, STREAM_BUF_SIZE, socket)
Expand Down Expand Up @@ -339,7 +364,7 @@ void *AudioThreadProc(void *arg) {
}

early_out:
a_active = 0;
a_active = false;
if (mode == UDP_STREAM)
SendUDPMessage(socket, STOP_REQ, CSTR_LEN(STOP_REQ), g_settings.ip, g_settings.port + 1);

Expand Down
23 changes: 12 additions & 11 deletions src/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
Expand All @@ -20,14 +21,14 @@
#include "connection.h"

SOCKET wifiServerSocket = INVALID_SOCKET;
extern int v_running;
extern bool v_running;

char* DROIDCAM_CONNECT_ERROR = \
const char* DROIDCAM_CONNECT_ERROR = \
"Connect failed, please try again.\n"
"Check IP and Port.\n"
"Check network connection.\n";

SOCKET Connect(const char* ip, int port, char **errormsg) {
SOCKET Connect(const char* ip, int port, const char **errormsg) {
int flags;
struct sockaddr_in sin;
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
Expand Down Expand Up @@ -85,41 +86,41 @@ SOCKET Connect(const char* ip, int port, char **errormsg) {
return sock;
}

int Send(const char * buffer, int bytes, SOCKET s) {
bool Send(const char * buffer, int bytes, SOCKET s) {
ssize_t w = 0;
char *ptr = (char*) buffer;
while (bytes > 0) {
w = send(s, ptr, bytes, 0);
if (w <= 0) {
return -1;
return false;
}
bytes -= w;
ptr += w;
}
return 1;
return true;
}

int Recv(const char* buffer, int bytes, SOCKET s) {
ssize_t Recv(const char* buffer, int bytes, SOCKET s) {
return recv(s, (char*)buffer, bytes, 0);
}

int RecvAll(const char* buffer, int bytes, SOCKET s) {
ssize_t RecvAll(const char* buffer, int bytes, SOCKET s) {
return recv(s, (char*)buffer, bytes, MSG_WAITALL);
}

int RecvNonBlock(char * buffer, int bytes, SOCKET s) {
ssize_t RecvNonBlock(char * buffer, int bytes, SOCKET s) {
int res = recv(s, buffer, bytes, MSG_DONTWAIT);
return (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) ? 0 : res;
}

int RecvNonBlockUDP(char * buffer, int bytes, SOCKET s) {
ssize_t RecvNonBlockUDP(char * buffer, int bytes, SOCKET s) {
struct sockaddr_in from;
socklen_t fromLen = sizeof(from);
int res = recvfrom(s, buffer, bytes, MSG_DONTWAIT, (struct sockaddr *)&from, &fromLen);
return (res < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) ? 0 : res;
}

int SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port) {
ssize_t SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port) {
struct sockaddr_in sin;
sin.sin_port = htons((uint16_t)port);
sin.sin_family = AF_INET;
Expand Down
17 changes: 10 additions & 7 deletions src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,24 @@
#ifndef __CONN_H__
#define __CONN_H__

#include <stdbool.h>
#include <sys/types.h>

#define INVALID_SOCKET -1
typedef int SOCKET;
typedef long int SOCKET_PTR;

SOCKET Connect(const char* ip, int port, char **errormsg);
SOCKET Connect(const char* ip, int port, const char **errormsg);
void connection_cleanup();
void disconnect(SOCKET s);

SOCKET accept_connection(int port);
SOCKET CreateUdpSocket(void);
int Send(const char * buffer, int bytes, SOCKET s);
int Recv(const char * buffer, int bytes, SOCKET s);
int RecvAll(const char * buffer, int bytes, SOCKET s);
int RecvNonBlock(char * buffer, int bytes, SOCKET s);
int RecvNonBlockUDP(char * buffer, int bytes, SOCKET s);
int SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port);
bool Send(const char * buffer, int bytes, SOCKET s);
ssize_t Recv(const char * buffer, int bytes, SOCKET s);
ssize_t RecvAll(const char * buffer, int bytes, SOCKET s);
ssize_t RecvNonBlock(char * buffer, int bytes, SOCKET s);
ssize_t RecvNonBlockUDP(char * buffer, int bytes, SOCKET s);
ssize_t SendUDPMessage(SOCKET s, const char *message, int length, char *ip, int port);

#endif
11 changes: 2 additions & 9 deletions src/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ int decoder_init(const char* v4l2_device, unsigned v4l2_width, unsigned v4l2_hei
set_v4l2_device(v4l2_device);
droidcam_device_fd = open_v4l2_device();
} else {
droidcam_device_fd = find_v4l2_device("platform:v4l2loopback_dc");
droidcam_device_fd = find_v4l2_device("platform:v4l2loopback_dc", &WEBCAM_W, &WEBCAM_H);
if (droidcam_device_fd < 0) {
// check for generic v4l2loopback device
droidcam_device_fd = find_v4l2_device("platform:v4l2loopback");
droidcam_device_fd = find_v4l2_device("platform:v4l2loopback", &WEBCAM_W, &WEBCAM_H);
}
}

Expand All @@ -108,13 +108,6 @@ int decoder_init(const char* v4l2_device, unsigned v4l2_width, unsigned v4l2_hei
WEBCAM_W = 320;
WEBCAM_H = 240;
droidcam_device_fd = 0;
} else {
query_v4l_device(droidcam_device_fd, &WEBCAM_W, &WEBCAM_H);
dbgprint("WEBCAM_W=%d, WEBCAM_H=%d\n", WEBCAM_W, WEBCAM_H);
if (WEBCAM_W < 2 || WEBCAM_H < 2 || WEBCAM_W > 9999 || WEBCAM_H > 9999){
MSG_ERROR("Unable to query v4l2 device for correct parameters");
return 0;
}
}

memset(&jpg_decoder, 0, sizeof(struct jpg_dec_ctx_s));
Expand Down
4 changes: 2 additions & 2 deletions src/decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ int decoder_horizontal_flip();
int decoder_vertical_flip();
void decoder_show_test_image();

/* 20ms 16hkz 16 bit */
/* 20ms 16khz 16 bit */
#define DROIDCAM_CHUNK_MS_2 20
#define DROIDCAM_SPX_CHUNK_BYTES_2 70
#define DROIDCAM_PCM_CHUNK_BYTES_2 640
Expand All @@ -65,7 +65,7 @@ void decoder_show_test_image();

void set_v4l2_device(const char* device);
int open_v4l2_device(void);
int find_v4l2_device(const char* bus_info);
int find_v4l2_device(const char* bus_info, unsigned *in_v4l2_width, unsigned *in_v4l2_height);
void query_v4l_device(int droidcam_device_fd, unsigned *WEBCAM_W, unsigned *WEBCAM_H);

snd_pcm_t *find_snd_device(void);
Expand Down
11 changes: 6 additions & 5 deletions src/decoder_snd.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ static snd_pcm_sframes_t period_size;
static unsigned int period_time = PERIOD_TIME;/* period time in us */
static unsigned int buffer_time = DROIDCAM_SPEEX_BACKBUF_MAX_COUNT * PERIOD_TIME; /* ring buffer length in us */

snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;

static int set_hwparams(snd_pcm_t *handle, snd_pcm_hw_params_t *params, snd_pcm_access_t access) {
unsigned int rrate;
snd_pcm_uframes_t size;
int err, dir;
int resample = 1;
int err;
int dir = 0;
const unsigned int resample = 1;
/* choose all parameters */
err = snd_pcm_hw_params_any(handle, params);
if (err < 0) {
Expand Down Expand Up @@ -248,6 +246,9 @@ int snd_transfer_commit(snd_pcm_t *handle, struct snd_transfer_s *transfer) {
snd_pcm_t *find_snd_device(void) {
int err, card, i;
snd_pcm_t *handle = NULL;
snd_pcm_hw_params_t *hwparams;
snd_pcm_sw_params_t *swparams;

snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_sw_params_alloca(&swparams);

Expand Down
Loading