/** * @brief Initialization of OpenMAX and structures. * @param ctx Application context to initialize. */ static void initAppOMX(AppOMXContext* ctx) { bcm_host_init() ; log_printer("Initialization...") ; { OMX_ERRORTYPE error = OMX_Init() ; if (error != OMX_ErrorNone) { omx_die(error, "OMX initialization failed...") ; return ; } } // Initialize the application context for video capture AppOMXContext_Memset(ctx, 0, sizeof(*ctx)) ; if (vcos_semaphore_create(ctx -> getHandlerLock(ctx), "handler_lock", 1) != VCOS_SUCCESS) die("Failed to create handler lock semaphore...\n") ; // Initialize component handles OMX_CALLBACKTYPE callbacks ; AppOMXContext_Memset(ctx, 0, sizeof(callbacks)) ; callbacks.EventHandler = event_handler ; callbacks.FillBufferDone = fill_output_buffer_done_handler ; init_component_handle("camera", ctx -> getCamera(ctx) , ctx, &callbacks) ; init_component_handle("video_encode", ctx -> getEncoder(ctx) , ctx, &callbacks) ; init_component_handle("null_sink", ctx -> getNullSink(ctx) , ctx, &callbacks) ; }
static void init_component_handle( const char *name, OMX_HANDLETYPE* hComponent, OMX_PTR pAppData, OMX_CALLBACKTYPE* callbacks) { OMX_ERRORTYPE r; char fullname[32]; // Get handle memset(fullname, 0, sizeof(fullname)); strcat(fullname, "OMX.broadcom."); strncat(fullname, name, strlen(fullname) - 1); //say("Initializing component %s", fullname); if((r = OMX_GetHandle(hComponent, fullname, pAppData, callbacks)) != OMX_ErrorNone) { omx_die(r, "Failed to get handle for component %s", fullname); } // Disable ports OMX_INDEXTYPE types[] = { OMX_IndexParamAudioInit, OMX_IndexParamVideoInit, OMX_IndexParamImageInit, OMX_IndexParamOtherInit }; OMX_PORT_PARAM_TYPE ports; OMX_INIT_STRUCTURE(ports); OMX_GetParameter(*hComponent, OMX_IndexParamVideoInit, &ports); int i; for(i = 0; i < 4; i++) { if(OMX_GetParameter(*hComponent, types[i], &ports) == OMX_ErrorNone) { OMX_U32 nPortIndex; for(nPortIndex = ports.nStartPortNumber; nPortIndex < ports.nStartPortNumber + ports.nPorts; nPortIndex++) { //say("Disabling port %d of component %s", nPortIndex, fullname); if((r = OMX_SendCommand(*hComponent, OMX_CommandPortDisable, nPortIndex, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable port %d of component %s", nPortIndex, fullname); } block_until_port_changed(*hComponent, nPortIndex, OMX_FALSE); } } } }
static void block_until_port_changed(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL bEnabled) { OMX_ERRORTYPE r; OMX_PARAM_PORTDEFINITIONTYPE portdef; OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = nPortIndex; OMX_U32 i = 0; while(i++ == 0 || portdef.bEnabled != bEnabled) { if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition"); } if(portdef.bEnabled != bEnabled) { usleep(10000); } } }
int encoder_encode_frame(struct encoded_pic_t *output) { OMX_ERRORTYPE r; if(ctx.encoder_output_buffer_available) { // Flush buffer to output file memcpy(output->buffer,ctx.encoder_ppBuffer_out->pBuffer,ctx.encoder_ppBuffer_out->nFilledLen); output->length=ctx.encoder_ppBuffer_out->nFilledLen; need_next_buffer_to_be_filled = 1; } // Buffer flushed, request a new buffer to be filled by the encoder component if(need_next_buffer_to_be_filled) { need_next_buffer_to_be_filled = 0; ctx.encoder_output_buffer_available = 0; if((r = OMX_FillThisBuffer(ctx.encoder, ctx.encoder_ppBuffer_out)) != OMX_ErrorNone) { omx_die(r, "Failed to request filling of the output buffer on encoder output port 201"); } } // Would be better to use signaling here but hey this works too usleep(1000); }
// OMX calls this handler for all the events it emits static OMX_ERRORTYPE event_handler( OMX_HANDLETYPE hComponent, OMX_PTR pAppData, OMX_EVENTTYPE eEvent, OMX_U32 nData1, OMX_U32 nData2, OMX_PTR pEventData) { dump_event(hComponent, eEvent, nData1, nData2); appctx *ctx = (appctx *)pAppData; switch(eEvent) { case OMX_EventCmdComplete: vcos_semaphore_wait(&ctx->handler_lock); if(nData1 == OMX_CommandFlush) { ctx->flushed = 1; } vcos_semaphore_post(&ctx->handler_lock); break; case OMX_EventParamOrConfigChanged: vcos_semaphore_wait(&ctx->handler_lock); if(nData2 == OMX_IndexParamCameraDeviceNumber) { ctx->camera_ready = 1; } vcos_semaphore_post(&ctx->handler_lock); break; case OMX_EventError: omx_die(nData1, "error event received"); break; default: break; } return OMX_ErrorNone; }
static void dump_port(OMX_HANDLETYPE hComponent, OMX_U32 nPortIndex, OMX_BOOL dumpformats) { OMX_ERRORTYPE r; OMX_PARAM_PORTDEFINITIONTYPE portdef; OMX_INIT_STRUCTURE(portdef); portdef.nPortIndex = nPortIndex; if((r = OMX_GetParameter(hComponent, OMX_IndexParamPortDefinition, &portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for port %d", nPortIndex); } dump_portdef(&portdef); if(dumpformats) { OMX_VIDEO_PARAM_PORTFORMATTYPE portformat; OMX_INIT_STRUCTURE(portformat); portformat.nPortIndex = nPortIndex; portformat.nIndex = 0; r = OMX_ErrorNone; //say("Port %d supports these video formats:", nPortIndex); while(r == OMX_ErrorNone) { if((r = OMX_GetParameter(hComponent, OMX_IndexParamVideoPortFormat, &portformat)) == OMX_ErrorNone) { // say("\t%s, compression: %s", dump_color_format(portformat.eColorFormat), dump_compression_format(portformat.eCompressionFormat)); portformat.nIndex++; } } } }
void encoder_close() { OMX_ERRORTYPE r; //say("Cleaning up..."); // Stop capturing video with the camera OMX_CONFIG_PORTBOOLEANTYPE capture; OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_FALSE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch off capture on camera video output port 71"); } // Return the last full buffer back to the encoder component ctx.encoder_ppBuffer_out->nFlags = OMX_BUFFERFLAG_EOS; if((r = OMX_FillThisBuffer(ctx.encoder, ctx.encoder_ppBuffer_out)) != OMX_ErrorNone) { omx_die(r, "Failed to request filling of the output buffer on encoder output port 201"); } //say("Cleaning up1..."); // Disable all the ports if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera input port 73"); } //block_until_port_changed(ctx.camera, 73, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera preview output port 70"); } //block_until_port_changed(ctx.camera, 70, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera video output port 71"); } //block_until_port_changed(ctx.camera, 71, OMX_FALSE); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandPortDisable, 200, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable encoder input port 200"); } //block_until_port_changed(ctx.encoder, 200, OMX_FALSE); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandPortDisable, 201, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable encoder output port 201"); } //block_until_port_changed(ctx.encoder, 201, OMX_FALSE); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortDisable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable null sink input port 240"); } //block_until_port_changed(ctx.null_sink, 240, OMX_FALSE); //say("Cleaning up3..."); // Free all the buffers if((r = OMX_FreeBuffer(ctx.camera, 73, ctx.camera_ppBuffer_in)) != OMX_ErrorNone) { omx_die(r, "Failed to free buffer for camera input port 73"); } if((r = OMX_FreeBuffer(ctx.encoder, 201, ctx.encoder_ppBuffer_out)) != OMX_ErrorNone) { omx_die(r, "Failed to free buffer for encoder output port 201"); } //say("Cleaning up4..."); // Transition all the components to idle and then to loaded states if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } //block_until_state_changed(ctx.camera, OMX_StateIdle); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the encoder component to idle"); } //block_until_state_changed(ctx.encoder, OMX_StateIdle); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } //block_until_state_changed(ctx.null_sink, OMX_StateIdle); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to loaded"); } //block_until_state_changed(ctx.camera, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the encoder component to loaded"); } //block_until_state_changed(ctx.encoder, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to loaded"); } //block_until_state_changed(ctx.null_sink, OMX_StateLoaded); // Free the component handles if((r = OMX_FreeHandle(ctx.camera)) != OMX_ErrorNone) { omx_die(r, "Failed to free camera component handle"); } if((r = OMX_FreeHandle(ctx.encoder)) != OMX_ErrorNone) { omx_die(r, "Failed to free encoder component handle"); } if((r = OMX_FreeHandle(ctx.null_sink)) != OMX_ErrorNone) { omx_die(r, "Failed to free null sink component handle"); } vcos_semaphore_delete(&ctx.handler_lock); if((r = OMX_Deinit()) != OMX_ErrorNone) { omx_die(r, "OMX de-initalization failed"); } }
int encoder_init(struct picture_t *info,int fps,int bright,int video_bitrate) { //tem_width=info->width; bcm_host_init(); OMX_ERRORTYPE r; if((r = OMX_Init()) != OMX_ErrorNone) { omx_die(r, "OMX initalization failed"); } // Init context memset(&ctx, 0, sizeof(ctx)); if(vcos_semaphore_create(&ctx.handler_lock, "handler_lock", 1) != VCOS_SUCCESS) { die("Failed to create handler lock semaphore"); } // Init component handles OMX_CALLBACKTYPE callbacks; memset(&ctx, 0, sizeof(callbacks)); callbacks.EventHandler = event_handler; callbacks.FillBufferDone = fill_output_buffer_done_handler; init_component_handle("camera", &ctx.camera , &ctx, &callbacks); init_component_handle("video_encode", &ctx.encoder, &ctx, &callbacks); init_component_handle("null_sink", &ctx.null_sink, &ctx, &callbacks); /* OMX_CALLBACKTYPE callbacks1; memset(&ctx, 0, sizeof(callbacks1)); callbacks1.EventHandler = event_handler; callbacks1.FillBufferDone = fill_camera_output_buffer_done_handler; */ init_component_handle("camera", &ctx.camera , &ctx, &callbacks); //===============change^^^^================ //say("Configuring camera..."); //say("Default port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_TRUE); //say("Default port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_TRUE); //say("Default port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_TRUE); // Request a callback to be made when OMX_IndexParamCameraDeviceNumber is // changed signaling that the camera device is ready for use. OMX_CONFIG_REQUESTCALLBACKTYPE cbtype; OMX_INIT_STRUCTURE(cbtype); cbtype.nPortIndex = OMX_ALL; cbtype.nIndex = OMX_IndexParamCameraDeviceNumber; cbtype.bEnable = OMX_TRUE; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigRequestCallback, &cbtype)) != OMX_ErrorNone) { omx_die(r, "Failed to request camera device number parameter change callback for camera"); } // Set device number, this triggers the callback configured just above OMX_PARAM_U32TYPE device; OMX_INIT_STRUCTURE(device); device.nPortIndex = OMX_ALL; device.nU32 = CAM_DEVICE_NUMBER; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamCameraDeviceNumber, &device)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera parameter device number"); } // Configure video format emitted by camera preview output port OMX_PARAM_PORTDEFINITIONTYPE camera_portdef; OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.format.video.nFrameWidth = info->width; camera_portdef.format.video.nFrameHeight = info->height; camera_portdef.format.video.xFramerate = fps << 16; // Stolen from gstomxvideodec.c of gst-omx camera_portdef.format.video.nStride = (camera_portdef.format.video.nFrameWidth + camera_portdef.nBufferAlignment - 1) & (~(camera_portdef.nBufferAlignment - 1)); camera_portdef.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera preview output port 70"); } // Configure video format emitted by camera video output port // Use configuration from camera preview output as basis for // camera video output configuration OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.nPortIndex = 71; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera video output port 71"); } // Configure frame rate OMX_CONFIG_FRAMERATETYPE framerate; OMX_INIT_STRUCTURE(framerate); framerate.nPortIndex = 70; framerate.xEncodeFramerate = camera_portdef.format.video.xFramerate; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera preview output port 70"); } framerate.nPortIndex = 71; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera video output port 71"); } // Configure sharpness OMX_CONFIG_SHARPNESSTYPE sharpness; OMX_INIT_STRUCTURE(sharpness); sharpness.nPortIndex = OMX_ALL; sharpness.nSharpness = CAM_SHARPNESS; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSharpness, &sharpness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera sharpness configuration"); } // Configure contrast OMX_CONFIG_CONTRASTTYPE contrast; OMX_INIT_STRUCTURE(contrast); contrast.nPortIndex = OMX_ALL; contrast.nContrast = CAM_CONTRAST; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonContrast, &contrast)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera contrast configuration"); } // Configure saturation OMX_CONFIG_SATURATIONTYPE saturation; OMX_INIT_STRUCTURE(saturation); saturation.nPortIndex = OMX_ALL; saturation.nSaturation = CAM_SATURATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSaturation, &saturation)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera saturation configuration"); } // Configure brightness OMX_CONFIG_BRIGHTNESSTYPE brightness; OMX_INIT_STRUCTURE(brightness); brightness.nPortIndex = OMX_ALL; brightness.nBrightness = bright; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonBrightness, &brightness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera brightness configuration"); } // Configure exposure value OMX_CONFIG_EXPOSUREVALUETYPE exposure_value; OMX_INIT_STRUCTURE(exposure_value); exposure_value.nPortIndex = OMX_ALL; exposure_value.xEVCompensation = CAM_EXPOSURE_VALUE_COMPENSTAION; exposure_value.bAutoSensitivity = CAM_EXPOSURE_AUTO_SENSITIVITY; exposure_value.nSensitivity = CAM_EXPOSURE_ISO_SENSITIVITY; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonExposureValue, &exposure_value)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera exposure value configuration"); } // Configure frame frame stabilisation OMX_CONFIG_FRAMESTABTYPE frame_stabilisation_control; OMX_INIT_STRUCTURE(frame_stabilisation_control); frame_stabilisation_control.nPortIndex = OMX_ALL; frame_stabilisation_control.bStab = CAM_FRAME_STABILISATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonFrameStabilisation, &frame_stabilisation_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame frame stabilisation control configuration"); } // Configure frame white balance control OMX_CONFIG_WHITEBALCONTROLTYPE white_balance_control; OMX_INIT_STRUCTURE(white_balance_control); white_balance_control.nPortIndex = OMX_ALL; white_balance_control.eWhiteBalControl = CAM_WHITE_BALANCE_CONTROL; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonWhiteBalance, &white_balance_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame white balance control configuration"); } // Configure image filter OMX_CONFIG_IMAGEFILTERTYPE image_filter; OMX_INIT_STRUCTURE(image_filter); image_filter.nPortIndex = OMX_ALL; image_filter.eImageFilter = CAM_IMAGE_FILTER; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonImageFilter, &image_filter)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera image filter configuration"); } // Configure mirror OMX_MIRRORTYPE eMirror = OMX_MirrorNone; if(CAM_FLIP_HORIZONTAL && !CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorHorizontal; } else if(!CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorVertical; } else if(CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorBoth; } OMX_CONFIG_MIRRORTYPE mirror; OMX_INIT_STRUCTURE(mirror); mirror.nPortIndex = 71; mirror.eMirror = eMirror; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonMirror, &mirror)) != OMX_ErrorNone) { omx_die(r, "Failed to set mirror configuration for camera video output port 71"); } // Ensure camera is ready while(!ctx.camera_ready) { usleep(10000); } //say("Configuring encoder..."); //say("Default port definition for encoder input port 200"); dump_port(ctx.encoder, 200, OMX_TRUE); //say("Default port definition for encoder output port 201"); dump_port(ctx.encoder, 201, OMX_TRUE); // Encoder input port definition is done automatically upon tunneling // Configure video format emitted by encoder output port OMX_PARAM_PORTDEFINITIONTYPE encoder_portdef; OMX_INIT_STRUCTURE(encoder_portdef); encoder_portdef.nPortIndex = 201; if((r = OMX_GetParameter(ctx.encoder, OMX_IndexParamPortDefinition, &encoder_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for encoder output port 201"); } // Copy some of the encoder output port configuration // from camera output port encoder_portdef.format.video.nFrameWidth = camera_portdef.format.video.nFrameWidth; encoder_portdef.format.video.nFrameHeight = camera_portdef.format.video.nFrameHeight; encoder_portdef.format.video.xFramerate = camera_portdef.format.video.xFramerate; encoder_portdef.format.video.nStride = camera_portdef.format.video.nStride; // Which one is effective, this or the configuration just below? encoder_portdef.format.video.nBitrate = video_bitrate; if((r = OMX_SetParameter(ctx.encoder, OMX_IndexParamPortDefinition, &encoder_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for encoder output port 201"); } // Configure bitrate OMX_VIDEO_PARAM_BITRATETYPE bitrate; OMX_INIT_STRUCTURE(bitrate); bitrate.eControlRate = OMX_Video_ControlRateVariable; bitrate.nTargetBitrate = encoder_portdef.format.video.nBitrate; bitrate.nPortIndex = 201; if((r = OMX_SetParameter(ctx.encoder, OMX_IndexParamVideoBitrate, &bitrate)) != OMX_ErrorNone) { omx_die(r, "Failed to set bitrate for encoder output port 201"); } // Configure format OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_INIT_STRUCTURE(format); format.nPortIndex = 201; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if((r = OMX_SetParameter(ctx.encoder, OMX_IndexParamVideoPortFormat, &format)) != OMX_ErrorNone) { omx_die(r, "Failed to set video format for encoder output port 201"); } OMX_CONFIG_PORTBOOLEANTYPE inlineHeader; OMX_INIT_STRUCTURE(inlineHeader); inlineHeader.nPortIndex = 201; inlineHeader.bEnabled = OMX_TRUE; if((r = OMX_SetParameter(ctx.encoder, OMX_IndexParamBrcmVideoAVCInlineHeaderEnable, &inlineHeader)) != OMX_ErrorNone) { omx_die(r, "Failed to switch on inlineHeader on video encoder output port 201"); } OMX_VIDEO_PARAM_AVCTYPE avc_st; OMX_INIT_STRUCTURE (avc_st); avc_st.nPortIndex = 201; if ((r = OMX_GetParameter (ctx.encoder, OMX_IndexParamVideoAvc, &avc_st))){ omx_die(r, "Failed to switch on avc_st on video encoder output port 201"); } avc_st.nPFrames = VIDEO_FRAMERATE-1; if ((r = OMX_SetParameter (ctx.encoder, OMX_IndexParamVideoAvc, &avc_st))){ omx_die(r, "Failed to switch on avc_st on video encoder output port 201"); } //say("Default port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_TRUE); // Null sink input port definition is done automatically upon tunneling // Tunnel camera preview output port and null sink input port //say("Setting up tunnel from camera preview output port 70 to null sink input port 240..."); if((r = OMX_SetupTunnel(ctx.camera, 70, ctx.null_sink, 240)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera preview output port 70 and null sink input port 240"); } // Tunnel camera video output port and encoder input port //say("Setting up tunnel from camera video output port 71 to encoder input port 200..."); if((r = OMX_SetupTunnel(ctx.camera, 71, ctx.encoder, 200)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera video output port 71 and encoder input port 200"); } // Switch components to idle state //say("Switching state of the camera component to idle..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.camera, OMX_StateIdle); //say("Switching state of the encoder component to idle..."); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the encoder component to idle"); } block_until_state_changed(ctx.encoder, OMX_StateIdle); //say("Switching state of the null sink component to idle..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } block_until_state_changed(ctx.null_sink, OMX_StateIdle); // Enable ports //say("Enabling ports..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera input port 73"); } block_until_port_changed(ctx.camera, 73, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera preview output port 70"); } block_until_port_changed(ctx.camera, 70, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera video output port 71"); } block_until_port_changed(ctx.camera, 71, OMX_TRUE); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandPortEnable, 200, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable encoder input port 200"); } block_until_port_changed(ctx.encoder, 200, OMX_TRUE); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandPortEnable, 201, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable encoder output port 201"); } block_until_port_changed(ctx.encoder, 201, OMX_TRUE); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortEnable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable null sink input port 240"); } block_until_port_changed(ctx.null_sink, 240, OMX_TRUE); // Allocate camera input buffer and encoder output buffer, // buffers for tunneled ports are allocated internally by OMX //say("Allocating buffers..."); OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 73; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera input port 73"); } if((r = OMX_AllocateBuffer(ctx.camera, &ctx.camera_ppBuffer_in, 73, NULL, camera_portdef.nBufferSize)) != OMX_ErrorNone) { omx_die(r, "Failed to allocate buffer for camera input port 73"); } /* camera_portdef.nPortIndex = 71; if((r = OMX_AllocateBuffer(ctx.camera, &ctx.camera_ppBuffer_out, 71, NULL, camera_portdef.nBufferSize)) != OMX_ErrorNone) { omx_die(r, "Failed to allocate buffer for camera output port 71"); } */ OMX_INIT_STRUCTURE(encoder_portdef); encoder_portdef.nPortIndex = 201; if((r = OMX_GetParameter(ctx.encoder, OMX_IndexParamPortDefinition, &encoder_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for encoder output port 201"); } if((r = OMX_AllocateBuffer(ctx.encoder, &ctx.encoder_ppBuffer_out, 201, NULL, encoder_portdef.nBufferSize)) != OMX_ErrorNone) { omx_die(r, "Failed to allocate buffer for encoder output port 201"); } // Switch state of the components prior to starting // the video capture and encoding loop //say("Switching state of the camera component to executing..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to executing"); } block_until_state_changed(ctx.camera, OMX_StateExecuting); //say("Switching state of the encoder component to executing..."); if((r = OMX_SendCommand(ctx.encoder, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the encoder component to executing"); } block_until_state_changed(ctx.encoder, OMX_StateExecuting); //say("Switching state of the null sink component to executing..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to executing"); } block_until_state_changed(ctx.null_sink, OMX_StateExecuting); OMX_CONFIG_PORTBOOLEANTYPE capture; OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_TRUE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch on capture on camera video output port 71"); } //say("Configured port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_FALSE); //say("Configured port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_FALSE); //say("Configured port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_FALSE); //say("Configured port definition for encoder input port 200"); dump_port(ctx.encoder, 200, OMX_FALSE); //say("Configured port definition for encoder output port 201"); dump_port(ctx.encoder, 201, OMX_FALSE); //say("Configured port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_FALSE); //say("Enter capture and encode loop, press Ctrl-C to quit..."); return 1; }
void *video_decode_test(void* arg) { bcm_host_init(); CUBE_STATE_T *state = (CUBE_STATE_T *)arg; OMX_ERRORTYPE r; if((r = OMX_Init()) != OMX_ErrorNone) { omx_die(r, "OMX initalization failed"); } // Init context appctx ctx; memset(&ctx, 0, sizeof(ctx)); if(vcos_semaphore_create(&ctx.handler_lock, "handler_lock", 1) != VCOS_SUCCESS) { die("Failed to create handler lock semaphore"); } ctx.eglImage = state->eglImage; // Init component handles OMX_CALLBACKTYPE callbacks; memset(&ctx, 0, sizeof(callbacks)); callbacks.EventHandler = event_handler; callbacks.FillBufferDone = my_fill_buffer_done; init_component_handle("camera", &ctx.camera , &ctx, &callbacks); init_component_handle("egl_render", &ctx.render, &ctx, &callbacks); init_component_handle("null_sink", &ctx.null_sink, &ctx, &callbacks); init_component_handle("clock", &ctx.clock, &ctx, &callbacks); OMX_U32 screen_width = state->screen_width, screen_height = state->screen_height; if(graphics_get_display_size(DISPLAY_DEVICE, &screen_width, &screen_height) < 0) { die("Failed to get display size"); } say("Configuring camera..."); dump_port(ctx.clock, 80, OMX_TRUE); say("Default port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_TRUE); say("Default port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_TRUE); say("Default port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_TRUE); OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCTURE(cstate); cstate.eState = OMX_TIME_ClockStateRunning; cstate.nWaitMask = 1; if((r = OMX_SetConfig(ctx.clock, OMX_IndexConfigTimeClockState, &cstate)) != OMX_ErrorNone) { omx_die(r, "Failed to request camera device number parameter change callback for camera"); } // Request a callback to be made when OMX_IndexParamCameraDeviceNumber is // changed signaling that the camera device is ready for use. OMX_CONFIG_REQUESTCALLBACKTYPE cbtype; OMX_INIT_STRUCTURE(cbtype); cbtype.nPortIndex = OMX_ALL; cbtype.nIndex = OMX_IndexParamCameraDeviceNumber; cbtype.bEnable = OMX_TRUE; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigRequestCallback, &cbtype)) != OMX_ErrorNone) { omx_die(r, "Failed to request camera device number parameter change callback for camera"); } // Set device number, this triggers the callback configured just above OMX_PARAM_U32TYPE device; OMX_INIT_STRUCTURE(device); device.nPortIndex = OMX_ALL; device.nU32 = CAM_DEVICE_NUMBER; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamCameraDeviceNumber, &device)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera parameter device number"); } // Configure video format emitted by camera preview output port OMX_PARAM_PORTDEFINITIONTYPE camera_portdef; OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.format.video.nFrameWidth = state->screen_width; camera_portdef.format.video.nFrameHeight = state->screen_height; camera_portdef.format.video.xFramerate = VIDEO_FRAMERATE << 16; // Stolen from gstomxvideodec.c of gst-omx camera_portdef.format.video.nStride = (camera_portdef.format.video.nFrameWidth + camera_portdef.nBufferAlignment - 1) & (~(camera_portdef.nBufferAlignment - 1)); camera_portdef.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera preview output port 70"); } // Configure video format emitted by camera video output port // Use configuration from camera preview output as basis for // camera video output configuration OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.nPortIndex = 71; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera video output port 71"); } // Configure frame rate OMX_CONFIG_FRAMERATETYPE framerate; OMX_INIT_STRUCTURE(framerate); framerate.nPortIndex = 70; framerate.xEncodeFramerate = camera_portdef.format.video.xFramerate; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera preview output port 70"); } framerate.nPortIndex = 71; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera video output port 71"); } // Configure sharpness OMX_CONFIG_SHARPNESSTYPE sharpness; OMX_INIT_STRUCTURE(sharpness); sharpness.nPortIndex = OMX_ALL; sharpness.nSharpness = CAM_SHARPNESS; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSharpness, &sharpness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera sharpness configuration"); } // Configure contrast OMX_CONFIG_CONTRASTTYPE contrast; OMX_INIT_STRUCTURE(contrast); contrast.nPortIndex = OMX_ALL; contrast.nContrast = CAM_CONTRAST; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonContrast, &contrast)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera contrast configuration"); } // Configure saturation OMX_CONFIG_SATURATIONTYPE saturation; OMX_INIT_STRUCTURE(saturation); saturation.nPortIndex = OMX_ALL; saturation.nSaturation = CAM_SATURATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSaturation, &saturation)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera saturation configuration"); } // Configure brightness OMX_CONFIG_BRIGHTNESSTYPE brightness; OMX_INIT_STRUCTURE(brightness); brightness.nPortIndex = OMX_ALL; brightness.nBrightness = CAM_BRIGHTNESS; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonBrightness, &brightness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera brightness configuration"); } // Configure exposure value OMX_CONFIG_EXPOSUREVALUETYPE exposure_value; OMX_INIT_STRUCTURE(exposure_value); exposure_value.nPortIndex = OMX_ALL; exposure_value.xEVCompensation = CAM_EXPOSURE_VALUE_COMPENSTAION; exposure_value.bAutoSensitivity = CAM_EXPOSURE_AUTO_SENSITIVITY; exposure_value.bAutoShutterSpeed = OMX_TRUE; // exposure_value.nShutterSpeedMsec = 10; exposure_value.nSensitivity = CAM_EXPOSURE_ISO_SENSITIVITY; exposure_value.eMetering = OMX_MeteringModeAverage; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonExposureValue, &exposure_value)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera exposure value configuration"); } OMX_CONFIG_EXPOSURECONTROLTYPE exposure; OMX_INIT_STRUCTURE(exposure); exposure.nPortIndex = OMX_ALL; exposure.eExposureControl = OMX_ExposureControlAuto; OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonExposure, &exposure); // Configure frame frame stabilisation OMX_CONFIG_FRAMESTABTYPE frame_stabilisation_control; OMX_INIT_STRUCTURE(frame_stabilisation_control); frame_stabilisation_control.nPortIndex = OMX_ALL; frame_stabilisation_control.bStab = CAM_FRAME_STABILISATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonFrameStabilisation, &frame_stabilisation_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame frame stabilisation control configuration"); } // Configure frame white balance control /* OMX_CONFIG_LIGHTNESSTYPE lightness_control; OMX_INIT_STRUCTURE(lightness_control); lightness_control.nPortIndex = OMX_ALL; lightness_control.nLightness = 0; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonLightness, &lightness_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame white balance control configuration"); }*/ // Configure frame white balance control OMX_CONFIG_WHITEBALCONTROLTYPE white_balance_control; OMX_INIT_STRUCTURE(white_balance_control); white_balance_control.nPortIndex = OMX_ALL; white_balance_control.eWhiteBalControl = CAM_WHITE_BALANCE_CONTROL; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonWhiteBalance, &white_balance_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame white balance control configuration"); } // Configure image filter OMX_CONFIG_IMAGEFILTERTYPE image_filter; OMX_INIT_STRUCTURE(image_filter); image_filter.nPortIndex = OMX_ALL; image_filter.eImageFilter = CAM_IMAGE_FILTER; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonImageFilter, &image_filter)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera image filter configuration"); } /* Set colour effect */ OMX_CONFIG_COLORENHANCEMENTTYPE colour; OMX_INIT_STRUCTURE(colour); colour.nPortIndex = OMX_ALL; colour.bColorEnhancement = OMX_FALSE; colour.nCustomizedU = 128; colour.nCustomizedV = 128; OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonColorEnhancement, &colour); // Configure mirror OMX_MIRRORTYPE eMirror = OMX_MirrorNone; if(CAM_FLIP_HORIZONTAL && !CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorHorizontal; } else if(!CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorVertical; } else if(CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorBoth; } OMX_CONFIG_MIRRORTYPE mirror; OMX_INIT_STRUCTURE(mirror); mirror.nPortIndex = 71; mirror.eMirror = eMirror; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonMirror, &mirror)) != OMX_ErrorNone) { omx_die(r, "Failed to set mirror configuration for camera video output port 71"); } // Ensure camera is ready while(!ctx.camera_ready) { usleep(10000); } say("Configuring render..."); say("Default port definition for render input port 90"); dump_port(ctx.render, 220, OMX_TRUE); // Render input port definition is done automatically upon tunneling say("Configuring null sink..."); say("Default port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_TRUE); // Null sink input port definition is done automatically upon tunneling // Tunnel camera preview output port and null sink input port say("Setting up tunnel from camera preview output port 70 to null sink input port 240..."); if((r = OMX_SetupTunnel(ctx.clock, 80, ctx.camera, 73)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera preview output port 70 and null sink input port 240"); } // Tunnel camera preview output port and null sink input port say("Setting up tunnel from camera preview output port 70 to null sink input port 240..."); if((r = OMX_SetupTunnel(ctx.camera, 70, ctx.null_sink, 240)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera preview output port 70 and null sink input port 240"); } // Tunnel camera video output port and render input port say("Setting up tunnel from camera video output port 71 to render input port 220..."); if((r = OMX_SetupTunnel(ctx.camera, 71, ctx.render, 220)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera video output port 71 and render input port 90"); } // Switch components to idle state say("Switching state of the camera component to idle..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.clock, OMX_StateIdle); say("Switching state of the camera component to idle..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.camera, OMX_StateIdle); say("Switching state of the render component to idle..."); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to idle"); } block_until_state_changed(ctx.render, OMX_StateIdle); say("Switching state of the null sink component to idle..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } block_until_state_changed(ctx.null_sink, OMX_StateIdle); // Enable ports say("Enabling ports..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandPortEnable, 80, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera input port 73"); } block_until_port_changed(ctx.clock, 80, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera input port 73"); } block_until_port_changed(ctx.camera, 73, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera preview output port 70"); } block_until_port_changed(ctx.camera, 70, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera video output port 71"); } block_until_port_changed(ctx.camera, 71, OMX_TRUE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortEnable, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable render input port 220"); } block_until_port_changed(ctx.render, 220, OMX_TRUE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortEnable, 221, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable render input port 221"); } block_until_port_changed(ctx.render, 220, OMX_TRUE); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortEnable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable null sink input port 240"); } block_until_port_changed(ctx.null_sink, 240, OMX_TRUE); // Allocate camera input buffer, buffers for tunneled // ports are allocated internally by OMX if((r = OMX_UseEGLImage(ctx.render, &ctx.eglBuffer, 221, NULL, ctx.eglImage)) != OMX_ErrorNone) { omx_die(r, "Failed to use eglimage"); } // Switch state of the components prior to starting // the video capture and encoding loop say("Switching state of the camera component to executing..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to executing"); } say("Switching state of the camera component to executing..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to executing"); } block_until_state_changed(ctx.camera, OMX_StateExecuting); say("Switching state of the render component to executing..."); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to executing"); } block_until_state_changed(ctx.render, OMX_StateExecuting); say("Switching state of the null sink component to executing..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to executing"); } block_until_state_changed(ctx.null_sink, OMX_StateExecuting); // Start capturing video with the camera say("Switching on capture on camera video output port 71..."); OMX_CONFIG_PORTBOOLEANTYPE capture; OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_TRUE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch on capture on camera video output port 71"); } say("Configured port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_FALSE); say("Configured port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_FALSE); say("Configured port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_FALSE); say("Configured port definition for render input port 90"); dump_port(ctx.render, 220, OMX_FALSE); say("Configured port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_FALSE); say("Enter capture and playback loop, press Ctrl-C to quit..."); if((r = OMX_FillThisBuffer(ctx.render, ctx.eglBuffer)) != OMX_ErrorNone) { omx_die(r, "Failed to fill buffer"); } signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGQUIT, signal_handler); while(!want_quit) { // Would be better to use signaling here but hey this works too usleep(1000); } say("Cleaning up..."); // Restore signal handlers signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); // Stop capturing video with the camera OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_FALSE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch off capture on camera video output port 71"); } // Flush the buffers on each component if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera input port 73"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera preview output port 70"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera video output port 71"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.render, OMX_CommandFlush, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of render input port 220"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandFlush, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of null sink input port 240"); } block_until_flushed(&ctx); // Disable all the ports if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera input port 73"); } block_until_port_changed(ctx.camera, 73, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera preview output port 70"); } block_until_port_changed(ctx.camera, 70, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera video output port 71"); } block_until_port_changed(ctx.camera, 71, OMX_FALSE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortDisable, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable render input port 90"); } if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortDisable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable null sink input port 240"); } block_until_port_changed(ctx.null_sink, 240, OMX_FALSE); // Free all the buffers if((r = OMX_FreeBuffer(ctx.camera, 73, ctx.camera_ppBuffer_in)) != OMX_ErrorNone) { omx_die(r, "Failed to free buffer for camera input port 73"); } // Transition all the components to idle and then to loaded states if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.camera, OMX_StateIdle); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to idle"); } block_until_state_changed(ctx.render, OMX_StateIdle); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } block_until_state_changed(ctx.null_sink, OMX_StateIdle); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to loaded"); } block_until_state_changed(ctx.camera, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to loaded"); } block_until_state_changed(ctx.render, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to loaded"); } block_until_state_changed(ctx.null_sink, OMX_StateLoaded); // Free the component handles if((r = OMX_FreeHandle(ctx.camera)) != OMX_ErrorNone) { omx_die(r, "Failed to free camera component handle"); } if((r = OMX_FreeHandle(ctx.render)) != OMX_ErrorNone) { omx_die(r, "Failed to free render component handle"); } if((r = OMX_FreeHandle(ctx.null_sink)) != OMX_ErrorNone) { omx_die(r, "Failed to free null sink component handle"); } // Exit vcos_semaphore_delete(&ctx.handler_lock); if((r = OMX_Deinit()) != OMX_ErrorNone) { omx_die(r, "OMX de-initalization failed"); } say("Exit!"); return 0; }