### Video Playback Example using IL Client Source: https://context7.com/raspberrypi/userland/llms.txt Demonstrates video playback by setting up and managing OpenMAX IL components for decoding and rendering. Requires initialization of the IL client and OMX, component creation, tunnel setup, and buffer management. Handles end-of-stream events. ```c #include "bcm_host.h" #include "ilclient.h" int video_playback_example(const char *filename) { ILCLIENT_T *client; COMPONENT_T *video_decode = NULL; COMPONENT_T *video_render = NULL; COMPONENT_T *video_scheduler = NULL; COMPONENT_T *clock = NULL; COMPONENT_T *list[5]; TUNNEL_T tunnel[4]; OMX_VIDEO_PARAM_PORTFORMATTYPE format; FILE *in; int status = 0; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if ((in = fopen(filename, "rb")) == NULL) return -1; // Initialize IL client if ((client = ilclient_init()) == NULL) { fclose(in); return -1; } // Initialize OMX if (OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return -1; } // Create video decoder component if (ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) { status = -1; goto cleanup; } list[0] = video_decode; // Create video renderer if (ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) { status = -1; goto cleanup; } list[1] = video_render; // Create clock component if (ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) { status = -1; goto cleanup; } list[2] = clock; // Create video scheduler if (ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) { status = -1; goto cleanup; } list[3] = video_scheduler; // Setup tunnels set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+2, clock, 80, video_scheduler, 12); // Setup clock tunnel and start clock ilclient_setup_tunnel(tunnel+2, 0, 0); ilclient_change_component_state(clock, OMX_StateExecuting); // Configure decoder input format ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(format)); format.nSize = sizeof(format); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format); // Enable input buffers ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL); ilclient_change_component_state(video_decode, OMX_StateExecuting); // Feed data loop OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; while ((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) { size_t bytes_read = fread(buf->pBuffer, 1, buf->nAllocLen, in); if (bytes_read == 0) { buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_EOS; OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf); break; } // Check for port settings changed event if (!port_settings_changed && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) { port_settings_changed = 1; // Setup decoder->scheduler tunnel ilclient_setup_tunnel(tunnel, 0, 0); ilclient_change_component_state(video_scheduler, OMX_StateExecuting); // Setup scheduler->render tunnel ilclient_setup_tunnel(tunnel+1, 0, 1000); ilclient_change_component_state(video_render, OMX_StateExecuting); } buf->nFilledLen = bytes_read; buf->nOffset = 0; OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf); } // Wait for EOS ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0, ILCLIENT_BUFFER_FLAG_EOS, -1); cleanup: fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); return status; } ``` -------------------------------- ### Install Executable Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_audio/CMakeLists.txt Installs the built executable to the 'bin' directory on the target system. ```cmake install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### Build and Install Userland Library Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/libs/sm/CMakeLists.txt Defines the userland library, links it with the vcos library, and installs it. ```cmake add_library(vcsm ${SHARED} user-vcsm.c) target_link_libraries(vcsm vcos) install(TARGETS vcsm DESTINATION lib) install(FILES user-vcsm.h DESTINATION include/interface/vcsm) ``` -------------------------------- ### Install vcos Library Source: https://github.com/raspberrypi/userland/blob/master/interface/vcos/pthreads/CMakeLists.txt Installs the built vcos library to the 'lib' directory. ```cmake install(TARGETS vcos DESTINATION lib) ``` -------------------------------- ### Install Plugin Library Source: https://github.com/raspberrypi/userland/blob/master/containers/dummy/CMakeLists.txt Installs the 'writer_dummy' target to the specified plugin directory '${VMCS_PLUGIN_DIR}', making it available as a plugin. ```cmake install(TARGETS writer_dummy DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### DispmanX Example: Full Display Management Source: https://context7.com/raspberrypi/userland/llms.txt This C code demonstrates a comprehensive DispmanX example, including opening a display, creating resources, adding elements, updating the display, taking snapshots, and cleanup. It requires the bcm_host library. ```c #include "bcm_host.h" int dispmanx_example(void) { DISPMANX_DISPLAY_HANDLE_T display; DISPMANX_UPDATE_HANDLE_T update; DISPMANX_ELEMENT_HANDLE_T element; DISPMANX_RESOURCE_HANDLE_T resource; VC_RECT_T src_rect, dst_rect; uint32_t image_ptr; int ret; bcm_host_init(); // Open display (0 = LCD/HDMI) display = vc_dispmanx_display_open(0); if (!display) { fprintf(stderr, "Failed to open display\n"); return -1; } // Get display info DISPMANX_MODEINFO_T info; ret = vc_dispmanx_display_get_info(display, &info); printf("Display: %dx%d\n", info.width, info.height); // Create an offscreen resource uint32_t width = 640, height = 480; resource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, width, height, &image_ptr); // Prepare rectangle for full resource vc_dispmanx_rect_set(&src_rect, 0, 0, width << 16, height << 16); vc_dispmanx_rect_set(&dst_rect, 100, 100, width, height); // Start an update update = vc_dispmanx_update_start(0); // Add element to display VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS, 255, // opacity 0 }; element = vc_dispmanx_element_add( update, display, 0, // layer &dst_rect, // destination rectangle resource, // source resource &src_rect, // source rectangle DISPMANX_PROTECTION_NONE, &alpha, NULL, // clamp DISPMANX_NO_ROTATE // transform ); // Submit update synchronously vc_dispmanx_update_submit_sync(update); // Update the resource with new image data uint32_t *image_data = malloc(width * height * 4); // Fill with red for (int i = 0; i < width * height; i++) { image_data[i] = 0xFF0000FF; // RGBA: Red } VC_RECT_T write_rect; vc_dispmanx_rect_set(&write_rect, 0, 0, width, height); vc_dispmanx_resource_write_data(resource, VC_IMAGE_RGBA32, width * 4, image_data, &write_rect); // Change element attributes update = vc_dispmanx_update_start(0); vc_dispmanx_rect_set(&dst_rect, 200, 200, width, height); vc_dispmanx_element_change_attributes( update, element, ELEMENT_CHANGE_DEST_RECT, // change flags 0, // layer 255, // opacity &dst_rect, // new dest rect NULL, // src rect 0, // mask DISPMANX_NO_ROTATE // transform ); vc_dispmanx_update_submit_sync(update); // Take a snapshot of the display DISPMANX_RESOURCE_HANDLE_T snapshot; snapshot = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, info.width, info.height, &image_ptr); vc_dispmanx_snapshot(display, snapshot, DISPMANX_NO_ROTATE); // Cleanup update = vc_dispmanx_update_start(0); vc_dispmanx_element_remove(update, element); vc_dispmanx_update_submit_sync(update); vc_dispmanx_resource_delete(resource); vc_dispmanx_resource_delete(snapshot); vc_dispmanx_display_close(display); free(image_data); bcm_host_deinit(); return 0; } ``` -------------------------------- ### Install bcm_host Library Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/libs/bcm_host/CMakeLists.txt Installs the bcm_host target to the 'lib' directory. ```cmake install(TARGETS bcm_host DESTINATION lib) ``` -------------------------------- ### Example Program Build and Execution Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_fft/gpu_fft.txt Instructions on how to build and run the example FFT program included with the Raspbian distro. It requires 'make' and can be run with optional command-line arguments for FFT length, batch size, and loop count. ```bash cd /opt/vc/src/hello_pi/hello_fft make sudo ./hello_fft.bin 12 It accepts three optional command-line arguments: ``` -------------------------------- ### Install Raw Video Writer Library Source: https://github.com/raspberrypi/userland/blob/master/containers/raw/CMakeLists.txt Installs the 'writer_raw_video' target to the plugin directory defined by VMCS_PLUGIN_DIR. ```cmake install(TARGETS writer_raw_video DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Install Library Source: https://github.com/raspberrypi/userland/blob/master/containers/flash/CMakeLists.txt Installs the 'reader_flv' library to the specified plugin directory. ```cmake install(TARGETS reader_flv DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Install Binary Writer Library Source: https://github.com/raspberrypi/userland/blob/master/containers/binary/CMakeLists.txt Installs the 'writer_binary' target to the specified plugin directory, making it available for use by the system. ```cmake install(TARGETS writer_binary DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure and Install ASF Plugins Source: https://github.com/raspberrypi/userland/blob/master/containers/asf/CMakeLists.txt Sets up the build environment for ASF reader and writer libraries and defines their installation destination. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_asf ${LIBRARY_TYPE} asf_reader.c) target_link_libraries(reader_asf containers) install(TARGETS reader_asf DESTINATION ${VMCS_PLUGIN_DIR}) add_library(writer_asf ${LIBRARY_TYPE} asf_writer.c) target_link_libraries(writer_asf containers) install(TARGETS writer_asf DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Install Library to Destination Source: https://github.com/raspberrypi/userland/blob/master/helpers/dtoverlay/CMakeLists.txt Installs the 'dtovl' target (the shared library) to the 'lib' directory on the target system. This makes the library available for use by other applications after installation. ```cmake install (TARGETS dtovl DESTINATION lib) ``` -------------------------------- ### Install Binary Reader Library Source: https://github.com/raspberrypi/userland/blob/master/containers/binary/CMakeLists.txt Installs the 'reader_binary' target to the specified plugin directory, making it available for use by the system. ```cmake install(TARGETS reader_binary DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Include Directories Setup Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/libs/bcm_host/CMakeLists.txt Specifies the include directories for the build, including platform-specific and host support paths. ```cmake include_directories( ../../../.. ../../../../interface/vcos/${VCOS_PLATFORM} ../../../../host_support/linux/added/include ../../../../host_applications/vmcs/test_apps/iltest ../../../../host_applications/framework/common ) ``` -------------------------------- ### Configure CMake Executable and Installation Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_world/CMakeLists.txt Defines the executable target, links necessary libraries, and specifies the installation directory for the binary. ```cmake set(EXEC hello_world.bin) set(SRCS world.c) add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### Initialize EGL and OpenGL ES on Raspberry Pi Source: https://context7.com/raspberrypi/userland/llms.txt This example demonstrates the full lifecycle of EGL initialization, including DispmanX window creation, context binding, and cleanup routines. ```c #include "bcm_host.h" #include #include #include typedef struct { uint32_t screen_width; uint32_t screen_height; EGLDisplay display; EGLSurface surface; EGLContext context; DISPMANX_DISPLAY_HANDLE_T dispman_display; DISPMANX_ELEMENT_HANDLE_T dispman_element; } EGL_STATE_T; int init_egl(EGL_STATE_T *state) { static const EGLint attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; static const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLConfig config; EGLint num_config; EGLBoolean result; bcm_host_init(); // Get display connection state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (state->display == EGL_NO_DISPLAY) { fprintf(stderr, "eglGetDisplay failed\n"); return -1; } // Initialize EGL result = eglInitialize(state->display, NULL, NULL); if (result == EGL_FALSE) { fprintf(stderr, "eglInitialize failed\n"); return -1; } // Get frame buffer configuration result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config); if (result == EGL_FALSE || num_config == 0) { fprintf(stderr, "eglChooseConfig failed\n"); return -1; } // Bind OpenGL ES API result = eglBindAPI(EGL_OPENGL_ES_API); if (result == EGL_FALSE) { fprintf(stderr, "eglBindAPI failed\n"); return -1; } // Create rendering context state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, context_attributes); if (state->context == EGL_NO_CONTEXT) { fprintf(stderr, "eglCreateContext failed\n"); return -1; } // Get display size int32_t success = graphics_get_display_size(0, &state->screen_width, &state->screen_height); if (success < 0) { fprintf(stderr, "graphics_get_display_size failed\n"); return -1; } // Create native window using DispmanX VC_RECT_T dst_rect, src_rect; dst_rect.x = 0; dst_rect.y = 0; dst_rect.width = state->screen_width; dst_rect.height = state->screen_height; src_rect.x = 0; src_rect.y = 0; src_rect.width = state->screen_width << 16; src_rect.height = state->screen_height << 16; state->dispman_display = vc_dispmanx_display_open(0); DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); state->dispman_element = vc_dispmanx_element_add( update, state->dispman_display, 0, // layer &dst_rect, 0, // src &src_rect, DISPMANX_PROTECTION_NONE, NULL, // alpha NULL, // clamp DISPMANX_NO_ROTATE ); static EGL_DISPMANX_WINDOW_T nativewindow; nativewindow.element = state->dispman_element; nativewindow.width = state->screen_width; nativewindow.height = state->screen_height; vc_dispmanx_update_submit_sync(update); // Create EGL window surface state->surface = eglCreateWindowSurface(state->display, config, &nativewindow, NULL); if (state->surface == EGL_NO_SURFACE) { fprintf(stderr, "eglCreateWindowSurface failed\n"); return -1; } // Make context current result = eglMakeCurrent(state->display, state->surface, state->surface, state->context); if (result == EGL_FALSE) { fprintf(stderr, "eglMakeCurrent failed\n"); return -1; } // Setup OpenGL ES viewport glViewport(0, 0, state->screen_width, state->screen_height); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); return 0; } void render_frame(EGL_STATE_T *state) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw your OpenGL ES content here... eglSwapBuffers(state->display, state->surface); } void cleanup_egl(EGL_STATE_T *state) { eglMakeCurrent(state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(state->display, state->surface); eglDestroyContext(state->display, state->context); eglTerminate(state->display); DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0); vc_dispmanx_element_remove(update, state->dispman_element); vc_dispmanx_update_submit_sync(update); vc_dispmanx_display_close(state->dispman_display); bcm_host_deinit(); } ``` -------------------------------- ### Configure Executable Build and Installation Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_jpeg/CMakeLists.txt Defines the executable name, source files, links necessary libraries, and specifies the installation path for the executable. ```cmake set(EXEC hello_jpeg.bin) set(SRCS jpeg.c) add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### Install RTSP Reader Plugin Source: https://github.com/raspberrypi/userland/blob/master/containers/rtsp/CMakeLists.txt Installs the 'reader_rtsp' target to the specified plugin directory, making it available for runtime loading. ```cmake install(TARGETS reader_rtsp DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Install Raw Video Reader Library Source: https://github.com/raspberrypi/userland/blob/master/containers/raw/CMakeLists.txt Installs the 'reader_raw_video' target to the specified plugin directory, typically defined by the VMCS_PLUGIN_DIR variable. ```cmake install(TARGETS reader_raw_video DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure and Install MP4 Plugin Libraries Source: https://github.com/raspberrypi/userland/blob/master/containers/mp4/CMakeLists.txt Defines the build targets for MP4 reader and writer libraries and specifies their installation destination as plugins. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_mp4 ${LIBRARY_TYPE} mp4_reader.c) target_link_libraries(reader_mp4 containers) install(TARGETS reader_mp4 DESTINATION ${VMCS_PLUGIN_DIR}) add_library(writer_mp4 ${LIBRARY_TYPE} mp4_writer.c) target_link_libraries(writer_mp4 containers) install(TARGETS writer_mp4 DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Define and Install Executable in CMake Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_encode/CMakeLists.txt Configures the build process for a C source file, linking it against project-specific libraries and defining its installation destination. ```cmake set(EXEC hello_encode.bin) set(SRCS encode.c) add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### Install Reader QSynth Library as a Plugin Source: https://github.com/raspberrypi/userland/blob/master/containers/qsynth/CMakeLists.txt Installs the 'reader_qsynth' target to the specified plugin directory. The destination path is determined by the 'VMCS_PLUGIN_DIR' variable, which should be defined elsewhere in the CMake configuration. ```cmake install(TARGETS reader_qsynth DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure MMAL Library Build Source: https://github.com/raspberrypi/userland/blob/master/interface/mmal/CMakeLists.txt Sets up the MMAL library build, including compiler flags, subdirectories, and installation rules. ```cmake # We support building both static and shared libraries if (NOT DEFINED LIBRARY_TYPE) set(LIBRARY_TYPE SHARED) endif (NOT DEFINED LIBRARY_TYPE) add_definitions(-Wall -Werror) add_library(mmal SHARED util/mmal_util.c) add_subdirectory(core) add_subdirectory(util) add_subdirectory(vc) add_subdirectory(components) add_subdirectory(openmaxil) add_subdirectory(client) target_link_libraries(mmal mmal_core mmal_util mmal_vc_client vcos mmal_components) install(TARGETS mmal DESTINATION lib) install(FILES mmal.h mmal_buffer.h mmal_clock.h mmal_common.h mmal_component.h mmal_encodings.h mmal_events.h mmal_format.h mmal_logging.h mmal_parameters.h mmal_parameters_audio.h mmal_parameters_camera.h mmal_parameters_clock.h mmal_parameters_common.h mmal_parameters_video.h mmal_pool.h mmal_port.h mmal_queue.h mmal_types.h DESTINATION include/interface/mmal ) # Test apps if(BUILD_MMAL_APPS) add_subdirectory(test) endif(BUILD_MMAL_APPS) ``` -------------------------------- ### Configure and Build RTP Reader Library Source: https://github.com/raspberrypi/userland/blob/master/containers/rtp/CMakeLists.txt Sets up the library build process, including source file aggregation, dependency linking, and installation destination. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) set(rtp_SRCS ${rtp_SRCS} rtp_reader.c) set(rtp_SRCS ${rtp_SRCS} rtp_h264.c) set(rtp_SRCS ${rtp_SRCS} rtp_mpeg4.c) set(rtp_SRCS ${rtp_SRCS} rtp_base64.c) add_library(reader_rtp ${LIBRARY_TYPE} ${rtp_SRCS}) target_link_libraries(reader_rtp containers) install(TARGETS reader_rtp DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure CMake for hello_videocube Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_videocube/CMakeLists.txt Defines the executable name, source files, and installation rules for the project. ```cmake set(EXEC hello_videocube.bin) set(SRCS triangle.c video.c) add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### Compile imv2pgm and imv2txt Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/raspicam/imv_examples/README.md Compile the C source files for post-processing video data. Ensure you have gcc and make installed. ```bash gcc imv2pgm.c -o imv2pgm -lm ``` ```bash gcc imv2txt.c -o imv2txt ``` -------------------------------- ### Configure CMake for wav_reader library Source: https://github.com/raspberrypi/userland/blob/master/containers/wav/CMakeLists.txt Sets up the build environment for the wav_reader library, including library prefix, include paths, and installation destination. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_wav ${LIBRARY_TYPE} wav_reader.c) target_link_libraries(reader_wav containers) install(TARGETS reader_wav DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure CMake for reader_rv9 library Source: https://github.com/raspberrypi/userland/blob/master/containers/rv9/CMakeLists.txt Sets up the library prefix, include directories, and installation path for the reader_rv9 plugin. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_rv9 ${LIBRARY_TYPE} rv9_reader.c) target_link_libraries(reader_rv9 containers) install(TARGETS reader_rv9 DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure CMake for hello_teapot executable Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_teapot/CMakeLists.txt Defines the executable name, source files, library dependencies, and installation destination for the hello_teapot project. ```cmake set(EXEC hello_teapot.bin) set(SRCS triangle.c video.c models.c) add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) install(TARGETS ${EXEC} RUNTIME DESTINATION bin) ``` -------------------------------- ### CMake Build Configuration for MMAL VC Client Source: https://github.com/raspberrypi/userland/blob/master/interface/mmal/vc/CMakeLists.txt Defines the library target, links dependencies, and configures installation paths for headers and binaries. ```cmake add_definitions(-DENABLE_MMAL_VCSM) add_library(mmal_vc_client ${LIBRARY_TYPE} mmal_vc_client.c mmal_vc_shm.c mmal_vc_api.c mmal_vc_opaque_alloc.c mmal_vc_msgnames.c mmal_vc_api_drm.c) #target_link_libraries(mmal_vc_client vchiq_arm vcos) target_link_libraries(mmal_vc_client vchiq_arm vcos vcsm) if(BUILD_MMAL_APPS) add_executable(mmal_vc_diag mmal_vc_diag.c) target_link_libraries(mmal_vc_diag mmal mmal_vc_client debug_sym vcos) install(TARGETS mmal_vc_diag RUNTIME DESTINATION bin) endif(BUILD_MMAL_APPS) include_directories ( ../../../host_applications/linux/libs/sm ) install(TARGETS mmal_vc_client DESTINATION lib) install(FILES mmal_vc_api.h mmal_vc_api_drm.h mmal_vc_client_priv.h mmal_vc_msgnames.h mmal_vc_msgs.h mmal_vc_opaque_alloc.h mmal_vc_shm.h DESTINATION include/interface/mmal/vc ) ``` -------------------------------- ### Configure CMake for dtoverlay Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/dtoverlay/CMakeLists.txt Defines the build environment, includes necessary headers, and sets up installation targets for the dtoverlay utility. ```cmake cmake_minimum_required(VERSION 2.8) get_filename_component (VIDEOCORE_ROOT ../../../.. ABSOLUTE) include (${VIDEOCORE_ROOT}/makefiles/cmake/global_settings.cmake) if (NOT WIN32) add_definitions(-Wall -Werror) endif () include_directories ( ${VIDEOCORE_HEADERS_BUILD_DIR} ${VIDEOCORE_ROOT} ${VIDEOCORE_ROOT}/opensrc/helpers/libfdt ${VIDEOCORE_ROOT}/helpers/dtoverlay ) add_executable(dtoverlay dtoverlay_main.c utils.c) target_link_libraries(dtoverlay dtovl) install(TARGETS dtoverlay RUNTIME DESTINATION bin) install(FILES dtoverlay.1 DESTINATION man/man1) add_custom_command(TARGET dtoverlay POST_BUILD COMMAND ln;-sf;dtoverlay;dtparam) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dtparam DESTINATION bin) install(FILES dtparam.1 DESTINATION man/man1) set(DTOVERLAY_SCRIPTS dtoverlay-pre dtoverlay-post) install(PROGRAMS ${DTOVERLAY_SCRIPTS} DESTINATION bin) ``` -------------------------------- ### Configure CMake for reader_rcv Library Source: https://github.com/raspberrypi/userland/blob/master/containers/rcv/CMakeLists.txt Sets library prefixes, include directories, and installation paths for the reader_rcv plugin. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_rcv ${LIBRARY_TYPE} rcv_reader.c) target_link_libraries(reader_rcv containers) install(TARGETS reader_rcv DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Build Shared Libraries for Raspberry Pi Userland Source: https://github.com/raspberrypi/userland/blob/master/containers/simple/CMakeLists.txt This CMakeLists.txt configures the build process for shared libraries. It sets the shared library prefix to empty, includes necessary directories, defines two libraries (reader_simple and writer_simple) with their respective source files, links them against the 'containers' library, and installs them to the VMCS_PLUGIN_DIR. ```cmake set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_simple ${LIBRARY_TYPE} simple_reader.c) target_link_libraries(reader_simple containers) install(TARGETS reader_simple DESTINATION ${VMCS_PLUGIN_DIR}) add_library(writer_simple ${LIBRARY_TYPE} simple_writer.c) target_link_libraries(writer_simple containers) install(TARGETS writer_simple DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure CMake for mpga_reader library Source: https://github.com/raspberrypi/userland/blob/master/containers/mpga/CMakeLists.txt Sets library prefixes, include directories, and defines the build and installation targets for the mpga_reader plugin. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_mpga ${LIBRARY_TYPE} mpga_reader.c) target_link_libraries(reader_mpga containers) install(TARGETS reader_mpga DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### Configure CMake for reader_mkv Library Source: https://github.com/raspberrypi/userland/blob/master/containers/mkv/CMakeLists.txt Sets up the build environment for the matroska_reader library, including library prefix configuration, include paths, and installation destination. ```cmake # Container module needs to go in as a plugins so different prefix # and install path set(CMAKE_SHARED_LIBRARY_PREFIX "") # Make sure the compiler can find the necessary include files include_directories (../..) add_library(reader_mkv ${LIBRARY_TYPE} matroska_reader.c) target_link_libraries(reader_mkv containers) install(TARGETS reader_mkv DESTINATION ${VMCS_PLUGIN_DIR}) ``` -------------------------------- ### CMake Build Configuration for VCHIQ Source: https://github.com/raspberrypi/userland/blob/master/interface/vchiq_arm/CMakeLists.txt Defines the shared library vchiq_arm and the executable vchiq_test, linking them against vcos and setting installation destinations. ```cmake add_library(vchiq_arm SHARED vchiq_lib.c vchiq_util.c) # pull in VCHI cond variable emulation target_link_libraries(vchiq_arm vcos) install(TARGETS vchiq_arm DESTINATION lib) #install(FILES etc/10-vchiq.rules DESTINATION /etc/udev/rules.d) include_directories(../..) add_executable(vchiq_test vchiq_test.c) target_link_libraries(vchiq_test vchiq_arm vcos) install(TARGETS vchiq_test RUNTIME DESTINATION bin) ``` -------------------------------- ### Building and Executing 2D FFT Demo Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_fft/gpu_fft.txt Build the hello_fft_2d demo using 'make' and execute it with sudo. This process generates a BMP file and demonstrates the 2D FFT functionality. ```bash make hello_fft_2d.bin sudo ./hello_fft_2d.bin ``` -------------------------------- ### Initialize BCM Host and Query Hardware Source: https://context7.com/raspberrypi/userland/llms.txt Initializes the VideoCore host environment and retrieves system information. bcm_host_init must be called before any other library functions. ```c #include "bcm_host.h" int main(void) { // Initialize BCM host - MUST be called first bcm_host_init(); // Get display dimensions uint32_t width, height; int32_t result = graphics_get_display_size(0, &width, &height); if (result >= 0) { printf("Display size: %dx%d\n", width, height); } // Detect board type int model = bcm_host_get_model_type(); switch (model) { case BCM_HOST_BOARD_TYPE_PI4MODELB: printf("Running on Raspberry Pi 4 Model B\n"); break; case BCM_HOST_BOARD_TYPE_PI3MODELB: printf("Running on Raspberry Pi 3 Model B\n"); break; case BCM_HOST_BOARD_TYPE_PI0W: printf("Running on Raspberry Pi Zero W\n"); break; } // Check if Pi4 family (4B, 400, CM4) if (bcm_host_is_model_pi4()) { printf("This is a Pi4 family device\n"); } // Get processor ID int processor = bcm_host_get_processor_id(); // BCM_HOST_PROCESSOR_BCM2835 (Pi 1, Zero) // BCM_HOST_PROCESSOR_BCM2836 (Pi 2) // BCM_HOST_PROCESSOR_BCM2837 (Pi 3) // BCM_HOST_PROCESSOR_BCM2711 (Pi 4) // Check display mode if (bcm_host_is_kms_active()) { printf("KMS display driver active\n"); } else if (bcm_host_is_fkms_active()) { printf("FKMS display driver active\n"); } // Get peripheral addresses (for direct hardware access) unsigned peripheral_addr = bcm_host_get_peripheral_address(); unsigned peripheral_size = bcm_host_get_peripheral_size(); // Cleanup when done bcm_host_deinit(); return 0; } ``` -------------------------------- ### Initialize and Configure MMAL Video Decoder Source: https://context7.com/raspberrypi/userland/llms.txt Demonstrates the full lifecycle of a video decoder component, including format commitment, buffer pool creation, and port callback registration. ```c #include // Callback when input buffer is returned static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { // Buffer processed, release it back to pool mmal_buffer_header_release(buffer); } // Callback when output buffer is filled static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { MMAL_QUEUE_T *queue = (MMAL_QUEUE_T *)port->userdata; mmal_queue_put(queue, buffer); } int setup_video_decoder(void) { MMAL_COMPONENT_T *decoder = NULL; MMAL_STATUS_T status; // Create video decoder component on VideoCore status = mmal_component_create("vc.ril.video_decode", &decoder); if (status != MMAL_SUCCESS) { fprintf(stderr, "Failed to create decoder: %d\n", status); return -1; } // Configure input port format MMAL_ES_FORMAT_T *format_in = decoder->input[0]->format; format_in->type = MMAL_ES_TYPE_VIDEO; format_in->encoding = MMAL_ENCODING_H264; format_in->es->video.width = 1920; format_in->es->video.height = 1080; format_in->es->video.frame_rate.num = 30; format_in->es->video.frame_rate.den = 1; format_in->es->video.par.num = 1; format_in->es->video.par.den = 1; format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED; // Commit format changes status = mmal_port_format_commit(decoder->input[0]); if (status != MMAL_SUCCESS) { mmal_component_destroy(decoder); return -1; } // Set buffer requirements decoder->input[0]->buffer_num = decoder->input[0]->buffer_num_min; decoder->input[0]->buffer_size = decoder->input[0]->buffer_size_min; decoder->output[0]->buffer_num = decoder->output[0]->buffer_num_min; decoder->output[0]->buffer_size = decoder->output[0]->buffer_size_min; // Create buffer pools MMAL_POOL_T *pool_in = mmal_pool_create( decoder->input[0]->buffer_num, decoder->input[0]->buffer_size); MMAL_POOL_T *pool_out = mmal_pool_create( decoder->output[0]->buffer_num, decoder->output[0]->buffer_size); // Create output queue for decoded frames MMAL_QUEUE_T *output_queue = mmal_queue_create(); decoder->output[0]->userdata = (void *)output_queue; // Enable ports with callbacks status = mmal_port_enable(decoder->input[0], input_callback); status = mmal_port_enable(decoder->output[0], output_callback); // Enable the component status = mmal_component_enable(decoder); // ... use decoder ... // Cleanup mmal_component_disable(decoder); mmal_component_destroy(decoder); mmal_pool_destroy(pool_in); mmal_pool_destroy(pool_out); mmal_queue_destroy(output_queue); return 0; } ``` -------------------------------- ### Query VideoCore settings via CLI Source: https://context7.com/raspberrypi/userland/llms.txt Use these commands in a shell to monitor system status, clock frequencies, and hardware configurations. ```bash # Query GPU temperature vcgencmd measure_temp # Output: temp=45.0'C # Query GPU memory allocation vcgencmd get_mem gpu # Output: gpu=128M # Query CPU/GPU clock frequencies vcgencmd measure_clock arm vcgencmd measure_clock core # Query voltage vcgencmd measure_volts core # Check codec license vcgencmd codec_enabled H264 # Output: H264=enabled # Get firmware version vcgencmd version # Get configuration settings vcgencmd get_config int # Display current display settings vcgencmd get_lcd_info # Get available commands vcgencmd commands ``` -------------------------------- ### CMake build configuration for dtmerge Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/dtmerge/CMakeLists.txt Defines the build environment, include paths, and installation targets for the dtmerge executable. ```cmake cmake_minimum_required(VERSION 2.8) get_filename_component (VIDEOCORE_ROOT ../../../.. ABSOLUTE) include (${VIDEOCORE_ROOT}/makefiles/cmake/global_settings.cmake) if (NOT WIN32) add_definitions(-Wall -Werror) endif () include_directories ( ${VIDEOCORE_HEADERS_BUILD_DIR} ${VIDEOCORE_ROOT} ${VIDEOCORE_ROOT}/opensrc/helpers/libfdt ${VIDEOCORE_ROOT}/helpers/dtoverlay ) add_executable(dtmerge dtmerge.c) target_link_libraries(dtmerge dtovl) install(TARGETS dtmerge RUNTIME DESTINATION bin) install(FILES dtmerge.1 DESTINATION man/man1) ``` -------------------------------- ### Process MMAL Buffers Source: https://context7.com/raspberrypi/userland/llms.txt Demonstrates acquiring buffers from a pool, filling them with data, setting timestamps and flags, and sending them to an MMAL port. It also shows how to process incoming buffers from a queue, handle events, lock/unlock memory, and release buffers. ```c #include void process_buffers(MMAL_POOL_T *pool, MMAL_PORT_T *port, MMAL_QUEUE_T *output_queue) { MMAL_BUFFER_HEADER_T *buffer; // Get buffer from pool (non-blocking) buffer = mmal_queue_get(pool->queue); if (buffer) { // Fill buffer with data memcpy(buffer->data, input_data, data_size); buffer->length = data_size; buffer->offset = 0; buffer->pts = timestamp_us; // Presentation timestamp in microseconds buffer->dts = MMAL_TIME_UNKNOWN; // Decode timestamp // Set buffer flags buffer->flags = MMAL_BUFFER_HEADER_FLAG_FRAME; if (is_keyframe) { buffer->flags |= MMAL_BUFFER_HEADER_FLAG_KEYFRAME; } if (is_end_of_stream) { buffer->flags |= MMAL_BUFFER_HEADER_FLAG_EOS; } // Send buffer to port MMAL_STATUS_T status = mmal_port_send_buffer(port, buffer); if (status != MMAL_SUCCESS) { mmal_buffer_header_release(buffer); } } // Process output buffers while ((buffer = mmal_queue_get(output_queue)) != NULL) { // Check if this is an event rather than data if (buffer->cmd) { // Handle event (e.g., format change) printf("Event received: 0x%08x\n", buffer->cmd); mmal_buffer_header_release(buffer); continue; } // Lock buffer memory before access (required on VideoCore) mmal_buffer_header_mem_lock(buffer); // Access decoded data uint8_t *data = buffer->data + buffer->offset; uint32_t length = buffer->length; // Check for end of stream if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS) { printf("End of stream reached\n"); } // Process data... process_frame(data, length); // Unlock and release buffer mmal_buffer_header_mem_unlock(buffer); mmal_buffer_header_release(buffer); } // Wait for buffer with timeout (blocking) buffer = mmal_queue_timedwait(output_queue, 1000); // 1 second timeout if (buffer) { // Process buffer... mmal_buffer_header_release(buffer); } } ``` -------------------------------- ### Configure VCOS Build Environment with CMake Source: https://github.com/raspberrypi/userland/blob/master/interface/vcos/CMakeLists.txt Sets up the build environment, defines header files, and configures compiler-specific flags for the VCOS component. ```cmake cmake_minimum_required (VERSION 2.8) get_filename_component (VIDEOCORE_ROOT "../.." ABSOLUTE) include (${VIDEOCORE_ROOT}/makefiles/cmake/global_settings.cmake) set (HEADERS vcos_assert.h vcos_atomic_flags.h vcos_blockpool.h vcos_cmd.h vcos_dlfcn.h vcos_event_flags.h vcos_event.h vcos.h vcos_init.h vcos_inttypes.h vcos_isr.h vcos_legacy_isr.h vcos_logging.h vcos_logging_control.h vcos_lowlevel_thread.h vcos_mem.h vcos_mempool.h vcos_msgqueue.h vcos_mutex.h vcos_named_semaphore.h vcos_once.h vcos_queue.h vcos_quickslow_mutex.h vcos_reentrant_mutex.h vcos_semaphore.h vcos_stdint.h vcos_string.h vcos_thread_attr.h vcos_thread.h vcos_timer.h vcos_tls.h vcos_types.h ) foreach (header ${HEADERS}) configure_file ("${header}" "${VCOS_HEADERS_BUILD_DIR}/${header}" COPYONLY) endforeach () if (CMAKE_COMPILER_IS_GNUCC) add_definitions (-ggdb -Werror -Wall) endif () if (CMAKE_COMPILER_2005) add_definitions (/WX /W4 /wd4127 /D_CRT_SECURE_NO_DEPRECATE) endif () include_directories (${VIDEOCORE_ROOT} ${VCOS_HEADERS_BUILD_DIR}) add_subdirectory (${RTOS}) set(VCOS_EXCLUDE_TESTS TRUE) if (NOT DEFINED VCOS_EXCLUDE_TESTS) add_testapp_subdirectory (test) endif (NOT DEFINED VCOS_EXCLUDE_TESTS) if (WIN32) build_command (RELEASE_BUILD_CMD CONFIGURATION Release) build_command (DEBUG_BUILD_CMD CONFIGURATION Debug) configure_file (build_all.bat.in build_all.bat @ONLY) endif () #install (FILES ${HEADERS} DESTINATION include/interface/vcos) ``` -------------------------------- ### Define Source Files Source: https://github.com/raspberrypi/userland/blob/master/interface/vcos/pthreads/CMakeLists.txt Lists all source files required for building the vcos library. ```cmake set (SOURCES vcos_pthreads.c vcos_dlfcn.c ../glibc/vcos_backtrace.c ../generic/vcos_generic_event_flags.c ../generic/vcos_mem_from_malloc.c ../generic/vcos_generic_named_sem.c ../generic/vcos_generic_safe_string.c ../generic/vcos_generic_reentrant_mtx.c ../generic/vcos_abort.c ../generic/vcos_cmd.c ../generic/vcos_init.c ../generic/vcos_msgqueue.c ../generic/vcos_logcat.c ../generic/vcos_generic_blockpool.c ) ``` -------------------------------- ### Build Executable and Link Libraries Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_tiger/CMakeLists.txt Creates the executable target and links it against necessary libraries. ```cmake add_executable(${EXEC} ${SRCS}) target_link_libraries(${EXEC} ${HELLO_PI_LIBS}) ``` -------------------------------- ### gpu_fft_prepare Source: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_fft/gpu_fft.txt Allocates memory and initializes data structures for an FFT batch. ```APIDOC ## gpu_fft_prepare ### Description Call once to allocate memory and initialise data structures for the FFT process. ### Parameters - **mb** (int) - Required - Mailbox file descriptor obtained by calling mbox_open() - **log2_N** (int) - Required - log2(FFT length) = 8 to 22 - **direction** (int) - Required - FFT direction: GPU_FFT_FWD for forward FFT, GPU_FFT_REV for inverse FFT - **jobs** (int) - Required - Number of transforms in batch = 1 or more ### Response - **Return** (int) - Returns 0 for success. - **Output** (GPU_FFT **) - Control structure pointer. ```