From: Thomas Walker Lynch Date: Tue, 17 Sep 2024 21:54:57 +0000 (+0000) Subject: first commit X-Git-Url: https://git.reasoningtechnology.com/usr/lib/python2.7/quopri.py?a=commitdiff_plain;h=1729f8c0b6fd64c8fb554e0489cfcb5c5301ef2f;p=noflash first commit --- 1729f8c0b6fd64c8fb554e0489cfcb5c5301ef2f diff --git a/developer/Erebus/framebuffer_filter b/developer/Erebus/framebuffer_filter new file mode 100755 index 0000000..9b49c28 Binary files /dev/null and b/developer/Erebus/framebuffer_filter differ diff --git a/developer/Erebus/framebuffer_filter.c b/developer/Erebus/framebuffer_filter.c new file mode 100644 index 0000000..fefd64a --- /dev/null +++ b/developer/Erebus/framebuffer_filter.c @@ -0,0 +1,85 @@ +// gcc framebuffer_filter.c -o framebuffer_filter + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_DELTA 10 // Max pixel change allowed + +// Function to clamp a value within a certain range +unsigned char clamp(unsigned char current, unsigned char previous) { + if (current > previous + MAX_DELTA) + return previous + MAX_DELTA; + else if (current < previous - MAX_DELTA) + return previous - MAX_DELTA; + else + return current; +} + +int main() { + int fb_fd = open("/dev/fb0", O_RDWR); + if (fb_fd == -1) { + perror("Error: cannot open framebuffer device"); + return 1; + } + + struct fb_var_screeninfo vinfo; + if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) { + perror("Error reading variable information"); + close(fb_fd); + return 1; + } + + // Calculate the screen size + int screensize = vinfo.yres_virtual * vinfo.xres_virtual * vinfo.bits_per_pixel / 8; + + // Map framebuffer into memory + unsigned char *fb_ptr = (unsigned char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); + if ((intptr_t)fb_ptr == -1) { + perror("Error: failed to map framebuffer device to memory"); + close(fb_fd); + return 1; + } + + // Allocate memory for previous frame buffer + unsigned char *prev_frame = malloc(screensize); + if (!prev_frame) { + perror("Error: unable to allocate memory for previous frame"); + munmap(fb_ptr, screensize); + close(fb_fd); + return 1; + } + + // Initial copy of the framebuffer + memcpy(prev_frame, fb_ptr, screensize); + + // Frame processing loop + while (1) { + // Process each pixel (assuming 32 bits per pixel - adjust as needed) + for (int i = 0; i < screensize; i += 4) { + // R, G, B values + fb_ptr[i] = clamp(fb_ptr[i], prev_frame[i]); // Blue + fb_ptr[i + 1] = clamp(fb_ptr[i + 1], prev_frame[i + 1]); // Green + fb_ptr[i + 2] = clamp(fb_ptr[i + 2], prev_frame[i + 2]); // Red + // fb_ptr[i + 3] = Alpha channel, leave as is or modify if necessary + } + + // Copy current frame to previous frame for the next iteration + memcpy(prev_frame, fb_ptr, screensize); + + // Sleep to avoid high CPU usage + usleep(16000); // ~60 FPS + } + + // Clean up + free(prev_frame); + munmap(fb_ptr, screensize); + close(fb_fd); + + return 0; +} diff --git a/developer/Erebus/transform_frame_stream.c b/developer/Erebus/transform_frame_stream.c new file mode 100644 index 0000000..15ebf5f --- /dev/null +++ b/developer/Erebus/transform_frame_stream.c @@ -0,0 +1,369 @@ +// +// gcc -I/usr/include/libdrm drm_info.c -o transform_frame_stream -ldrm +// ./transform_frame_stream + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------------------------------------------------------------------------- +// Pixel + +// These pixels have hardware support ,and thus must be packed in the order +// expected by the hardware. +// 0xAARRGGBB +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; + }; + } PixelRGBA; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t alpha; + uint8_t red; + uint8_t green; + uint8_t blue; + }; + } PixelRGBA; +#else + #warning "Unknown __BYTE_ORDER__ found when packing a PixelRGBA." +#endif + +const PixelRGBA black = {.aggregate = 0xff000000}; +const PixelRGBA white = {.aggregate = 0xffffffff}; + +PixelRGBA·structure + ( + PixelRGBA *to_px + ,uint8_t red + ,uint8_t green + ,uint8_t blue + ,uint8_t alpha + ){ + px->blue = blue; + px->green = green; + px->red = red; + px->alpha = alpha; +} +PixelRGBA·destructure + ( + PixelRGBA *from_px + ,uint8_t *red + ,uint8_t *green + ,uint8_t *blue + ,uint8_t *alpha + ){ + *blue = from_px->blue; + *green = from_px->green; + *red = from_px->red; + *alpha = from_px->alpha; +} + + +// -------------------------------------------------------------------------------- +// Frame + +typedef struct __attribute__((packed)){ + uint32_t width; + uint32_t height; + PixelRGBA data[]; +} FrameRGBA; + +FrameRGBA·alloc(int width ,int height){ + bool null_frame = false; + + if( width == 0 ){ + fprintf(stderr, "FrameRGBA·alloc:: frame width of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if( height == 0 ){ + fprintf(stderr, "FrameRGBA·alloc:: frame height of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if(null_frame) return NULL; + + FrameRGBA *frame = malloc(sizeof(FrameRGBA)); + if(!frame){ + fprintf(stderr ,"FrameRGBA·alloc::failed to allocate frame\n"); + null_frame = true; + } + frame->data = malloc( width * height * sizeof(int) ); + if(!frame->data){ + fprintf(stderr ,"FrameRGBA·alloc::failed to allocate frame data\n"); + null_frame = true; + } + if(null_frame) return NULL; + + frame->width = width; + frame->height = height; + return frame; +} +FrameRGBA·alloc_same(Frame_data *frame){ + if(!frame) return NULL; + return alloc(frame->width ,frame->height); +} +FrameRGBA·dealloc(FrameRGBA *frame){ + free(frame); +} + +FrameRGBA·dimensions(FrameRGBA *frame ,uint32_t *width ,uint32_t *height){ + if(!frame){ + *width = 0; + *height = 0; + return; + } + *width = frame->width; + *height = frame->height; +} + +// both frames have already been allocated +FrameRGBA·copy(FrameRGBA *from_frame ,FrameRGBA **to_frame_arg){ + if(to_frame_arg == NULL) return; + if(*to_frame_arg == NULL) return; + if( from_frame == NULL ){ + *to_frame = NULL; + return; + } + FrameRGBA *to_frame = *to_frame_arg; + + int32_t width, height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(**to_frame.width < width){ + width = to_frame.width; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is wider than to_frame ,there will be truncation\n"); + }else if(to_frame.width > width){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is wider, so stale uninitialized pixels will remain at the end of scan lines.\n"); + } + if(to_frame.height < height){ + height = to_frame.height; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is taller than to_frame ,there will be truncation\n"); + }else if(to_frame.height > height){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is taller, so stale or uninitialized scan lines will remain at the bottom of the frame.\n"); + } + + int32_t j = 0; + int32_t offset = 0; + do{ + memcpy( + from_frame->data + offset + ,to_frame-data + ,width * sizeof(PixelRGBA) + ); + offset += width; + j++; + }while(j <= height); +} +// if i and j walk out of frame returns NULL +PixelRGB *FrameRGBA·access(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + int32_t width, height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(i > width) return NULL; + if(j > height) return NULL; + uint32_t line_size = from_frame->width * sizeof(PixelRGB); + return from_frame->data + j*line_size + i*sizeof(PixelRGB); +} +PixelRGB FrameRGBA·read(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + return *FrameRGBA·access(FrameRGBA *from_frame ,uint32_t i ,uint32_t j); +} +void FrameRGBA·write(FrameRGBA *to_frame ,uint32_t i ,uint32_t j ,PixelRGBA px){ + *FrameRGBA·access(FrameRGBA *from_frame ,uint32_t i ,uint32_t j) = px; +} + +// search frame for condition where f returns a non-null pointer +// f is handed successive pointers to pixels in the frame. +// f is given the frame in case it needs context. +// f is given an argument is it is difficult to curry functions in C. +void *FrameRGBA·exist +( + FrameRGBA *frame + ,void *f(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + + if(!frame) return NULL; + + void *item; + int32_t width, height; + FrameRGBA·dimensions(frame ,&width ,&height); + int32_t i = 0; + int32_t j = 0; + do{ + PixelRGBA *px = FrameRGBA·access(frame ,i ,j); + if( item=f(frame ,px ,arg) ) return item; + + if(i == width){ + i = 0; + j++; + }else{ + i++; + } + }while(j <= height); + return NULL; +} + +typedef struct{ + void f(FrameRGBA *frame ,PixelRGBA *px ,void *arg) f; + void *arg; +} every_arg_t; +void *(*every_f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg0){ + every_arg_t *ea = arg0; + ea->f(frame ,px ,ea->arg); + return NULL; +} +void *FrameRGBA·every +( + FrameRGBA *frame + ,void *f(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + ever_arg_t ea = {.f = f ,.arg = arg}; + FrameRGBA·exist(to_frame ,ever_f ,&ea); +} + +void (*fill_f)(FrameRGBA *to_frame ,PixelRGBA *to_px ,void *arg){ + PixelRGBA *px = arg; + *to_px = *px; + return NULL; +} +FrameRGBA·fill(Frame_data *to_frame ,PixelRGB *fill_px){ + FrameRGBA·every(to_frame ,fill_f ,fill_px); +} +FrameRGBA·fill_black(Frame_data *to_frame){ + FrameRGBA·fill(to_frame ,&black); +} +FrameRGBA·fill_white(Frame_data *to_frame){ + FrameRGBA·fill(to_frame ,&black); +} + +// -------------------------------------------------------------------------------- +// Transform functions +// Given the previous frame, current frame, and an argument; modifies the +// current frame. + +int identity_transform(FrameRGBA *prev_frame ,FrameRGBA *curr_frame ,void *args){ + // no processing in the identity transform + copy_FrameRGBA(curr_frame ,prev_frame); + return 0; // Success +} + +// -------------------------------------------------------------------------------- +// transform frame stream + +int transform_frame_stream(int (*transform)(FrameRGBA * ,FrameRGBA * ,void *) ,void *transform_args){ + // Simulated screen info (would be fetched from the actual DRM system) + FrameRGBA *prev_frame = Framedata·alloc(3840 ,2400); + FrameRGBA *curr_frame = Framedata·alloc_same(prev_frame); + + // Fornow ,we'll simulate grabbing the first frame by filling it with random values. + // In the real implementation ,you will fetch the current frame data from the DRM API. + for(int i = 0; i < width * height; i++){ + curr_frame.data[i] = rand(); // Simulate grabbing a frame with random pixel data + } + + // Call the transform function forthe first frame (identity in this case) + transform(&prev_frame ,&curr_frame ,transform_args); + + // Main processing loop (simplified to one iteration fornow) + while (1){ + // Simulate grabbing the next frame (we just reuse the current one forthis example) + // In real code ,you would fetch the next frame from the DRM system here. + + // Call the transform function foreach new frame + transform(&prev_frame ,&curr_frame ,transform_args); + + // Copy current frame to previous frame (fornext iteration) + memcpy(prev_frame.data ,curr_frame.data ,width * height * sizeof(unsigned int)); + + break; // Exit after one loop forthis example (replace with continuous loop in real implementation) + } + + // Clean up memory + free(prev_frame.data); + free(curr_frame.data); + + return 0; // Success +} + +int main(int argc ,char **argv){ + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2" ,O_RDWR | O_CLOEXEC); + if(fd < 0){ + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if(!resources){ + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for(int i = 0; i < resources->count_connectors; i++){ + connector = drmModeGetConnector(fd ,resources->connectors[i]); + if(connector->connection == DRM_MODE_CONNECTED){ + break; + } + drmModeFreeConnector(connector); + } + + if(!connector || connector->connection != DRM_MODE_CONNECTED){ + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd ,connector->encoder_id); + if(!encoder){ + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd ,encoder->crtc_id); + if(!crtc){ + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Call transform_frame_stream with identity transform + transform_frame_stream(identity_transform ,NULL); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return 0; +} diff --git a/developer/Erebus/transform_frame_stream.c~ b/developer/Erebus/transform_frame_stream.c~ new file mode 100644 index 0000000..f45ce5d --- /dev/null +++ b/developer/Erebus/transform_frame_stream.c~ @@ -0,0 +1,89 @@ +// gcc -I/usr/include/libdrm drm_info.c -o drm_info -ldrm +// ./drm_info + + + +#include +#include +#include +#include +#include + + +int transform_frame_stream(){ + printf("Framebuffer ID: %d\n", crtc->buffer_id); + printf("Resolution: %dx%d\n", crtc->width, crtc->height); +} + +// no argument parsing for this first version. +int main(int argc ,char **arc ,char **envp){ + + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2", O_RDWR | O_CLOEXEC); + if (fd < 0) { + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if (!resources) { + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for (int i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(fd, resources->connectors[i]); + if (connector->connection == DRM_MODE_CONNECTED) { + break; + } + drmModeFreeConnector(connector); + } + + if (!connector || connector->connection != DRM_MODE_CONNECTED) { + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd, connector->encoder_id); + if (!encoder) { + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd, encoder->crtc_id); + if (!crtc) { + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + int error; + error = transform_frame_stream(crtc->buffer); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return error; +} diff --git a/developer/Erebus/transform_frames.c b/developer/Erebus/transform_frames.c new file mode 100644 index 0000000..f45ce5d --- /dev/null +++ b/developer/Erebus/transform_frames.c @@ -0,0 +1,89 @@ +// gcc -I/usr/include/libdrm drm_info.c -o drm_info -ldrm +// ./drm_info + + + +#include +#include +#include +#include +#include + + +int transform_frame_stream(){ + printf("Framebuffer ID: %d\n", crtc->buffer_id); + printf("Resolution: %dx%d\n", crtc->width, crtc->height); +} + +// no argument parsing for this first version. +int main(int argc ,char **arc ,char **envp){ + + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2", O_RDWR | O_CLOEXEC); + if (fd < 0) { + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if (!resources) { + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for (int i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(fd, resources->connectors[i]); + if (connector->connection == DRM_MODE_CONNECTED) { + break; + } + drmModeFreeConnector(connector); + } + + if (!connector || connector->connection != DRM_MODE_CONNECTED) { + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd, connector->encoder_id); + if (!encoder) { + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd, encoder->crtc_id); + if (!crtc) { + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + int error; + error = transform_frame_stream(crtc->buffer); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return error; +} diff --git a/developer/Erebus/transform_frames.c~ b/developer/Erebus/transform_frames.c~ new file mode 100644 index 0000000..dad6da8 --- /dev/null +++ b/developer/Erebus/transform_frames.c~ @@ -0,0 +1,81 @@ +// gcc -I/usr/include/libdrm drm_info.c -o drm_info -ldrm +// ./drm_info + + + +#include +#include +#include +#include +#include + +int main() { + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2", O_RDWR | O_CLOEXEC); + if (fd < 0) { + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if (!resources) { + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for (int i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(fd, resources->connectors[i]); + if (connector->connection == DRM_MODE_CONNECTED) { + break; + } + drmModeFreeConnector(connector); + } + + if (!connector || connector->connection != DRM_MODE_CONNECTED) { + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd, connector->encoder_id); + if (!encoder) { + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd, encoder->crtc_id); + if (!crtc) { + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + printf("Framebuffer ID: %d\n", crtc->buffer_id); + printf("Resolution: %dx%d\n", crtc->width, crtc->height); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return 0; +} diff --git a/developer/cc/drm_info b/developer/cc/drm_info new file mode 100755 index 0000000..3722f7c Binary files /dev/null and b/developer/cc/drm_info differ diff --git a/developer/cc/drm_info.c b/developer/cc/drm_info.c new file mode 100644 index 0000000..dad6da8 --- /dev/null +++ b/developer/cc/drm_info.c @@ -0,0 +1,81 @@ +// gcc -I/usr/include/libdrm drm_info.c -o drm_info -ldrm +// ./drm_info + + + +#include +#include +#include +#include +#include + +int main() { + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2", O_RDWR | O_CLOEXEC); + if (fd < 0) { + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if (!resources) { + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for (int i = 0; i < resources->count_connectors; i++) { + connector = drmModeGetConnector(fd, resources->connectors[i]); + if (connector->connection == DRM_MODE_CONNECTED) { + break; + } + drmModeFreeConnector(connector); + } + + if (!connector || connector->connection != DRM_MODE_CONNECTED) { + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd, connector->encoder_id); + if (!encoder) { + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd, encoder->crtc_id); + if (!crtc) { + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + printf("Framebuffer ID: %d\n", crtc->buffer_id); + printf("Resolution: %dx%d\n", crtc->width, crtc->height); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return 0; +} diff --git a/developer/cc/modified_transform_frame_stream.c b/developer/cc/modified_transform_frame_stream.c new file mode 100644 index 0000000..7e1a824 --- /dev/null +++ b/developer/cc/modified_transform_frame_stream.c @@ -0,0 +1,136 @@ + +// gcc -I/usr/include/libdrm transform_frame_stream.c -o transform_frame_stream -ldrm +// ./transform_frame_stream + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------------------------------------------------------------------------- +// Pixel + +#if __BYTE_ORDER == __LITTLE_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; + }; + } PixelRGBA; +#elif __BYTE_ORDER == __BIG_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t alpha; + uint8_t red; + uint8_t green; + uint8_t blue; + }; + } PixelRGBA; +#else + #warning "Unknown __BYTE_ORDER__ found when packing a PixelRGBA." +#endif + +PixelRGBA black = {.aggregate = 0xff000000}; +PixelRGBA white = {.aggregate = 0xffffffff}; + +void PixelRGBA_structure(PixelRGBA *px, uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha){ + px->blue = blue; + px->green = green; + px->red = red; + px->alpha = alpha; +} + +void PixelRGBA_destructure(PixelRGBA *px, uint8_t *red, uint8_t *green, uint8_t *blue, uint8_t *alpha){ + *blue = px->blue; + *green = px->green; + *red = px->red; + *alpha = px->alpha; +} + +PixelRGBA PixelRGBA_random(){ + PixelRGBA px; + px.aggregate = rand(); + return px; +} + +// -------------------------------------------------------------------------------- +// Frame + +typedef struct{ + uint32_t width; + uint32_t height; + PixelRGBA data[]; +} FrameRGBA; + +FrameRGBA *FrameRGBA_alloc(int width ,int height){ + if(width == 0 || height == 0){ + fprintf(stderr, "FrameRGBA_alloc: Invalid frame dimensions\n"); + return NULL; + } + + FrameRGBA *frame = (FrameRGBA *)malloc(sizeof(FrameRGBA) + width * height * sizeof(PixelRGBA)); + if(!frame){ + fprintf(stderr, "Failed to allocate memory for frame\n"); + return NULL; + } + + frame->width = width; + frame->height = height; + + // Initialize frame with random pixels for now (could be replaced with real frame data later) + for(int i = 0; i < width * height; i++){ + frame->data[i] = PixelRGBA_random(); + } + + return frame; +} + +void FrameRGBA_free(FrameRGBA *frame){ + if(frame){ + free(frame); + } +} + +// -------------------------------------------------------------------------------- +// Identity Transform + +void apply_identity_transform(FrameRGBA *frame){ + // This is an identity transform, so nothing is changed in the frame + printf("Applying identity transform to frame\n"); + // Normally, transformations would modify the frame data here +} + +// -------------------------------------------------------------------------------- +// Main function to grab frames and apply identity transform + +int main(){ + // Simulating grabbing a frame with fixed dimensions for now + int width = 640; + int height = 480; + + FrameRGBA *frame = FrameRGBA_alloc(width, height); + if(!frame){ + return EXIT_FAILURE; + } + + // Apply identity transform (does nothing) + apply_identity_transform(frame); + + // Simulate some output (e.g., saving frame, displaying, etc.) + printf("Frame processed and passed through identity transform\n"); + + // Clean up + FrameRGBA_free(frame); + + return EXIT_SUCCESS; +} diff --git a/developer/cc/transform_frame_stream b/developer/cc/transform_frame_stream new file mode 100755 index 0000000..179a668 Binary files /dev/null and b/developer/cc/transform_frame_stream differ diff --git a/developer/cc/transform_frame_stream.c b/developer/cc/transform_frame_stream.c new file mode 100644 index 0000000..322caf6 --- /dev/null +++ b/developer/cc/transform_frame_stream.c @@ -0,0 +1,386 @@ +// +// gcc -I/usr/include/libdrm transform_frame_stream.c -o transform_frame_stream -ldrm +// ./transform_frame_stream + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------------------------------------------------------------------------- +// Pixel + +// These pixels have hardware support ,and thus must be packed in the order +// expected by the hardware. +// 0xAARRGGBB +#if __BYTE_ORDER == __LITTLE_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; + }; + } PixelRGBA; +#elif __BYTE_ORDER == __BIG_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t alpha; + uint8_t red; + uint8_t green; + uint8_t blue; + }; + } PixelRGBA; +#else + #warning "Unknown __BYTE_ORDER__ found when packing a PixelRGBA." +#endif + +PixelRGBA black = {.aggregate = 0xff000000}; +PixelRGBA white = {.aggregate = 0xffffffff}; + +void PixelRGBA·structure + ( + PixelRGBA *px + ,uint8_t red + ,uint8_t green + ,uint8_t blue + ,uint8_t alpha + ){ + px->blue = blue; + px->green = green; + px->red = red; + px->alpha = alpha; +} +void PixelRGBA·destructure + ( + PixelRGBA *px + ,uint8_t *red + ,uint8_t *green + ,uint8_t *blue + ,uint8_t *alpha + ){ + *blue = px->blue; + *green = px->green; + *red = px->red; + *alpha = px->alpha; +} + +PixelRGBA PixelRGBA·random(){ + PixelRGBA px; + px.aggregate = rand(); + return px; +} + + + +// -------------------------------------------------------------------------------- +// Frame + +typedef struct{ + uint32_t width; + uint32_t height; + PixelRGBA data[]; +} FrameRGBA; + +FrameRGBA *FrameRGBA·alloc(int width ,int height){ + bool null_frame = false; + + if( width == 0 ){ + fprintf(stderr ,"FrameRGBA·alloc:: frame width of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if( height == 0 ){ + fprintf(stderr ,"FrameRGBA·alloc:: frame height of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if(null_frame) return NULL; + + size_t size = sizeof(FrameRGBA) + width * height * sizeof(PixelRGBA); + FrameRGBA *frame = malloc(size); + if(!frame){ + fprintf(stderr ,"FrameRGBA·alloc::failed to allocate frame\n"); + return NULL; + } + + frame->width = width; + frame->height = height; + return frame; +} + +FrameRGBA *FrameRGBA·alloc_same(FrameRGBA *frame){ + if(!frame) return NULL; + return FrameRGBA·alloc(frame->width ,frame->height); +} + +void FrameRGBA·dealloc(FrameRGBA *frame){ + free(frame); +} + +void FrameRGBA·dimensions(FrameRGBA *frame ,uint32_t *width ,uint32_t *height){ + if(!frame){ + *width = 0; + *height = 0; + return; + } + *width = frame->width; + *height = frame->height; +} + +// both frames have already been allocated +void FrameRGBA·copy(FrameRGBA *from_frame ,FrameRGBA **to_frame_arg){ + if( to_frame_arg == NULL ) return; + if(*to_frame_arg == NULL) return; + if( from_frame == NULL ){ + *to_frame_arg = NULL; + return; + } + FrameRGBA *to_frame = *to_frame_arg; + + uint32_t width ,height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(to_frame->width < width){ + width = to_frame->width; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is wider than to_frame, there will be truncation\n"); + }else if(to_frame->width > width){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is wider, so stale uninitialized pixels will remain at the end of scan lines.\n"); + } + if(to_frame->height < height){ + height = to_frame->height; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is taller than to_frame, there will be truncation\n"); + }else if(to_frame->height > height){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is taller, so stale or uninitialized scan lines will remain at the bottom of the frame.\n"); + } + + uint32_t j = 0; + uint32_t offset = 0; + do{ + memcpy( + to_frame->data + offset, + from_frame->data + offset, + width * sizeof(PixelRGBA) + ); + offset += width; + j++; + }while(j < height); +} + +// if i and j walk out of frame returns NULL +PixelRGBA *FrameRGBA·access(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + uint32_t width ,height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(i >= width) return NULL; + if(j >= height) return NULL; + return &(from_frame->data[j * width + i]); +} + +PixelRGBA FrameRGBA·read(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + return *FrameRGBA·access(from_frame ,i ,j); +} + +void FrameRGBA·write(FrameRGBA *to_frame ,uint32_t i ,uint32_t j ,PixelRGBA px){ + *FrameRGBA·access(to_frame ,i ,j) = px; +} + +// search frame for condition where f returns a non-null pointer +// f is handed successive pointers to pixels in the frame. +// f is given the frame in case it needs context. +// f is given an argument is it is difficult to curry functions in C. +void *FrameRGBA·exist +( + FrameRGBA *frame + ,void *(*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + + if(!frame) return NULL; + + void *item; + uint32_t width ,height; + FrameRGBA·dimensions(frame ,&width ,&height); + uint32_t i = 0; + uint32_t j = 0; + do{ + PixelRGBA *px = FrameRGBA·access(frame ,i ,j); + if( item=f(frame ,px ,arg) ) return item; + + if( i == width - 1 ){ + i = 0; + j++; + }else{ + i++; + } + }while(j < height); + return NULL; +} + +typedef struct{ + void (*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg); + void *arg; +} every_arg_t; + +void *every_f(FrameRGBA *frame ,PixelRGBA *px ,void *arg0){ + every_arg_t *ea = arg0; + ea->f(frame ,px ,ea->arg); + return NULL; +} +void FrameRGBA·every +( + FrameRGBA *frame + ,void (*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + every_arg_t ea = {.f = f ,.arg = arg}; + FrameRGBA·exist(frame ,every_f ,&ea); +} + +void fill_f(FrameRGBA *to_frame ,PixelRGBA *to_px ,void *arg){ + PixelRGBA *px = arg; + *to_px = *px; +} +void FrameRGBA·fill(FrameRGBA *to_frame ,PixelRGBA *fill_px){ + FrameRGBA·every(to_frame ,fill_f ,fill_px); +} + +void FrameRGBA·fill_black(FrameRGBA *to_frame){ + FrameRGBA·fill(to_frame ,&black); +} + +void FrameRGBA·fill_white(FrameRGBA *to_frame){ + FrameRGBA·fill(to_frame ,&white); +} + +void fill_random_f(FrameRGBA *frame ,PixelRGBA *px ,void *arg){ + *px = PixelRGBA·random(); +} +void FrameRGBA·fill_random(FrameRGBA *frame){ + if(!frame) return; + FrameRGBA·every(frame ,fill_random_f ,NULL); +} + + +// -------------------------------------------------------------------------------- +// Transform functions +// Given the previous frame ,current frame ,and an argument; modifies the +// current frame. + +int identity_transform(FrameRGBA *prev_frame ,FrameRGBA *curr_frame ,void *args){ + // no processing in the identity transform + FrameRGBA·copy(prev_frame ,&curr_frame); + return 0; // Success +} + +// -------------------------------------------------------------------------------- +// transform frame stream + +int transform_frame_stream(int (*transform)(FrameRGBA * ,FrameRGBA * ,void *) ,void *transform_args){ + // Simulated screen info (would be fetched from the actual DRM system) + FrameRGBA *prev_frame = FrameRGBA·alloc(3840 ,2400); + FrameRGBA *curr_frame = FrameRGBA·alloc_same(prev_frame); + + // For now ,we'll simulate grabbing the first frame by filling it with random values. + // In the real implementation ,you will fetch the current frame data from the DRM API. + uint32_t width ,height; + FrameRGBA·dimensions(curr_frame ,&width ,&height); + FrameRGBA·fill_random(curr_frame); + + // Call the transform function for the first frame (identity in this case) + transform(prev_frame ,curr_frame ,transform_args); + + // Main processing loop (simplified to one iteration for now) + while(1){ + // Simulate grabbing the next frame (we just reuse the current one for this example) + // In real code ,you would fetch the next frame from the DRM system here. + FrameRGBA·fill_random(curr_frame); + + // Call the transform function for each new frame + transform(prev_frame ,curr_frame ,transform_args); + FrameRGBA·copy(curr_frame ,&prev_frame); + + break; // Exit after one loop for this example (replace with continuous loop in real implementation) + } + + // Clean up memory + FrameRGBA·dealloc(prev_frame); + FrameRGBA·dealloc(curr_frame); + + return 0; // Success +} + +int main(int argc ,char **argv){ + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2",O_RDWR | O_CLOEXEC); + if(fd < 0){ + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if(!resources){ + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for(int i = 0; i < resources->count_connectors; i++){ + connector = drmModeGetConnector(fd ,resources->connectors[i]); + if(connector->connection == DRM_MODE_CONNECTED){ + break; + } + drmModeFreeConnector(connector); + } + + if(!connector || connector->connection != DRM_MODE_CONNECTED){ + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd ,connector->encoder_id); + if(!encoder){ + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd ,encoder->crtc_id); + if(!crtc){ + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Call transform_frame_stream with identity transform + transform_frame_stream(identity_transform ,NULL); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return 0; +} diff --git a/developer/cc/transform_frame_stream_2.c b/developer/cc/transform_frame_stream_2.c new file mode 100644 index 0000000..322caf6 --- /dev/null +++ b/developer/cc/transform_frame_stream_2.c @@ -0,0 +1,386 @@ +// +// gcc -I/usr/include/libdrm transform_frame_stream.c -o transform_frame_stream -ldrm +// ./transform_frame_stream + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// -------------------------------------------------------------------------------- +// Pixel + +// These pixels have hardware support ,and thus must be packed in the order +// expected by the hardware. +// 0xAARRGGBB +#if __BYTE_ORDER == __LITTLE_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t blue; + uint8_t green; + uint8_t red; + uint8_t alpha; + }; + } PixelRGBA; +#elif __BYTE_ORDER == __BIG_ENDIAN + typedef union{ + uint32_t aggregate; + struct __attribute__((packed)) { + uint8_t alpha; + uint8_t red; + uint8_t green; + uint8_t blue; + }; + } PixelRGBA; +#else + #warning "Unknown __BYTE_ORDER__ found when packing a PixelRGBA." +#endif + +PixelRGBA black = {.aggregate = 0xff000000}; +PixelRGBA white = {.aggregate = 0xffffffff}; + +void PixelRGBA·structure + ( + PixelRGBA *px + ,uint8_t red + ,uint8_t green + ,uint8_t blue + ,uint8_t alpha + ){ + px->blue = blue; + px->green = green; + px->red = red; + px->alpha = alpha; +} +void PixelRGBA·destructure + ( + PixelRGBA *px + ,uint8_t *red + ,uint8_t *green + ,uint8_t *blue + ,uint8_t *alpha + ){ + *blue = px->blue; + *green = px->green; + *red = px->red; + *alpha = px->alpha; +} + +PixelRGBA PixelRGBA·random(){ + PixelRGBA px; + px.aggregate = rand(); + return px; +} + + + +// -------------------------------------------------------------------------------- +// Frame + +typedef struct{ + uint32_t width; + uint32_t height; + PixelRGBA data[]; +} FrameRGBA; + +FrameRGBA *FrameRGBA·alloc(int width ,int height){ + bool null_frame = false; + + if( width == 0 ){ + fprintf(stderr ,"FrameRGBA·alloc:: frame width of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if( height == 0 ){ + fprintf(stderr ,"FrameRGBA·alloc:: frame height of zero, so returning a null frame pointer\n"); + null_frame = true; + } + if(null_frame) return NULL; + + size_t size = sizeof(FrameRGBA) + width * height * sizeof(PixelRGBA); + FrameRGBA *frame = malloc(size); + if(!frame){ + fprintf(stderr ,"FrameRGBA·alloc::failed to allocate frame\n"); + return NULL; + } + + frame->width = width; + frame->height = height; + return frame; +} + +FrameRGBA *FrameRGBA·alloc_same(FrameRGBA *frame){ + if(!frame) return NULL; + return FrameRGBA·alloc(frame->width ,frame->height); +} + +void FrameRGBA·dealloc(FrameRGBA *frame){ + free(frame); +} + +void FrameRGBA·dimensions(FrameRGBA *frame ,uint32_t *width ,uint32_t *height){ + if(!frame){ + *width = 0; + *height = 0; + return; + } + *width = frame->width; + *height = frame->height; +} + +// both frames have already been allocated +void FrameRGBA·copy(FrameRGBA *from_frame ,FrameRGBA **to_frame_arg){ + if( to_frame_arg == NULL ) return; + if(*to_frame_arg == NULL) return; + if( from_frame == NULL ){ + *to_frame_arg = NULL; + return; + } + FrameRGBA *to_frame = *to_frame_arg; + + uint32_t width ,height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(to_frame->width < width){ + width = to_frame->width; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is wider than to_frame, there will be truncation\n"); + }else if(to_frame->width > width){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is wider, so stale uninitialized pixels will remain at the end of scan lines.\n"); + } + if(to_frame->height < height){ + height = to_frame->height; + fprintf(stderr ,"FrameRGBA·copy:: from_frame is taller than to_frame, there will be truncation\n"); + }else if(to_frame->height > height){ + fprintf(stderr ,"FrameRGBA·copy:: to_frame is taller, so stale or uninitialized scan lines will remain at the bottom of the frame.\n"); + } + + uint32_t j = 0; + uint32_t offset = 0; + do{ + memcpy( + to_frame->data + offset, + from_frame->data + offset, + width * sizeof(PixelRGBA) + ); + offset += width; + j++; + }while(j < height); +} + +// if i and j walk out of frame returns NULL +PixelRGBA *FrameRGBA·access(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + uint32_t width ,height; + FrameRGBA·dimensions(from_frame ,&width ,&height); + if(i >= width) return NULL; + if(j >= height) return NULL; + return &(from_frame->data[j * width + i]); +} + +PixelRGBA FrameRGBA·read(FrameRGBA *from_frame ,uint32_t i ,uint32_t j){ + return *FrameRGBA·access(from_frame ,i ,j); +} + +void FrameRGBA·write(FrameRGBA *to_frame ,uint32_t i ,uint32_t j ,PixelRGBA px){ + *FrameRGBA·access(to_frame ,i ,j) = px; +} + +// search frame for condition where f returns a non-null pointer +// f is handed successive pointers to pixels in the frame. +// f is given the frame in case it needs context. +// f is given an argument is it is difficult to curry functions in C. +void *FrameRGBA·exist +( + FrameRGBA *frame + ,void *(*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + + if(!frame) return NULL; + + void *item; + uint32_t width ,height; + FrameRGBA·dimensions(frame ,&width ,&height); + uint32_t i = 0; + uint32_t j = 0; + do{ + PixelRGBA *px = FrameRGBA·access(frame ,i ,j); + if( item=f(frame ,px ,arg) ) return item; + + if( i == width - 1 ){ + i = 0; + j++; + }else{ + i++; + } + }while(j < height); + return NULL; +} + +typedef struct{ + void (*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg); + void *arg; +} every_arg_t; + +void *every_f(FrameRGBA *frame ,PixelRGBA *px ,void *arg0){ + every_arg_t *ea = arg0; + ea->f(frame ,px ,ea->arg); + return NULL; +} +void FrameRGBA·every +( + FrameRGBA *frame + ,void (*f)(FrameRGBA *frame ,PixelRGBA *px ,void *arg) + ,void *arg + ){ + every_arg_t ea = {.f = f ,.arg = arg}; + FrameRGBA·exist(frame ,every_f ,&ea); +} + +void fill_f(FrameRGBA *to_frame ,PixelRGBA *to_px ,void *arg){ + PixelRGBA *px = arg; + *to_px = *px; +} +void FrameRGBA·fill(FrameRGBA *to_frame ,PixelRGBA *fill_px){ + FrameRGBA·every(to_frame ,fill_f ,fill_px); +} + +void FrameRGBA·fill_black(FrameRGBA *to_frame){ + FrameRGBA·fill(to_frame ,&black); +} + +void FrameRGBA·fill_white(FrameRGBA *to_frame){ + FrameRGBA·fill(to_frame ,&white); +} + +void fill_random_f(FrameRGBA *frame ,PixelRGBA *px ,void *arg){ + *px = PixelRGBA·random(); +} +void FrameRGBA·fill_random(FrameRGBA *frame){ + if(!frame) return; + FrameRGBA·every(frame ,fill_random_f ,NULL); +} + + +// -------------------------------------------------------------------------------- +// Transform functions +// Given the previous frame ,current frame ,and an argument; modifies the +// current frame. + +int identity_transform(FrameRGBA *prev_frame ,FrameRGBA *curr_frame ,void *args){ + // no processing in the identity transform + FrameRGBA·copy(prev_frame ,&curr_frame); + return 0; // Success +} + +// -------------------------------------------------------------------------------- +// transform frame stream + +int transform_frame_stream(int (*transform)(FrameRGBA * ,FrameRGBA * ,void *) ,void *transform_args){ + // Simulated screen info (would be fetched from the actual DRM system) + FrameRGBA *prev_frame = FrameRGBA·alloc(3840 ,2400); + FrameRGBA *curr_frame = FrameRGBA·alloc_same(prev_frame); + + // For now ,we'll simulate grabbing the first frame by filling it with random values. + // In the real implementation ,you will fetch the current frame data from the DRM API. + uint32_t width ,height; + FrameRGBA·dimensions(curr_frame ,&width ,&height); + FrameRGBA·fill_random(curr_frame); + + // Call the transform function for the first frame (identity in this case) + transform(prev_frame ,curr_frame ,transform_args); + + // Main processing loop (simplified to one iteration for now) + while(1){ + // Simulate grabbing the next frame (we just reuse the current one for this example) + // In real code ,you would fetch the next frame from the DRM system here. + FrameRGBA·fill_random(curr_frame); + + // Call the transform function for each new frame + transform(prev_frame ,curr_frame ,transform_args); + FrameRGBA·copy(curr_frame ,&prev_frame); + + break; // Exit after one loop for this example (replace with continuous loop in real implementation) + } + + // Clean up memory + FrameRGBA·dealloc(prev_frame); + FrameRGBA·dealloc(curr_frame); + + return 0; // Success +} + +int main(int argc ,char **argv){ + int fd; + drmModeRes *resources; + drmModeConnector *connector = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + + // Open the DRM device + fd = open("/dev/dri/card2",O_RDWR | O_CLOEXEC); + if(fd < 0){ + perror("Cannot open DRM device"); + return -1; + } + + // Get resources + resources = drmModeGetResources(fd); + if(!resources){ + perror("drmModeGetResources failed"); + close(fd); + return -1; + } + + // Find a connected connector + for(int i = 0; i < resources->count_connectors; i++){ + connector = drmModeGetConnector(fd ,resources->connectors[i]); + if(connector->connection == DRM_MODE_CONNECTED){ + break; + } + drmModeFreeConnector(connector); + } + + if(!connector || connector->connection != DRM_MODE_CONNECTED){ + printf("No connected connector found\n"); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Get encoder and CRTC + encoder = drmModeGetEncoder(fd ,connector->encoder_id); + if(!encoder){ + perror("drmModeGetEncoder failed"); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + crtc = drmModeGetCrtc(fd ,encoder->crtc_id); + if(!crtc){ + perror("drmModeGetCrtc failed"); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + return -1; + } + + // Call transform_frame_stream with identity transform + transform_frame_stream(identity_transform ,NULL); + + // Clean up + drmModeFreeCrtc(crtc); + drmModeFreeEncoder(encoder); + drmModeFreeConnector(connector); + drmModeFreeResources(resources); + close(fd); + + return 0; +} diff --git a/developer/developer b/developer/developer new file mode 100644 index 0000000..e69de29