diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index db796e825..e7c12e30c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -394,8 +394,7 @@ add_sdl_test_executable(teststreaming NEEDS_RESOURCES TESTUTILS SOURCES teststre add_sdl_test_executable(testtimer NONINTERACTIVE NONINTERACTIVE_ARGS --no-interactive NONINTERACTIVE_TIMEOUT 60 SOURCES testtimer.c) add_sdl_test_executable(testurl SOURCES testurl.c) add_sdl_test_executable(testver NONINTERACTIVE SOURCES testver.c) -add_sdl_test_executable(testcamera SOURCES testcamera.c) -add_sdl_test_executable(testcameraminimal MAIN_CALLBACKS SOURCES testcameraminimal.c) +add_sdl_test_executable(testcamera MAIN_CALLBACKS SOURCES testcamera.c) add_sdl_test_executable(testviewport NEEDS_RESOURCES TESTUTILS SOURCES testviewport.c) add_sdl_test_executable(testwm SOURCES testwm.c) add_sdl_test_executable(testyuv NONINTERACTIVE NONINTERACTIVE_ARGS "--automated" NEEDS_RESOURCES TESTUTILS SOURCES testyuv.c testyuv_cvt.c) diff --git a/test/testcamera.c b/test/testcamera.c index e5389d218..9fc04c534 100644 --- a/test/testcamera.c +++ b/test/testcamera.c @@ -9,224 +9,45 @@ including commercial applications, and to alter it and redistribute it freely. */ -#include "SDL3/SDL_main.h" -#include "SDL3/SDL.h" -#include "SDL3/SDL_test.h" -#include "SDL3/SDL_camera.h" -#ifdef SDL_PLATFORM_EMSCRIPTEN -#include -#endif +#define SDL_MAIN_USE_CALLBACKS 1 +#include +#include +#include -#if 1 -int main(int argc, char **argv) +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDLTest_CommonState *state = NULL; +static SDL_Camera *camera = NULL; +static SDL_CameraSpec spec; +static SDL_Texture *texture = NULL; +static SDL_bool texture_updated = SDL_FALSE; +static SDL_Surface *frame_current = NULL; + +int SDL_AppInit(int argc, char *argv[]) { - SDL_Log("FIXME: update me"); - return 0; -} -#else -static const char *usage = "\ - \n\ - =========================================================================\n\ - \n\ -Use keyboards:\n\ - o: open first camera device. (close previously opened)\n\ - l: switch to, and list camera devices\n\ - i: information about status (Init, Playing, Stopped)\n\ - f: formats and resolutions available\n\ - s: start / stop capture\n\ - h: display help\n\ - esc: exit \n\ - \n\ - =========================================================================\n\ - \n\ -"; - -typedef struct { - Uint64 next_check; - int frame_counter; - int check_delay; - double last_fps; -} measure_fps_t; - -static void -update_fps(measure_fps_t *m) -{ - Uint64 now = SDL_GetTicks(); - Uint64 deadline; - m->frame_counter++; - if (m->check_delay == 0) { - m->check_delay = 1500; - } - deadline = m->next_check; - if (now >= deadline) { - /* Print out some timing information */ - const Uint64 then = m->next_check - m->check_delay; - m->last_fps = ((double) m->frame_counter * 1000) / (now - then); - m->next_check = now + m->check_delay; - m->frame_counter = 0; - } -} - -#if defined(SDL_PLATFORM_LINUX) && !defined(SDL_PLATFORM_ANDROID) -static void load_average(float *val) -{ - FILE *fp = 0; - char line[1024]; - fp = fopen("/proc/loadavg", "rt"); - if (fp) { - char *s = fgets(line, sizeof(line), fp); - if (s) { - SDL_sscanf(s, "%f", val); - } - fclose(fp); - } -} -#endif - - -struct data_capture_t { - SDL_CameraDevice *device; - SDL_CameraSpec obtained; - int stopped; - SDL_CameraFrame frame_current; - measure_fps_t fps_capture; - SDL_Texture *texture; - int texture_updated; -}; - -#define SAVE_CAPTURE_STATE(x) \ - data_capture_tab[(x)].device = device; \ - data_capture_tab[(x)].obtained = obtained; \ - data_capture_tab[(x)].stopped = stopped; \ - data_capture_tab[(x)].frame_current = frame_current; \ - data_capture_tab[(x)].fps_capture = fps_capture; \ - data_capture_tab[(x)].texture = texture; \ - data_capture_tab[(x)].texture_updated = texture_updated; \ - - -#define RESTORE_CAPTURE_STATE(x) \ - device = data_capture_tab[(x)].device; \ - obtained = data_capture_tab[(x)].obtained; \ - stopped = data_capture_tab[(x)].stopped; \ - frame_current = data_capture_tab[(x)].frame_current; \ - fps_capture = data_capture_tab[(x)].fps_capture; \ - texture = data_capture_tab[(x)].texture; \ - texture_updated = data_capture_tab[(x)].texture_updated; \ - - - - - -static SDL_CameraDeviceID get_instance_id(int index) { - int ret = 0; - int num = 0; - SDL_CameraDeviceID *devices; - devices = SDL_GetCameraDevices(&num); - if (devices) { - if (index >= 0 && index < num) { - ret = devices[index]; - } - SDL_free(devices); - } - - if (ret == 0) { -/* SDL_Log("invalid index"); */ - } - - return ret; -} - - - -int main(int argc, char **argv) -{ - SDL_Window *window = NULL; - SDL_Renderer *renderer = NULL; - SDL_Event evt; - int quit = 0; - - SDLTest_CommonState *state; - - int current_dev = 0; - measure_fps_t fps_main; - - - SDL_FRect r_playstop = { 50, 50, 120, 50 }; - SDL_FRect r_close = { 50 + (120 + 50) * 1, 50, 120, 50 }; - - SDL_FRect r_open = { 50 + (120 + 50) * 2, 50, 120, 50 }; - - SDL_FRect r_format = { 50 + (120 + 50) * 3, 50, 120, 50 }; - SDL_FRect r_listdev = { 50 + (120 + 50) * 4, 50, 120, 50 }; - - SDL_CameraDevice *device; - SDL_CameraSpec obtained; - int stopped = 0; - SDL_CameraFrame frame_current; - measure_fps_t fps_capture; - SDL_Texture *texture = NULL; - int texture_updated = 0; - - struct data_capture_t data_capture_tab[16]; - const int data_capture_tab_size = SDL_arraysize(data_capture_tab); - - SDL_zero(fps_main); - SDL_zero(fps_capture); - SDL_zero(frame_current); - SDL_zeroa(data_capture_tab); - - /* Set 0 to disable TouchEvent to be duplicated as MouseEvent with SDL_TOUCH_MOUSEID */ - SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); - /* Set 0 to disable MouseEvent to be duplicated as TouchEvent with SDL_MOUSE_TOUCHID */ - SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0"); - - { - int i; - for (i = 0; i < data_capture_tab_size; i++) { - data_capture_tab[i].device = NULL; - } - } + int devcount = 0; + int i; /* Initialize test framework */ state = SDLTest_CommonCreateState(argv, 0); if (state == NULL) { - return 1; + return -1; } /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - /* Parse commandline */ - { - int i; - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed <= 0) { - static const char *options[] = {NULL}; - SDLTest_CommonLogUsage(state, argv[0], options); - SDLTest_CommonDestroyState(state); - return 1; - } - - i += consumed; - } - } - - SDL_Log("%s", usage); - /* Load the SDL library */ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError()); - return 1; + return -1; } window = SDL_CreateWindow("Local Video", 1000, 800, 0); if (window == NULL) { SDL_Log("Couldn't create window: %s", SDL_GetError()); - return 1; + return -1; } SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); @@ -234,544 +55,143 @@ int main(int argc, char **argv) renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (renderer == NULL) { /* SDL_Log("Couldn't create renderer: %s", SDL_GetError()); */ - return 1; + return -1; } - SDL_LogSetAllPriority(SDL_LOG_PRIORITY_INFO); - - device = SDL_OpenCamera(0); - - if (!device) { - SDL_Log("Error SDL_OpenCamera: %s", SDL_GetError()); + SDL_CameraDeviceID *devices = SDL_GetCameraDevices(&devcount); + if (!devices) { + SDL_Log("SDL_GetCameraDevices failed: %s", SDL_GetError()); + return -1; } - { - /* List formats */ - int i, num = SDL_GetNumCameraFormats(device); - for (i = 0; i < num; i++) { - Uint32 format; - SDL_GetCameraFormat(device, i, &format); - SDL_Log("format %d/%d: %s", i, num, SDL_GetPixelFormatName(format)); - { - int w, h; - int j, num2 = SDL_GetNumCameraFrameSizes(device, format); - for (j = 0; j < num2; j++) { - SDL_GetCameraFrameSize(device, format, j, &w, &h); - SDL_Log(" framesizes %d/%d : %d x %d", j, num2, w, h); - } - } - } + SDL_Log("Saw %d camera devices.", devcount); + for (i = 0; i < devcount; i++) { + char *name = SDL_GetCameraDeviceName(devices[i]); + SDL_Log(" - Camera #%d: %s", i, name); + SDL_free(name); } - /* Set Spec */ - { - int ret; - /* forced_format */ - SDL_CameraSpec desired; - SDL_zero(desired); - desired.width = 640 * 2; - desired.height = 360 * 2; - desired.format = SDL_PIXELFORMAT_NV12; - ret = SDL_SetCameraSpec(device, &desired, &obtained, SDL_CAMERA_ALLOW_ANY_CHANGE); + const SDL_CameraDeviceID devid = devices[0]; /* just take the first one. */ + SDL_free(devices); - if (ret < 0) { - SDL_SetCameraSpec(device, NULL, &obtained, 0); - } + if (!devid) { + SDL_Log("No cameras available?"); + return -1; + } + + SDL_CameraSpec *pspec = NULL; + #if 0 /* just for edge-case testing purposes, ignore. */ + pspec = &spec; + spec.width = 100 /*1280 * 2*/; + spec.height = 100 /*720 * 2*/; + spec.format = SDL_PIXELFORMAT_YUY2 /*SDL_PIXELFORMAT_RGBA8888*/; + #endif + + camera = SDL_OpenCameraDevice(devid, pspec); + if (!camera) { + SDL_Log("Failed to open camera device: %s", SDL_GetError()); + return -1; } - SDL_Log("Open camera device. Obtained spec: size=%d x %d format=%s", - obtained.width, obtained.height, SDL_GetPixelFormatName(obtained.format)); + return 0; /* start the main app loop. */ +} - { - SDL_CameraSpec spec; - if (SDL_GetCameraFormat(device, &spec) == 0) { - SDL_Log("Read spec: size=%d x %d format=%s", - spec.width, spec.height, SDL_GetPixelFormatName(spec.format)); - } else { - SDL_Log("Error read spec: %s", SDL_GetError()); - } - } - - if (SDL_StartCamera(device) < 0) { - SDL_Log("error SDL_StartCamera(): %s", SDL_GetError()); - } - - while (!quit) { - - SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, 255); - SDL_RenderClear(renderer); - - SDL_SetRenderDrawColor(renderer, 0x33, 0x33, 0x33, 255); - - SDL_RenderFillRect(renderer, &r_playstop); - SDL_RenderFillRect(renderer, &r_close); - SDL_RenderFillRect(renderer, &r_open); - SDL_RenderFillRect(renderer, &r_format); - SDL_RenderFillRect(renderer, &r_listdev); - - SDL_SetRenderDrawColor(renderer, 0xcc, 0xcc, 0xcc, 255); - - SDLTest_DrawString(renderer, r_playstop.x + 5, r_playstop.y + 5, "play stop"); - SDLTest_DrawString(renderer, r_close.x + 5, r_close.y + 5, "close"); - SDLTest_DrawString(renderer, r_open.x + 5, r_open.y + 5, "open dev"); - SDLTest_DrawString(renderer, r_format.x + 5, r_format.y + 5, "formats"); - - { - char buf[256]; - SDL_snprintf(buf, 256, "device %d", current_dev); - SDLTest_DrawString(renderer, r_listdev.x + 5, r_listdev.y + 5, buf); - } - - while (SDL_PollEvent(&evt)) { - SDL_FRect *r = NULL; - SDL_FPoint pt; - int sym = 0; - - pt.x = 0; - pt.y = 0; - - SDL_ConvertEventToRenderCoordinates(renderer, &evt); - - switch (evt.type) - { - case SDL_EVENT_KEY_DOWN: - { - sym = evt.key.keysym.sym; - break; - } - case SDL_EVENT_QUIT: - { - quit = 1; - SDL_Log("Ctlr+C : Quit!"); - } - break; - - case SDL_EVENT_FINGER_DOWN: - { - pt.x = evt.tfinger.x; - pt.y = evt.tfinger.y; - } - break; - - case SDL_EVENT_MOUSE_BUTTON_DOWN: - { - pt.x = evt.button.x; - pt.y = evt.button.y; - } - break; - } - - if (pt.x != 0 && pt.y != 0) { - if (SDL_PointInRectFloat(&pt, &r_playstop)) { - r = &r_playstop; - sym = SDLK_s; - } - if (SDL_PointInRectFloat(&pt, &r_close)) { - r = &r_close; - sym = SDLK_c; - } - if (SDL_PointInRectFloat(&pt, &r_open)) { - r = &r_open; - sym = SDLK_o; - } - - if (SDL_PointInRectFloat(&pt, &r_format)) { - r = &r_format; - sym = SDLK_f; - } - if (SDL_PointInRectFloat(&pt, &r_listdev)) { - r = &r_listdev; - sym = SDLK_l; - } - } - - - if (r) { - SDL_SetRenderDrawColor(renderer, 0x33, 0, 0, 255); - SDL_RenderFillRect(renderer, r); - } - - - if (sym == SDLK_c) { - if (frame_current.num_planes) { - SDL_ReleaseCameraFrame(device, &frame_current); - } - SDL_CloseCamera(device); - device = NULL; - SDL_Log("Close"); - } - - if (sym == SDLK_o) { - if (device) { - SDL_Log("Close previous .."); - if (frame_current.num_planes) { - SDL_ReleaseCameraFrame(device, &frame_current); - } - SDL_CloseCamera(device); - } - - texture_updated = 0; - - SDL_ClearError(); - - SDL_Log("Try to open:%s", SDL_GetCameraDeviceName(get_instance_id(current_dev))); - - obtained.width = 640 * 2; - obtained.height = 360 * 2; - device = SDL_OpenCameraWithSpec(get_instance_id(current_dev), &obtained, &obtained, SDL_CAMERA_ALLOW_ANY_CHANGE); - - /* spec may have changed because of re-open */ - if (texture) { - SDL_DestroyTexture(texture); - texture = NULL; - } - - SDL_Log("Open device:%p %s", (void*)device, SDL_GetError()); - stopped = 0; - } - - if (sym == SDLK_l) { - int num = 0; - SDL_CameraDeviceID *devices; - int i; - devices = SDL_GetCameraDevices(&num); - - SDL_Log("Num devices : %d", num); - for (i = 0; i < num; i++) { - SDL_Log("Device %d/%d : %s", i, num, SDL_GetCameraDeviceName(devices[i])); - } - SDL_free(devices); - - SAVE_CAPTURE_STATE(current_dev); - - current_dev += 1; - if (current_dev >= num || current_dev >= (int) SDL_arraysize(data_capture_tab)) { - current_dev = 0; - } - - RESTORE_CAPTURE_STATE(current_dev); - SDL_Log("--> select dev %d / %d", current_dev, num); - } - - if (sym == SDLK_i) { - SDL_CameraStatus status = SDL_GetCameraStatus(device); - if (status == SDL_CAMERA_STOPPED) { SDL_Log("STOPPED"); } - if (status == SDL_CAMERA_PLAYING) { SDL_Log("PLAYING"); } - if (status == SDL_CAMERA_INIT) { SDL_Log("INIT"); } - } - - if (sym == SDLK_s) { - if (stopped) { - SDL_Log("Stop"); - SDL_StopCamera(device); - } else { - SDL_Log("Start"); - SDL_StartCamera(device); - } - stopped = !stopped; - } - - if (sym == SDLK_f) { - SDL_Log("List formats"); - - if (!device) { - device = SDL_OpenCamera(get_instance_id(current_dev)); - } - - /* List formats */ - { - int i, num = SDL_GetNumCameraFormats(device); - for (i = 0; i < num; i++) { - Uint32 format; - SDL_GetCameraFormat(device, i, &format); - SDL_Log("format %d/%d : %s", i, num, SDL_GetPixelFormatName(format)); - { - int w, h; - int j, num2 = SDL_GetNumCameraFrameSizes(device, format); - for (j = 0; j < num2; j++) { - SDL_GetCameraFrameSize(device, format, j, &w, &h); - SDL_Log(" framesizes %d/%d : %d x %d", j, num2, w, h); - } - } - } - } - } +int SDL_AppEvent(const SDL_Event *event) +{ + switch (event->type) { + case SDL_EVENT_KEY_DOWN: { + const SDL_Keycode sym = event->key.keysym.sym; if (sym == SDLK_ESCAPE || sym == SDLK_AC_BACK) { - quit = 1; SDL_Log("Key : Escape!"); + return 1; } - - if (sym == SDLK_h || sym == SDLK_F1) { - SDL_Log("%s", usage); - } + break; } + case SDL_EVENT_QUIT: + SDL_Log("Ctlr+C : Quit!"); + return 1; - SAVE_CAPTURE_STATE(current_dev); - - { - int i, n = SDL_arraysize(data_capture_tab); - for (i = 0; i < n; i++) { - RESTORE_CAPTURE_STATE(i); - - if (!device) { - /* device has been closed */ - frame_current.num_planes = 0; - texture_updated = 0; - } else { - int ret; - SDL_CameraFrame frame_next; - SDL_zero(frame_next); - - ret = SDL_AcquireCameraFrame(device, &frame_next); - if (ret < 0) { - SDL_Log("dev[%d] err SDL_AcquireCameraFrame: %s", i, SDL_GetError()); - } -#if 1 - if (frame_next.num_planes) { - SDL_Log("dev[%d] frame: %p at %" SDL_PRIu64, i, (void*)frame_next.data[0], frame_next.timestampNS); - } -#endif - - if (frame_next.num_planes) { - - update_fps(&fps_capture); - - if (frame_current.num_planes) { - ret = SDL_ReleaseCameraFrame(device, &frame_current); - if (ret < 0) { - SDL_Log("dev[%d] err SDL_ReleaseCameraFrame: %s", i, SDL_GetError()); - } - } - frame_current = frame_next; - texture_updated = 0; - } - } - - SAVE_CAPTURE_STATE(i); - } - } - - - RESTORE_CAPTURE_STATE(current_dev); - - - - /* Moving square */ - SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 255); - { - SDL_FRect r; - static float x = 0; - x += 10; - if (x > 1000) { - x = 0; - } - r.x = x; - r.y = 100; - r.w = r.h = 10; - SDL_RenderFillRect(renderer, &r); - } - - SDL_SetRenderDrawColor(renderer, 0x33, 0x33, 0x33, 255); - - - SAVE_CAPTURE_STATE(current_dev); - - { - int i, n = SDL_arraysize(data_capture_tab); - for (i = 0; i < n; i++) { - RESTORE_CAPTURE_STATE(i); - - /* Update SDL_Texture with last video frame (only once per new frame) */ - if (frame_current.num_planes && texture_updated == 0) { - - /* Create texture with appropriate format (for DMABUF or not) */ - if (texture == NULL) { - Uint32 format = obtained.format; - texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, obtained.width, obtained.height); - if (texture == NULL) { - SDL_Log("Couldn't create texture: %s", SDL_GetError()); - return 1; - } - } - - { - /* Use software data */ - if (frame_current.num_planes == 1) { - SDL_UpdateTexture(texture, NULL, - frame_current.data[0], frame_current.pitch[0]); - } else if (frame_current.num_planes == 2) { - SDL_UpdateNVTexture(texture, NULL, - frame_current.data[0], frame_current.pitch[0], - frame_current.data[1], frame_current.pitch[1]); - } else if (frame_current.num_planes == 3) { - SDL_UpdateYUVTexture(texture, NULL, frame_current.data[0], frame_current.pitch[0], - frame_current.data[1], frame_current.pitch[1], - frame_current.data[2], frame_current.pitch[2]); - } - texture_updated = 1; - } - } - - SAVE_CAPTURE_STATE(i); - } - } - - - RESTORE_CAPTURE_STATE(current_dev); - - { - int i, n = SDL_arraysize(data_capture_tab); - int win_w, win_h; - int total_texture_updated = 0; - int curr_texture_updated = 0; - for (i = 0; i < n; i++) { - if (data_capture_tab[i].texture_updated) { - total_texture_updated += 1; - } + case SDL_EVENT_CAMERA_DEVICE_APPROVED: + if (SDL_GetCameraFormat(camera, &spec) < 0) { + SDL_Log("Couldn't get camera spec: %s", SDL_GetError()); + return -1; } - SDL_GetRenderOutputSize(renderer, &win_w, &win_h); - - - for (i = 0; i < n; i++) { - RESTORE_CAPTURE_STATE(i); - /* RenderCopy the SDL_Texture */ - if (texture_updated == 1) { - /* Scale texture to fit the screen */ - - int tw, th; - int w; - SDL_FRect d; - SDL_QueryTexture(texture, NULL, NULL, &tw, &th); - - w = win_w / total_texture_updated; - - if (tw > w - 20) { - float scale = (float) (w - 20) / (float) tw; - tw = w - 20; - th = (int)((float) th * scale); - } - d.x = (float)(10 + curr_texture_updated * w); - d.y = (float)(win_h - th); - d.w = (float)tw; - d.h = (float)(th - 10); - SDL_RenderTexture(renderer, texture, NULL, &d); - - curr_texture_updated += 1; - } + /* Create texture with appropriate format */ + texture = SDL_CreateTexture(renderer, spec.format, SDL_TEXTUREACCESS_STATIC, spec.width, spec.height); + if (texture == NULL) { + SDL_Log("Couldn't create texture: %s", SDL_GetError()); + return -1; } + break; - } - - RESTORE_CAPTURE_STATE(current_dev); - - - /* display status and FPS */ - if (!device) { -#ifdef SDL_PLATFORM_IOS - const float x_offset = 500; -#else - const float x_offset = 0; -#endif - char buf[256]; - SDL_snprintf(buf, 256, "Device %d (%s) is not opened", current_dev, SDL_GetCameraDeviceName(get_instance_id(current_dev))); - SDLTest_DrawString(renderer, x_offset + 10, 10, buf); - } else { -#ifdef SDL_PLATFORM_IOS - const float x_offset = 500; -#else - const float x_offset = 0; -#endif - const char *status = "no status"; - char buf[256]; - - if (device) { - SDL_CameraStatus s = SDL_GetCameraStatus(device); - if (s == SDL_CAMERA_INIT) { - status = "init"; - } else if (s == SDL_CAMERA_PLAYING) { - status = "playing"; - } else if (s == SDL_CAMERA_STOPPED) { - status = "stopped"; - } else if (s == SDL_CAMERA_FAIL) { - status = "failed"; - } - - } - - /* capture device, capture fps, capture status */ - SDL_snprintf(buf, 256, "Device %d - %2.2f fps - %s", current_dev, fps_capture.last_fps, status); - SDLTest_DrawString(renderer, x_offset + 10, 10, buf); - - /* capture spec */ - SDL_snprintf(buf, sizeof(buf), "%d x %d %s", obtained.width, obtained.height, SDL_GetPixelFormatName(obtained.format)); - SDLTest_DrawString(renderer, x_offset + 10, 20, buf); - - /* video fps */ - SDL_snprintf(buf, sizeof(buf), "%2.2f fps", fps_main.last_fps); - SDLTest_DrawString(renderer, x_offset + 10, 30, buf); - - } - - /* display last error */ - { - SDLTest_DrawString(renderer, 400, 10, SDL_GetError()); - } - - /* display load average */ -#if defined(SDL_PLATFORM_LINUX) && !defined(SDL_PLATFORM_ANDROID) - { - float val = 0.0f; - char buf[128]; - load_average(&val); - if (val != 0.0f) { - SDL_snprintf(buf, sizeof(buf), "load avg %2.2f percent", val); - SDLTest_DrawString(renderer, 800, 10, buf); - } - } -#endif - - - SDL_Delay(20); - SDL_RenderPresent(renderer); - - update_fps(&fps_main); - + case SDL_EVENT_CAMERA_DEVICE_DENIED: + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Camera permission denied!", "User denied access to the camera!", window); + return -1; } + return SDLTest_CommonEventMainCallbacks(state, event); +} +int SDL_AppIterate(void) +{ + SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, 255); + SDL_RenderClear(renderer); - SAVE_CAPTURE_STATE(current_dev); + if (texture != NULL) { /* if not NULL, camera is ready to go. */ + int win_w, win_h, tw, th; + SDL_FRect d; + Uint64 timestampNS = 0; + SDL_Surface *frame_next = SDL_AcquireCameraFrame(camera, ×tampNS); - { - int i, n = SDL_arraysize(data_capture_tab); - for (i = 0; i < n; i++) { - RESTORE_CAPTURE_STATE(i); - - if (device) { - if (SDL_StopCamera(device) < 0) { - SDL_Log("error SDL_StopCamera(): %s", SDL_GetError()); - } - if (frame_current.num_planes) { - SDL_ReleaseCameraFrame(device, &frame_current); - } - SDL_CloseCamera(device); - } - - if (texture) { - SDL_DestroyTexture(texture); - } + #if 0 + if (frame_next) { + SDL_Log("frame: %p at %" SDL_PRIu64, (void*)frame_next->pixels, timestampNS); } + #endif + + if (frame_next) { + if (frame_current) { + if (SDL_ReleaseCameraFrame(camera, frame_current) < 0) { + SDL_Log("err SDL_ReleaseCameraFrame: %s", SDL_GetError()); + } + } + + /* It's not needed to keep the frame once updated the texture is updated. + * But in case of 0-copy, it's needed to have the frame while using the texture. + */ + frame_current = frame_next; + texture_updated = SDL_FALSE; + } + + /* Update SDL_Texture with last video frame (only once per new frame) */ + if (frame_current && !texture_updated) { + SDL_UpdateTexture(texture, NULL, frame_current->pixels, frame_current->pitch); + texture_updated = SDL_TRUE; + } + + SDL_QueryTexture(texture, NULL, NULL, &tw, &th); + SDL_GetRenderOutputSize(renderer, &win_w, &win_h); + d.x = (float) ((win_w - tw) / 2); + d.y = (float) ((win_h - th) / 2); + d.w = (float) tw; + d.h = (float) th; + SDL_RenderTexture(renderer, texture, NULL, &d); } + SDL_RenderPresent(renderer); + + return 0; /* keep iterating. */ +} + +void SDL_AppQuit(void) +{ + SDL_ReleaseCameraFrame(camera, frame_current); + SDL_CloseCamera(camera); + SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); - - SDL_Quit(); - SDLTest_CommonDestroyState(state); - - return 0; } -#endif \ No newline at end of file + diff --git a/test/testcameraminimal.c b/test/testcameraminimal.c deleted file mode 100644 index 9fc04c534..000000000 --- a/test/testcameraminimal.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright (C) 1997-2024 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely. -*/ - -#define SDL_MAIN_USE_CALLBACKS 1 -#include -#include -#include - -static SDL_Window *window = NULL; -static SDL_Renderer *renderer = NULL; -static SDLTest_CommonState *state = NULL; -static SDL_Camera *camera = NULL; -static SDL_CameraSpec spec; -static SDL_Texture *texture = NULL; -static SDL_bool texture_updated = SDL_FALSE; -static SDL_Surface *frame_current = NULL; - -int SDL_AppInit(int argc, char *argv[]) -{ - int devcount = 0; - int i; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, 0); - if (state == NULL) { - return -1; - } - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError()); - return -1; - } - - window = SDL_CreateWindow("Local Video", 1000, 800, 0); - if (window == NULL) { - SDL_Log("Couldn't create window: %s", SDL_GetError()); - return -1; - } - - SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); - - renderer = SDL_CreateRenderer(window, NULL, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); - if (renderer == NULL) { - /* SDL_Log("Couldn't create renderer: %s", SDL_GetError()); */ - return -1; - } - - SDL_CameraDeviceID *devices = SDL_GetCameraDevices(&devcount); - if (!devices) { - SDL_Log("SDL_GetCameraDevices failed: %s", SDL_GetError()); - return -1; - } - - SDL_Log("Saw %d camera devices.", devcount); - for (i = 0; i < devcount; i++) { - char *name = SDL_GetCameraDeviceName(devices[i]); - SDL_Log(" - Camera #%d: %s", i, name); - SDL_free(name); - } - - const SDL_CameraDeviceID devid = devices[0]; /* just take the first one. */ - SDL_free(devices); - - if (!devid) { - SDL_Log("No cameras available?"); - return -1; - } - - SDL_CameraSpec *pspec = NULL; - #if 0 /* just for edge-case testing purposes, ignore. */ - pspec = &spec; - spec.width = 100 /*1280 * 2*/; - spec.height = 100 /*720 * 2*/; - spec.format = SDL_PIXELFORMAT_YUY2 /*SDL_PIXELFORMAT_RGBA8888*/; - #endif - - camera = SDL_OpenCameraDevice(devid, pspec); - if (!camera) { - SDL_Log("Failed to open camera device: %s", SDL_GetError()); - return -1; - } - - return 0; /* start the main app loop. */ -} - -int SDL_AppEvent(const SDL_Event *event) -{ - switch (event->type) { - case SDL_EVENT_KEY_DOWN: { - const SDL_Keycode sym = event->key.keysym.sym; - if (sym == SDLK_ESCAPE || sym == SDLK_AC_BACK) { - SDL_Log("Key : Escape!"); - return 1; - } - break; - } - - case SDL_EVENT_QUIT: - SDL_Log("Ctlr+C : Quit!"); - return 1; - - case SDL_EVENT_CAMERA_DEVICE_APPROVED: - if (SDL_GetCameraFormat(camera, &spec) < 0) { - SDL_Log("Couldn't get camera spec: %s", SDL_GetError()); - return -1; - } - - /* Create texture with appropriate format */ - texture = SDL_CreateTexture(renderer, spec.format, SDL_TEXTUREACCESS_STATIC, spec.width, spec.height); - if (texture == NULL) { - SDL_Log("Couldn't create texture: %s", SDL_GetError()); - return -1; - } - break; - - case SDL_EVENT_CAMERA_DEVICE_DENIED: - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Camera permission denied!", "User denied access to the camera!", window); - return -1; - } - - return SDLTest_CommonEventMainCallbacks(state, event); -} - -int SDL_AppIterate(void) -{ - SDL_SetRenderDrawColor(renderer, 0x99, 0x99, 0x99, 255); - SDL_RenderClear(renderer); - - if (texture != NULL) { /* if not NULL, camera is ready to go. */ - int win_w, win_h, tw, th; - SDL_FRect d; - Uint64 timestampNS = 0; - SDL_Surface *frame_next = SDL_AcquireCameraFrame(camera, ×tampNS); - - #if 0 - if (frame_next) { - SDL_Log("frame: %p at %" SDL_PRIu64, (void*)frame_next->pixels, timestampNS); - } - #endif - - if (frame_next) { - if (frame_current) { - if (SDL_ReleaseCameraFrame(camera, frame_current) < 0) { - SDL_Log("err SDL_ReleaseCameraFrame: %s", SDL_GetError()); - } - } - - /* It's not needed to keep the frame once updated the texture is updated. - * But in case of 0-copy, it's needed to have the frame while using the texture. - */ - frame_current = frame_next; - texture_updated = SDL_FALSE; - } - - /* Update SDL_Texture with last video frame (only once per new frame) */ - if (frame_current && !texture_updated) { - SDL_UpdateTexture(texture, NULL, frame_current->pixels, frame_current->pitch); - texture_updated = SDL_TRUE; - } - - SDL_QueryTexture(texture, NULL, NULL, &tw, &th); - SDL_GetRenderOutputSize(renderer, &win_w, &win_h); - d.x = (float) ((win_w - tw) / 2); - d.y = (float) ((win_h - th) / 2); - d.w = (float) tw; - d.h = (float) th; - SDL_RenderTexture(renderer, texture, NULL, &d); - } - - SDL_RenderPresent(renderer); - - return 0; /* keep iterating. */ -} - -void SDL_AppQuit(void) -{ - SDL_ReleaseCameraFrame(camera, frame_current); - SDL_CloseCamera(camera); - SDL_DestroyTexture(texture); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDLTest_CommonDestroyState(state); -} -