Skip to content

Commit

Permalink
fix some issues
Browse files Browse the repository at this point in the history
1. Automatically detect libturbojpeg linking arguments.
2. Fixed a data race with `a_running` and `v_running` when exiting.
3. Automatically try next v4l2 dev when failing to set pixel format.
  • Loading branch information
skbeh committed May 20, 2023
1 parent 1a68890 commit 995a3f8
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 63 deletions.
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
20 changes: 10 additions & 10 deletions src/av.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@
#include "settings.h"
#include "connection.h"
#include "decoder.h"
#include <stdbool.h>
#include <stdint.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 @@ -45,7 +46,7 @@ void *BatteryThreadProc(__attribute__((__unused__)) void *args) {
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;
}
Expand Down Expand Up @@ -97,7 +98,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 @@ -143,9 +144,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 @@ -276,7 +276,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 +339,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
7 changes: 4 additions & 3 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
2 changes: 1 addition & 1 deletion src/connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
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);

Expand Down
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
16 changes: 14 additions & 2 deletions src/decoder_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ int open_v4l2_device(void) {
if (!S_ISCHR(st.st_mode))
return 0;

fd = open(v4l2_device, O_RDWR | O_NONBLOCK, 0);
fd = open(v4l2_device, O_WRONLY | O_NONBLOCK, 0);
if (fd <= 0) {
errprint("Error opening '%s': %d '%s'\n", v4l2_device, errno, strerror(errno));
return 0;
Expand All @@ -42,14 +42,17 @@ int open_v4l2_device(void) {
return fd;
}

int find_v4l2_device(const char* bus_info) {
int find_v4l2_device(const char* bus_info, unsigned *in_v4l2_width, unsigned *in_v4l2_height) {
int bus_info_len = strlen(bus_info);
int video_dev_fd;
int video_dev_nr = 0;
struct v4l2_capability v4l2cap;

dbgprint("Looking for v4l2 card: %s\n", bus_info);
for (video_dev_nr = 0; video_dev_nr < 99; video_dev_nr++) {
unsigned v4l2_width = *in_v4l2_width;
unsigned v4l2_height = *in_v4l2_height;

snprintf(v4l2_device, sizeof(v4l2_device), "/dev/video%d", video_dev_nr);

video_dev_fd = open_v4l2_device();
Expand All @@ -61,8 +64,17 @@ int find_v4l2_device(const char* bus_info) {
continue;
}

query_v4l_device(video_dev_fd, &v4l2_width, &v4l2_height)
dbgprint("Device %s is '%s' @ %s\n", v4l2_device, v4l2cap.card, v4l2cap.bus_info);
dbgprint("v4l2_width=%d, v4l2_height=%d\n", v4l2_width, v4l2_height);
if (v4l2_width < 2 || v4l2_height < 2 || v4l2_width > 9999 || v4l2_height > 9999){
errprint("Unable to query v4l2 device for correct parameters\n");
continue;
}

if (0 == strncmp(bus_info, (const char*) v4l2cap.bus_info, bus_info_len)) {
*in_v4l2_width = v4l2_width;
*in_v4l2_height = v4l2_height;
return video_dev_fd;
}

Expand Down
26 changes: 14 additions & 12 deletions src/droidcam-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include <pthread.h>
#include <signal.h>
#include <stdatomic.h>
#include <stdbool.h>

#include "common.h"
#include "settings.h"
Expand All @@ -23,11 +25,11 @@ Thread athread = {0, -1}, vthread = {0, -1}, dthread = {0, -1};

char *v4l2_dev = 0;
unsigned v4l2_width = 0, v4l2_height = 0;
volatile int a_active = 0;
volatile int v_active = 0;
volatile int v_running = 0;
volatile int a_running = 0;
volatile int thread_cmd = 0;
volatile bool a_active = false;
volatile bool v_active = false;
volatile bool v_running = false;
volatile bool a_running = false;
volatile char thread_cmd = 0;
int no_controls = 0;
struct settings g_settings = {0};

Expand All @@ -39,8 +41,8 @@ void * VideoThreadProc(void * args);
void * DecodeThreadProc(void * args);

void sig_handler(__attribute__((__unused__)) int sig) {
a_running = 0;
v_running = 0;
a_running = false;
v_running = false;
return;
}

Expand Down Expand Up @@ -113,7 +115,7 @@ static void parse_args(int argc, char *argv[]) {
continue;
}
if (argv[i][0] == '-' && argv[i][1] == 'v') {
v_running = 1;
v_running = true;
continue;
}

Expand Down Expand Up @@ -142,8 +144,8 @@ static void parse_args(int argc, char *argv[]) {
if (argv[i][0] == '-' && argv[i][1] == 'l') {
g_settings.port = strtoul(argv[i+1], NULL, 10);
g_settings.connection = CB_WIFI_SRVR;
a_running = 0;
v_running = 1;
a_running = false;
v_running = true;
return;
}

Expand Down Expand Up @@ -235,7 +237,7 @@ int main(int argc, char *argv[]) {
parse_args(argc, argv);

if (!v_running && !a_running)
v_running = 1;
v_running = true;

if (!decoder_init(v4l2_dev, v4l2_width, v4l2_height)) {
return 2;
Expand Down Expand Up @@ -264,7 +266,7 @@ int main(int argc, char *argv[]) {
videoSocket = rc;
}
else {
char *errmsg = NULL;
const char *errmsg = NULL;
videoSocket = Connect(g_settings.ip, g_settings.port, &errmsg);
if (videoSocket == INVALID_SOCKET) {
errprint("Video: Connect failed to %s:%d\n", g_settings.ip, g_settings.port);
Expand Down
Loading

0 comments on commit 995a3f8

Please sign in to comment.