Full but still broken rework of everything
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.22.1)
|
||||
project(camera_hook LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(camera_hook LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -51,7 +51,7 @@ set_target_properties(camera_hook PROPERTIES
|
||||
|
||||
# Camera provider wrapper (static C binary, bind-mounted over original)
|
||||
add_executable(camera_provider_wrapper src/camera_provider_wrapper.c)
|
||||
target_link_options(camera_provider_wrapper PRIVATE -static)
|
||||
set_target_properties(camera_provider_wrapper PROPERTIES
|
||||
LINKER_LANGUAGE C
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../root-module"
|
||||
)
|
||||
|
||||
@@ -54,6 +54,10 @@ int get_rtsp_shmem_fd();
|
||||
int get_rtsp_width();
|
||||
int get_rtsp_height();
|
||||
|
||||
// Get the shared memory base pointer (for reading frames)
|
||||
// Returns nullptr if not initialized
|
||||
uint8_t* get_rtsp_shmem_base();
|
||||
|
||||
} // namespace rtsp_client
|
||||
|
||||
#endif // RTSP_CLIENT_H
|
||||
|
||||
@@ -87,6 +87,10 @@ int get_decoder_width();
|
||||
int get_decoder_height();
|
||||
bool is_decoder_running();
|
||||
|
||||
// Get the shared memory base pointer (for reading frames)
|
||||
// Returns nullptr if not initialized
|
||||
uint8_t* get_shmem_base();
|
||||
|
||||
// Write a YUV420 frame to the shared memory ring buffer
|
||||
// Called internally by the decoder thread
|
||||
// y_data, u_data, v_data: pointers to Y, U, V planes
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <dlfcn.h>
|
||||
#include <android/log.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
@@ -11,10 +13,20 @@
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
|
||||
// Define native_handle_t (not publicly available in NDK)
|
||||
struct native_handle_t {
|
||||
int version;
|
||||
int numFds;
|
||||
int numInts;
|
||||
int data[0];
|
||||
};
|
||||
|
||||
#include "camera_hal/types.h"
|
||||
#include "camera_hal/ICameraProvider.h"
|
||||
#include "camera_hal/ICameraDevice.h"
|
||||
#include "camera_hal/ICameraDeviceSession.h"
|
||||
#include "video_decoder.h"
|
||||
#include "rtsp_client.h"
|
||||
|
||||
#define LOG_TAG "CameraHook"
|
||||
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
@@ -104,15 +116,55 @@ static bool check_virtual_camera_enabled() {
|
||||
}
|
||||
|
||||
static bool inject_video_frame(int32_t stream_id, void* buffer_handle,
|
||||
int32_t width, int32_t height) {
|
||||
// Task 7/9 will implement: read from shared memory ring buffer,
|
||||
// lock AHardwareBuffer, copy YUV data, unlock.
|
||||
// Returns true if frame was injected, false if no frame available.
|
||||
int32_t width, int32_t height) {
|
||||
(void)stream_id;
|
||||
(void)buffer_handle;
|
||||
(void)width;
|
||||
(void)height;
|
||||
return false;
|
||||
|
||||
uint8_t* shmem_base = video_decoder::get_shmem_base();
|
||||
if (!shmem_base) {
|
||||
shmem_base = rtsp_client::get_rtsp_shmem_base();
|
||||
if (!shmem_base) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
video_decoder::RingBufferHeader* header = (video_decoder::RingBufferHeader*)shmem_base;
|
||||
if (header->magic != video_decoder::RING_MAGIC || header->version != video_decoder::RING_VERSION) {
|
||||
ALOGE("Invalid ring buffer magic/version");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(header->flags & video_decoder::FLAG_DECODER_RUNNING)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t frame_size = header->frame_width * header->frame_height * 3 / 2;
|
||||
uint32_t read_idx = header->write_index;
|
||||
if (read_idx >= header->frame_count) {
|
||||
ALOGE("Invalid write_index: %u", read_idx);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* frame_data = shmem_base + video_decoder::RING_HEADER_SIZE + (read_idx * frame_size);
|
||||
|
||||
native_handle_t* handle = (native_handle_t*)buffer_handle;
|
||||
if (!handle || handle->numFds < 1) {
|
||||
ALOGE("Invalid native handle");
|
||||
return false;
|
||||
}
|
||||
|
||||
int fd = handle->data[0];
|
||||
size_t buf_size = (size_t)width * height * 3 / 2;
|
||||
void* addr = mmap(nullptr, buf_size, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (addr == MAP_FAILED) {
|
||||
ALOGE("mmap failed: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(addr, frame_data, frame_size);
|
||||
munmap(addr, buf_size);
|
||||
|
||||
ALOGD("Injected frame %u (stream %d, %dx%d)", header->sequence, stream_id, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void update_fps_counter() {
|
||||
|
||||
@@ -644,6 +644,10 @@ int rtsp_client::get_rtsp_shmem_fd() {
|
||||
return g_rtsp.shmem_fd;
|
||||
}
|
||||
|
||||
uint8_t* rtsp_client::get_rtsp_shmem_base() {
|
||||
return g_rtsp.shmem_base;
|
||||
}
|
||||
|
||||
int rtsp_client::get_rtsp_width() {
|
||||
return g_rtsp.width;
|
||||
}
|
||||
|
||||
@@ -387,6 +387,10 @@ int video_decoder::get_shmem_fd() {
|
||||
return g_decoder.shmem_fd;
|
||||
}
|
||||
|
||||
uint8_t* video_decoder::get_shmem_base() {
|
||||
return g_decoder.shmem_base;
|
||||
}
|
||||
|
||||
int video_decoder::get_decoder_width() {
|
||||
return g_decoder.width;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user