diff --git a/audio_plugin/build.sh b/audio_plugin/build.sh index eb6e9e9..5ea093f 100644 --- a/audio_plugin/build.sh +++ b/audio_plugin/build.sh @@ -4,7 +4,7 @@ rm -r build64 mkdir build64 cd build64 cmake .. -DCMAKE_TOOLCHAIN_FILE=../cross-arm64.cmake -make -j4 +make -j8 cd .. @@ -12,4 +12,4 @@ rm -r build mkdir build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE=../cross-armhf.cmake -make -j4 \ No newline at end of file +make -j8 \ No newline at end of file diff --git a/audio_plugin/module_pcm_android_aserver.c b/audio_plugin/module_pcm_android_aserver.c index 85a9889..3b3b059 100644 --- a/audio_plugin/module_pcm_android_aserver.c +++ b/audio_plugin/module_pcm_android_aserver.c @@ -1,9 +1,11 @@ #include +#include #include #include #include #include #include +#include #define MIN_REQUEST_LENGTH 5 @@ -29,16 +31,37 @@ typedef struct snd_pcm_android_aserver { int fd; int frame_bytes; unsigned int position; - char* buffer; + void* buffer; int buffer_size; + bool use_shm; } snd_pcm_android_aserver_t; -static void grow_buffer_if_necessary(snd_pcm_android_aserver_t* android_aserver, int new_size) { - if (new_size > android_aserver->buffer_size) { - if (android_aserver->buffer) free(android_aserver->buffer); - android_aserver->buffer_size = new_size; - android_aserver->buffer = (char*)malloc(new_size); - } +static int android_aserver_recv_fd(int fd) { + char zero = 0; + struct iovec iovmsg = {.iov_base = &zero, .iov_len = 1}; + struct { + struct cmsghdr align; + int fds[1]; + } ctrlmsg; + + struct msghdr msg = { + .msg_name = NULL, + .msg_namelen = 0, + .msg_iov = &iovmsg, + .msg_iovlen = 1, + .msg_flags = 0, + .msg_control = &ctrlmsg, + .msg_controllen = sizeof(struct cmsghdr) + sizeof(int) + }; + + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = msg.msg_controllen; + ((int*)CMSG_DATA(cmsg))[0] = -1; + + recvmsg(fd, &msg, 0); + return ((int*)CMSG_DATA(cmsg))[0]; } static int android_aserver_close(snd_pcm_ioplug_t* io) { @@ -51,12 +74,12 @@ static int android_aserver_close(snd_pcm_ioplug_t* io) { request_data[0] = REQUEST_CODE_CLOSE; memcpy(request_data + 1, &request_length, 4); - write(android_aserver->fd, request_data, sizeof(request_data)); + write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); close(android_aserver->fd); } - if (android_aserver->buffer) { - free(android_aserver->buffer); + if (android_aserver->buffer_size > 0) { + munmap(android_aserver->buffer, android_aserver->buffer_size); android_aserver->buffer_size = 0; } @@ -66,14 +89,13 @@ static int android_aserver_close(snd_pcm_ioplug_t* io) { static int android_aserver_start(snd_pcm_ioplug_t* io) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - - grow_buffer_if_necessary(android_aserver, MIN_REQUEST_LENGTH); int request_length = 0; - android_aserver->buffer[0] = REQUEST_CODE_START; - memcpy(android_aserver->buffer + 1, &request_length, 4); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_START; + memcpy(request_data + 1, &request_length, 4); - int res = write(android_aserver->fd, android_aserver->buffer, MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); if (res < 0) return -EINVAL; return 0; @@ -81,29 +103,27 @@ static int android_aserver_start(snd_pcm_ioplug_t* io) { static int android_aserver_stop(snd_pcm_ioplug_t* io) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - - grow_buffer_if_necessary(android_aserver, MIN_REQUEST_LENGTH); int request_length = 0; - android_aserver->buffer[0] = REQUEST_CODE_STOP; - memcpy(android_aserver->buffer + 1, &request_length, 4); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_STOP; + memcpy(request_data + 1, &request_length, 4); - int res = write(android_aserver->fd, android_aserver->buffer, MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); if (res < 0) return -EINVAL; return 0; } -static int android_aserver_pause(snd_pcm_ioplug_t* io) { +static int android_aserver_pause(snd_pcm_ioplug_t* io, int enable) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - - grow_buffer_if_necessary(android_aserver, MIN_REQUEST_LENGTH); int request_length = 0; - android_aserver->buffer[0] = REQUEST_CODE_PAUSE; - memcpy(android_aserver->buffer + 1, &request_length, 4); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_PAUSE; + memcpy(request_data + 1, &request_length, 4); - int res = write(android_aserver->fd, android_aserver->buffer, MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); if (res < 0) return -EINVAL; return 0; @@ -137,66 +157,90 @@ static int android_aserver_prepare(snd_pcm_ioplug_t* io) { } int request_length = 10; - grow_buffer_if_necessary(android_aserver, request_length + MIN_REQUEST_LENGTH); - android_aserver->buffer[0] = REQUEST_CODE_PREPARE; - memcpy(android_aserver->buffer + 1, &request_length, 4); - memcpy(android_aserver->buffer + 5, &channels, 1); - memcpy(android_aserver->buffer + 6, &data_type, 1); - memcpy(android_aserver->buffer + 7, &io->rate, 4); - memcpy(android_aserver->buffer + 11, &io->buffer_size, 4); + char request_data[request_length + MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_PREPARE; + memcpy(request_data + 1, &request_length, 4); + memcpy(request_data + 5, &channels, 1); + memcpy(request_data + 6, &data_type, 1); + memcpy(request_data + 7, &io->rate, 4); + memcpy(request_data + 11, &io->buffer_size, 4); - int res = write(android_aserver->fd, android_aserver->buffer, request_length + MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, request_length + MIN_REQUEST_LENGTH); if (res < 0) return -EINVAL; + if (android_aserver->use_shm) { + if (android_aserver->buffer_size > 0) { + munmap(android_aserver->buffer, android_aserver->buffer_size); + android_aserver->buffer_size = 0; + } + + int fd = android_aserver_recv_fd(android_aserver->fd); + if (fd >= 0) { + android_aserver->buffer_size = io->buffer_size * android_aserver->frame_bytes; + android_aserver->buffer = mmap(NULL, android_aserver->buffer_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); + + if (android_aserver->buffer == MAP_FAILED) { + android_aserver->buffer_size = 0; + android_aserver->use_shm = false; + } + close(fd); + } + } + return 0; } static snd_pcm_sframes_t android_aserver_pointer(snd_pcm_ioplug_t* io) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - - grow_buffer_if_necessary(android_aserver, MIN_REQUEST_LENGTH); int request_length = 0; - android_aserver->buffer[0] = REQUEST_CODE_POINTER; - memcpy(android_aserver->buffer + 1, &request_length, 4); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_POINTER; + memcpy(request_data + 1, &request_length, 4); - int res = write(android_aserver->fd, android_aserver->buffer, MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); if (res < 0) return android_aserver->position; int position; res = read(android_aserver->fd, &position, 4); - if (res < 0) return android_aserver->position; + if (res != 4) return android_aserver->position; android_aserver->position = position; return android_aserver->position; } -static snd_pcm_sframes_t android_aserver_write(snd_pcm_ioplug_t* io, const snd_pcm_channel_area_t* areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { +static snd_pcm_sframes_t android_aserver_transfer(snd_pcm_ioplug_t* io, const snd_pcm_channel_area_t* areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - const char* src_data = (char*)areas->addr + (areas->first + areas->step * offset) / 8; + char* data = (char*)areas->addr + (areas->first + areas->step * offset) / 8; int request_length = size * android_aserver->frame_bytes; - grow_buffer_if_necessary(android_aserver, request_length + MIN_REQUEST_LENGTH); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_WRITE; + memcpy(request_data + 1, &request_length, 4); - android_aserver->buffer[0] = REQUEST_CODE_WRITE; - memcpy(android_aserver->buffer + 1, &request_length, 4); - memcpy(android_aserver->buffer + 5, src_data, request_length); + if (android_aserver->use_shm) memcpy(android_aserver->buffer, data, request_length); - int res = write(android_aserver->fd, android_aserver->buffer, request_length + MIN_REQUEST_LENGTH); - return (res >= MIN_REQUEST_LENGTH ? res - MIN_REQUEST_LENGTH : 0) / android_aserver->frame_bytes; + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); + if (res < 0) return 0; + + if (!android_aserver->use_shm) { + res = write(android_aserver->fd, data, request_length); + if (res < 0) return 0; + } + + return size; } static int android_aserver_drain(snd_pcm_ioplug_t* io) { snd_pcm_android_aserver_t* android_aserver = io->private_data; - - grow_buffer_if_necessary(android_aserver, MIN_REQUEST_LENGTH); int request_length = 0; - android_aserver->buffer[0] = REQUEST_CODE_DRAIN; - memcpy(android_aserver->buffer + 1, &request_length, 4); + char request_data[MIN_REQUEST_LENGTH]; + request_data[0] = REQUEST_CODE_DRAIN; + memcpy(request_data + 1, &request_length, 4); - int res = write(android_aserver->fd, android_aserver->buffer, MIN_REQUEST_LENGTH); + int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH); if (res < 0) return -EINVAL; return 0; @@ -232,8 +276,9 @@ static snd_pcm_ioplug_callback_t android_aserver_callback = { .start = android_aserver_start, .stop = android_aserver_stop, .pause = android_aserver_pause, + .resume = android_aserver_start, .prepare = android_aserver_prepare, - .transfer = android_aserver_write, + .transfer = android_aserver_transfer, .drain = android_aserver_drain, .pointer = android_aserver_pointer, }; @@ -250,7 +295,13 @@ static int android_aserver_connect() { strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path) - 1); - int res = connect(fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_un)); + int res; + do { + res = 0; + if (connect(fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_un)) < 0) res = -errno; + } + while (res == -EINTR); + if (res < 0) { close(fd); return -1; @@ -278,6 +329,9 @@ static int android_aserver_create(snd_pcm_t** pcmp, const char* name, snd_pcm_st android_aserver->fd = android_aserver_connect(); if (android_aserver->fd < 0) goto error; + char* use_shm_value = getenv("ANDROID_ASERVER_USE_SHM"); + android_aserver->use_shm = use_shm_value && (strcmp(use_shm_value, "true") == 0 || strcmp(use_shm_value, "1") == 0); + res = snd_pcm_ioplug_create(&android_aserver->io, name, stream, mode); if (res < 0) goto error; @@ -290,7 +344,7 @@ static int android_aserver_create(snd_pcm_t** pcmp, const char* name, snd_pcm_st *pcmp = android_aserver->io.pcm; return 0; - error: +error: if (android_aserver->fd >= 0) close(android_aserver->fd); free(android_aserver); return res; diff --git a/obb_image_generator/.gitattributes b/obb_image_generator/.gitattributes index 486a232..9d28601 100644 --- a/obb_image_generator/.gitattributes +++ b/obb_image_generator/.gitattributes @@ -1 +1,2 @@ *.zip filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text diff --git a/obb_image_generator/generate.sh b/obb_image_generator/generate.sh index e5b32fd..97b4f5e 100644 --- a/obb_image_generator/generate.sh +++ b/obb_image_generator/generate.sh @@ -1,28 +1,34 @@ #!/bin/bash +OBB_IMG_VERSION=2 + clear echo "Winlator OBB Image Generator" -rm -r imagefs +if [ -d imagefs ]; then + rm -r imagefs +fi + mkdir -p imagefs -echo "Unzipping ubuntu-prepared.zip..." -unzip -q -o ubuntu-prepared.zip -d imagefs +echo "Extracting ubuntu-prepared.txz..." +tar -xf ubuntu-prepared.txz -C imagefs -echo "Unzipping wine.zip..." -mkdir -p imagefs/opt/wine -unzip -q -o wine.zip -d imagefs/opt/wine +echo "Extracting wine.txz..." +tar -xf wine.txz -C imagefs/opt -echo "Unzipping patches.zip..." -unzip -q -o patches.zip -d imagefs +for f in imagefs/opt/* +do + if [[ $f == *wine* ]] + then + mv $f imagefs/opt/wine + fi +done -cd imagefs -rm -r .l2s +echo "Extracting patches.txz..." +tar -xf patches.txz -C imagefs echo "Creating OBB Image..." -tar -I 'zstd -19' -cf main.1.com.winlator.obb . +tar -I 'zstd -19' -cf main.$OBB_IMG_VERSION.com.winlator.obb -C imagefs . -cp main.1.com.winlator.obb ../ - -cd .. rm -r imagefs \ No newline at end of file diff --git a/obb_image_generator/patches.txz b/obb_image_generator/patches.txz new file mode 100644 index 0000000..f9afb7e --- /dev/null +++ b/obb_image_generator/patches.txz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81b664900f48a282d5c0fd0ad4c52d88db55b6547751a1d760412539271661dc +size 148307140 diff --git a/obb_image_generator/patches.zip b/obb_image_generator/patches.zip deleted file mode 100644 index 689c370..0000000 --- a/obb_image_generator/patches.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f839cc26c734381cca65cee8f19a0c9dd61c467fb1ca7ae7612e72a09b833fd8 -size 185785402 diff --git a/obb_image_generator/prepare-ubuntu.sh b/obb_image_generator/prepare-ubuntu.sh index 531ff19..e8dac6c 100644 --- a/obb_image_generator/prepare-ubuntu.sh +++ b/obb_image_generator/prepare-ubuntu.sh @@ -17,12 +17,10 @@ apt install -y locales locale-gen --no-archive en_US.utf8 #wine dependencies (armhf) -apt install -y libasound2:armhf libc6:armhf libglib2.0-0:armhf libgstreamer1.0-0:armhf libgstreamer-plugins-base1.0-0:armhf libgstreamer-plugins-good1.0-0:armhf gstreamer1.0-plugins-base:armhf gstreamer1.0-plugins-good:armhf gstreamer1.0-plugins-ugly:armhf gstreamer1.0-libav:armhf libunwind8:armhf libx11-6:armhf libxext6:armhf libfontconfig1:armhf libfreetype6:armhf libglu1-mesa:armhf libglu1:armhf libgnutls30:armhf libosmesa6:armhf libxcomposite1:armhf libxcursor1:armhf libxfixes3:armhf libxi6:armhf libxrandr2:armhf libxrender1:armhf libxcb-randr0:armhf libxcb-xfixes0:armhf libwayland-client0:armhf libvulkan1:armhf +apt install -y libasound2:armhf libc6:armhf libglib2.0-0:armhf libgstreamer1.0-0:armhf gstreamer1.0-plugins-base:armhf gstreamer1.0-plugins-good:armhf gstreamer1.0-plugins-ugly:armhf gstreamer1.0-libav:armhf libunwind8:armhf libx11-6:armhf libxext6:armhf libfontconfig1:armhf libfreetype6:armhf libglu1-mesa:armhf libglu1:armhf libgnutls30:armhf libosmesa6:armhf libxcomposite1:armhf libxcursor1:armhf libxfixes3:armhf libxi6:armhf libxrandr2:armhf libxrender1:armhf libxcb-randr0:armhf libxcb-xfixes0:armhf libwayland-client0:armhf libvulkan1:armhf #wine dependencies (arm64) -apt install -y libasound2:arm64 libc6:arm64 libglib2.0-0:arm64 libgstreamer1.0-0:arm64 libgstreamer-plugins-base1.0-0:arm64 libgstreamer-plugins-good1.0-0:arm64 gstreamer1.0-plugins-base:arm64 gstreamer1.0-plugins-good:arm64 gstreamer1.0-plugins-ugly:arm64 gstreamer1.0-libav:arm64 libunwind8:arm64 libx11-6:arm64 libxext6:arm64 libfontconfig1:arm64 libfreetype6:arm64 libglu1-mesa:arm64 libglu1:arm64 libgnutls30:arm64 libosmesa6:arm64 libxcomposite1:arm64 libxcursor1:arm64 libxfixes3:arm64 libxi6:arm64 libxrandr2:arm64 libxrender1:arm64 libxcb-randr0:arm64 libxcb-xfixes0:arm64 libwayland-client0:arm64 libvulkan1:arm64 - -apt remove -y libpulse0:armhf libpulse0:arm64 +apt install -y libasound2:arm64 libc6:arm64 libglib2.0-0:arm64 libgstreamer1.0-0:arm64 gstreamer1.0-plugins-base:arm64 gstreamer1.0-plugins-good:arm64 gstreamer1.0-plugins-ugly:arm64 gstreamer1.0-libav:arm64 libunwind8:arm64 libx11-6:arm64 libxext6:arm64 libfontconfig1:arm64 libfreetype6:arm64 libglu1-mesa:arm64 libglu1:arm64 libgnutls30:arm64 libosmesa6:arm64 libxcomposite1:arm64 libxcursor1:arm64 libxfixes3:arm64 libxi6:arm64 libxrandr2:arm64 libxrender1:arm64 libxcb-randr0:arm64 libxcb-xfixes0:arm64 libwayland-client0:arm64 libvulkan1:arm64 apt update -y apt upgrade -y @@ -39,6 +37,7 @@ rm -r dri rm -r libLLVM-9.so rm -r libLLVM-9.so.1 -rm -r /root/chroot.sh +rm -r /root/prepare-ubuntu.sh +rm -r /var/lib/apt/lists/* exit \ No newline at end of file diff --git a/obb_image_generator/ubuntu-prepared.txz b/obb_image_generator/ubuntu-prepared.txz new file mode 100644 index 0000000..bc580ce --- /dev/null +++ b/obb_image_generator/ubuntu-prepared.txz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bd95302a76fe6d6911b6c37f6cc09cd667c5346d8817e52482389269658de4cf +size 176149768 diff --git a/obb_image_generator/ubuntu-prepared.zip b/obb_image_generator/ubuntu-prepared.zip deleted file mode 100644 index 28825ef..0000000 --- a/obb_image_generator/ubuntu-prepared.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:47f6a0ca4c699e6a46ded8508138ab9e250e9ba6c0f5fb2dfd3c863bb03b5948 -size 308425004 diff --git a/obb_image_generator/wine.txz b/obb_image_generator/wine.txz new file mode 100644 index 0000000..e2fa819 --- /dev/null +++ b/obb_image_generator/wine.txz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa600e26aa624b7c9b28451cf55f3ed036f6cd5553ac75558bb6f49e1db42d42 +size 56536008 diff --git a/obb_image_generator/wine.zip b/obb_image_generator/wine.zip deleted file mode 100644 index c389b7d..0000000 --- a/obb_image_generator/wine.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4496eed06154cd6ee81f969d8679b29dede15ff8c8b289c81f2bbe88d35d1f1 -size 142208940