예제 #1
0
파일: ilcore.c 프로젝트: Andrewftv/lbmc
ret_code_t ilcore_clean_tunnel(ilcore_tunnel_h h)
{
    omx_tunnel_t *tunnel = (omx_tunnel_t *)h;
    OMX_ERRORTYPE omx_err;

    if (!tunnel || !tunnel->src_comp || !tunnel->dst_comp)
    {
        DBG_E("%s: Incorrect parameters\n", __FUNCTION__);
        return L_FAILED;
    }

    ilcore_disable_port(tunnel->src_comp, tunnel->src_port, 0);
    ilcore_disable_port(tunnel->dst_comp, tunnel->dst_port, 0);

    omx_err = OMX_SetupTunnel(ilcore_get_handle(tunnel->src_comp), tunnel->src_port, NULL, 0);
    if(omx_err != OMX_ErrorNone) 
    {
        DBG_E("%s: could not unset tunnel on comp src %s port %d err = 0x%08x\n", __FUNCTION__, 
            ilcore_get_comp_name(tunnel->src_comp), tunnel->src_port, omx_err);
    }
    omx_err = OMX_SetupTunnel(ilcore_get_handle(tunnel->dst_comp), tunnel->dst_port, NULL, 0);
    if(omx_err != OMX_ErrorNone) 
    {
        DBG_E("%s: could not unset tunnel on comp dst %s port %d err = 0x%08x\n", __FUNCTION__, 
            ilcore_get_comp_name(tunnel->dst_comp), tunnel->dst_port, omx_err);
    }

    return L_OK;
}
예제 #2
0
bool Component::tunnelToNull(int port)
{
    bool result = false;
    OMX_ERRORTYPE error;
    if(CustomFillBufferDoneHandler)
    {
        CustomFillBufferDoneHandler = NULL;
    }
    
    if(setToStateIdle())
    {
        disableAllPorts();
        if(getName() != "OMX.broadcom.clock" &&
           getName() != "OMX.broadcom.audio_render" &&
           getName() != "OMX.broadcom.audio_mixer")
        {
            error = OMX_SetupTunnel(handle, port, NULL, 0);
            OMX_TRACE(error);
            if(error == OMX_ErrorNone)
            {
                result = true;  
            } 
        }else
        {
            result = true; 
        }
        
        
    }
    ofLogVerbose(__func__) << getName() << " TUNNELED TO NULL: " << result;
    return result;
    
}
예제 #3
0
파일: omx.c 프로젝트: Ezio-PS/movian
omx_tunnel_t *
omx_tunnel_create(omx_component_t *src, int srcport, omx_component_t *dst,
		  int dstport, const char *name)
{
  OMX_STATETYPE state;
  omxchk(OMX_GetState(src->oc_handle, &state));

  if(state == OMX_StateLoaded)
    omx_set_state(src, OMX_StateIdle);

  omxdbg("Creating tunnel %s from %s:%d to %s:%d\n",
	 name, src->oc_name, srcport, dst->oc_name, dstport);

  omx_send_command(src, OMX_CommandPortDisable, srcport, NULL, 1);
  omx_send_command(dst, OMX_CommandPortDisable, dstport, NULL, 1);
  omxchk(OMX_SetupTunnel(src->oc_handle, srcport, dst->oc_handle, dstport));
  omx_send_command(src, OMX_CommandPortEnable, srcport, NULL, 0);
  omx_send_command(dst, OMX_CommandPortEnable, dstport, NULL, 0);

  omxchk(OMX_GetState(dst->oc_handle, &state));
  if(state == OMX_StateLoaded)
    omx_set_state(dst, OMX_StateIdle);

  omx_tunnel_t *ot = malloc(sizeof(omx_tunnel_t));
  ot->ot_src = src;
  ot->ot_srcport = srcport;
  ot->ot_dst = dst;
  ot->ot_dstport = dstport;
  ot->ot_name = name;
  return ot;
}
예제 #4
0
파일: ilcore.c 프로젝트: Andrewftv/lbmc
ret_code_t ilcore_setup_tunnel(ilcore_tunnel_h h)
{
    omx_tunnel_t *tunnel = (omx_tunnel_t *)h;
    OMX_STATETYPE state;
    OMX_ERRORTYPE omx_err;

    if (!tunnel || !tunnel->src_comp || !tunnel->dst_comp)
    {
        DBG_E("%s: Incorrect parameters\n", __FUNCTION__);
        return L_FAILED;
    }

    if (ilcore_get_state(tunnel->src_comp, &state) != L_OK)
        return L_FAILED;

    if (state == OMX_StateLoaded)
    {
        if (ilcore_set_state(tunnel->src_comp, OMX_StateIdle))
            return L_FAILED;
    }

    if (ilcore_disable_port(tunnel->src_comp, tunnel->src_port, 0) != L_OK)
        return L_FAILED;
    if (ilcore_disable_port(tunnel->dst_comp, tunnel->dst_port, 0) != L_OK)
        return L_FAILED;

    omx_err = OMX_SetupTunnel(ilcore_get_handle(tunnel->src_comp), tunnel->src_port,
        ilcore_get_handle(tunnel->dst_comp), tunnel->dst_port);
    if(omx_err != OMX_ErrorNone) 
    {
        DBG_E("%s: could not setup tunnel src %s port %d dst %s port %d err = 0x%08x\n", __FUNCTION__, 
            ilcore_get_comp_name(tunnel->src_comp), tunnel->src_port, ilcore_get_comp_name(tunnel->dst_comp),
            tunnel->dst_port, omx_err);
        return L_FAILED;
    }

    if (ilcore_enable_port(tunnel->src_comp, tunnel->src_port, 0) != L_OK)
        return L_FAILED;
    if (ilcore_enable_port(tunnel->dst_comp, tunnel->dst_port, 0) != L_OK)
        return L_FAILED;

    if (ilcore_get_state(tunnel->dst_comp, &state) != L_OK)
        return L_FAILED;
    
    omx_err = omx_core_comp_wait_command(tunnel->dst_comp, OMX_CommandPortEnable, tunnel->dst_port, 2000);
    if(omx_err != OMX_ErrorNone)
        return L_FAILED;
    
    if (state == OMX_StateLoaded)
    {
        if (ilcore_set_state(tunnel->dst_comp, OMX_StateIdle))
            return L_FAILED;
    }
    omx_err = omx_core_comp_wait_command(tunnel->src_comp, OMX_CommandPortEnable, tunnel->src_port, 2000);
    if(omx_err != OMX_ErrorNone)
        return L_FAILED;

    return L_OK;
}
OMX_API OMX_ERRORTYPE TIOMX_SetupTunnel(OMX_IN OMX_HANDLETYPE hOutput,
    OMX_IN OMX_U32 nPortOutput,
    OMX_IN OMX_HANDLETYPE hInput, OMX_IN OMX_U32 nPortInput)
{

	ALOGV("TIOMX_SetupTunnel\n");

	return OMX_SetupTunnel(hOutput, nPortOutput, hInput, nPortInput);
}
예제 #6
0
파일: omx.c 프로젝트: kshostak/showtime
void
omx_tunnel_destroy(omx_tunnel_t *ot)
{
  omxdbg("Destroying tunnel\n");
  omx_send_command(ot->ot_src, OMX_CommandPortDisable, ot->ot_srcport, NULL, 0);
  omx_send_command(ot->ot_dst, OMX_CommandPortDisable, ot->ot_dstport, NULL, 0);
  omxchk(OMX_SetupTunnel(ot->ot_src->oc_handle, ot->ot_srcport, NULL, 0));
  free(ot);
}
예제 #7
0
int main(int argc, char** argv) {

    OMX_ERRORTYPE err;
    int argn_dec;
    OMX_STRING full_component_name;
    int isRate=0,isChannel=0;
    OMX_AUDIO_PARAM_PCMMODETYPE sPCMModeParam;
    if(argc < 2) {
        display_help();
    } else {
        flagIsOutputExpected = 0;
        flagDecodedOutputReceived = 0;
        flagIsVolCompRequested = 0;
        flagSetupTunnel = 0;
        flagIsSinkRequested = 0;

        argn_dec = 1;
        while (argn_dec < argc) {
            if (*(argv[argn_dec]) == '-') {
                if (flagIsOutputExpected) {
                    display_help();
                }
                switch (*(argv[argn_dec] + 1)) {
                case 'h' :
                    display_help();
                    break;
                case 't' :
                    flagSetupTunnel = 1;
                    flagIsSinkRequested = 1;
                    flagIsVolCompRequested = 1;
                    break;
                case 's':
                    flagIsSinkRequested = 1;
                    break;
                case 'o':
                    flagIsOutputExpected = 1;
                    break;
                case 'v':
                    flagIsVolCompRequested = 1;
                    break;
                case 'r' :
                    isRate = 1;
                    break;
                case 'n' :
                    isChannel = 1;
                    break;
                default:
                    display_help();
                }
            } else {
                if (flagIsOutputExpected) {
                    if(strstr(argv[argn_dec], ".pcm") == NULL) {
                        output_file = malloc(strlen(argv[argn_dec]) + 5);
                        strcpy(output_file,argv[argn_dec]);
                        strcat(output_file, ".pcm");
                    } else {
                        output_file = malloc(strlen(argv[argn_dec]) + 1);
                        strcpy(output_file,argv[argn_dec]);
                    }
                    flagIsOutputExpected = 0;
                    flagDecodedOutputReceived = 1;
                } else if(isRate) {
                    rate=atoi(argv[argn_dec]);
                    isRate=0;
                    if(rate <0 || rate >48000) {
                        DEBUG(DEB_LEV_ERR, "Bad Parameter rate\n");
                        display_help();
                    }
                } else if(isChannel) {
                    channel=atoi(argv[argn_dec]);
                    isChannel = 0;
                    if(channel <0 || channel >6) {
                        DEBUG(DEB_LEV_ERR, "Bad Parameter channel\n");
                        display_help();
                    }
                }
            }
            argn_dec++;
        }

        /** if volume componenterter component is not selected then sink component will not work, even if specified */
        if(!flagIsVolCompRequested && flagIsSinkRequested) {
            DEBUG(DEB_LEV_ERR, "You requested for sink - not producing any output file\n");
            flagIsVolCompRequested = 1;
            flagDecodedOutputReceived = 0;
        }

        /** output file name check */
        //case 1 - user did not specify any output file
        if(!flagIsOutputExpected && !flagDecodedOutputReceived && !flagIsSinkRequested) {
            DEBUG(DEB_LEV_ERR,"\n you did not enter any output file name");
            output_file = malloc(20);
            strcpy(output_file,"output.pcm");
            DEBUG(DEB_LEV_ERR,"\n the decoded output file name will be %s \n", output_file);
        } else if(flagDecodedOutputReceived) {
            if(flagIsSinkRequested || flagSetupTunnel) {
                flagDecodedOutputReceived = 0;
                DEBUG(DEB_LEV_ERR, "Sink Requested or Components are tunneled. No FILE Output will be produced\n");
            } else {
                //case 2 - user has given wrong format
                if(flagIsVolCompRequested && strstr(output_file, ".pcm") == NULL) {
                    output_file[strlen(output_file) - strlen(strstr(output_file, "."))] = '\0';
                    strcat(output_file, ".rgb");
                    DEBUG(DEB_LEV_ERR,"\n volume component option is selected - so the output file is %s \n", output_file);
                }
            }
        }
        if(flagSetupTunnel) {
            DEBUG(DEFAULT_MESSAGES,"The components are tunneled between themselves\n");
        }
    }

    if(!flagIsSinkRequested) {
        outfile = fopen(output_file, "wb");
        if(outfile == NULL) {
            DEBUG(DEB_LEV_ERR, "Error in opening output file %s\n", output_file);
            exit(1);
        }
    }

    /* Initialize application private data */
    appPriv = malloc(sizeof(appPrivateType));
    appPriv->sourceEventSem = malloc(sizeof(tsem_t));
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            appPriv->alsasinkEventSem = malloc(sizeof(tsem_t));
        }
        appPriv->volumeEventSem = malloc(sizeof(tsem_t));
    }
    appPriv->eofSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->sourceEventSem, 0);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            tsem_init(appPriv->alsasinkEventSem, 0);
        }
        tsem_init(appPriv->volumeEventSem, 0);
    }
    tsem_init(appPriv->eofSem, 0);

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the Omx core\n");
    err = OMX_Init();
    if (err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
        exit(1);
    } else {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Omx core is initialized \n");
    }

    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_ComponentNameEnum();
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_RoleEnum(COMPONENT_NAME_BASE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OMX_ComponentEnumByRole(BASE_ROLE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
    test_OpenClose(COMPONENT_NAME_BASE);
    DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");


    full_component_name = malloc(OMX_MAX_STRINGNAME_SIZE);
    strcpy(full_component_name, "OMX.st.alsa.alsasrc");

    DEBUG(DEFAULT_MESSAGES, "The component selected for decoding is %s\n", full_component_name);

    /** getting audio source handle */
    err = OMX_GetHandle(&appPriv->audiosrchandle, full_component_name, NULL, &audiosrccallbacks);
    if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "No audio source component found. Exiting...\n");
        exit(1);
    } else {
        DEBUG(DEFAULT_MESSAGES, "Found The component for capturing is %s\n", full_component_name);
    }

    /** getting volume componenterter component handle, if specified */
    if(flagIsVolCompRequested == 1) {
        err = OMX_GetHandle(&appPriv->volume_handle, "OMX.st.volume.component", NULL, &volume_callbacks);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "No volume componenterter component found. Exiting...\n");
            exit(1);
        } else {
            DEBUG(DEFAULT_MESSAGES, "Found The component for volume componenterter \n");
        }

        /** getting sink component handle - if reqd' */
        if(flagIsSinkRequested == 1) {
            err = OMX_GetHandle(&appPriv->alsasink_handle, "OMX.st.alsa.alsasink", NULL, &alsasink_callbacks);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "No audio sink component component found. Exiting...\n");
                exit(1);
            } else {
                DEBUG(DEFAULT_MESSAGES, "Found The audio sink component for volume componenterter \n");
            }
        }
    }

    if(rate >0 || channel >0) {
        setHeader(&sPCMModeParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
        err = OMX_GetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in GetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        sPCMModeParam.nChannels = (channel >0 ) ? channel:sPCMModeParam.nChannels;
        sPCMModeParam.nSamplingRate = (rate >0 ) ? rate:sPCMModeParam.nSamplingRate;
        err = OMX_SetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        if(flagIsSinkRequested) {
            err = OMX_SetParameter(appPriv->alsasink_handle,OMX_IndexParamAudioPcm,&sPCMModeParam);
            if (err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSink. Exiting...\n");
                exit(1);
            }
        }
    } else if(flagIsSinkRequested) {
        setHeader(&sPCMModeParam, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
        err = OMX_GetParameter(appPriv->audiosrchandle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in GetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSrc. Exiting...\n");
            exit(1);
        }
        err = OMX_SetParameter(appPriv->alsasink_handle,OMX_IndexParamAudioPcm,&sPCMModeParam);
        if (err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Err in SetParameter OMX_AUDIO_PARAM_PCMMODETYPE in AlsaSink. Exiting...\n");
            exit(1);
        }
    }

    /** output buffer size calculation based on input dimension speculation */
    DEBUG(DEB_LEV_SIMPLE_SEQ, "\n buffer_out_size : %d \n", (int)buffer_out_size);

    /** if tunneling option is given then set up the tunnel between the components */
    if (flagSetupTunnel) {
        DEBUG(DEB_LEV_SIMPLE_SEQ, "Setting up Tunnel\n");
        err = OMX_SetupTunnel(appPriv->audiosrchandle, 0, appPriv->volume_handle, 0);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Set up Tunnel between audio src & volume component Failed\n");
            exit(1);
        }
        err = OMX_SetupTunnel(appPriv->volume_handle, 1, appPriv->alsasink_handle, 0);
        if(err != OMX_ErrorNone) {
            DEBUG(DEB_LEV_ERR, "Set up Tunnel between volume component & audio sink Failed\n");
            exit(1);
        }
        DEBUG(DEFAULT_MESSAGES, "Set up Tunnel Completed\n");
    }

    /** sending command to audio source component to go to idle state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);

    /** in tunnel case, change the volume component and sink comp state to idle */
    if(flagIsVolCompRequested && flagSetupTunnel) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        if(flagIsSinkRequested && flagSetupTunnel) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        }
    }

    if(flagSetupTunnel) {
        if(flagIsSinkRequested) {
            tsem_down(appPriv->alsasinkEventSem);
        }
        if(flagIsVolCompRequested) {
            tsem_down(appPriv->volumeEventSem);
        }
    }

    /** if tunneling option is not given then allocate buffers on audio source output port */
    if (!flagSetupTunnel) {
        pOutBuffer[0] = pOutBuffer[1] = NULL;
        err = OMX_AllocateBuffer(appPriv->audiosrchandle, &pOutBuffer[0], 0, NULL, buffer_out_size);
        err = OMX_AllocateBuffer(appPriv->audiosrchandle, &pOutBuffer[1], 0, NULL, buffer_out_size);
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
    tsem_down(appPriv->sourceEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "source Sem free\n");

    if(!flagSetupTunnel) {
        if(flagIsVolCompRequested == 1) {
            pOutBufferVolc[0] = pOutBufferVolc[1] = NULL;
            err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);

            /** in non tunneled case, using buffers in volume component input port, allocated by audio dec component output port */
            err = OMX_UseBuffer(appPriv->volume_handle, &pInBufferVolc[0], 0, NULL, buffer_out_size, pOutBuffer[0]->pBuffer);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to use the volume component comp allocate buffer\n");
                exit(1);
            }
            err = OMX_UseBuffer(appPriv->volume_handle, &pInBufferVolc[1], 0, NULL, buffer_out_size, pOutBuffer[1]->pBuffer);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to use the volume component comp allocate buffer\n");
                exit(1);
            }

            /** allocating buffers in the volume componenterter compoennt output port */

            err = OMX_AllocateBuffer(appPriv->volume_handle, &pOutBufferVolc[0], 1, NULL, buffer_out_size);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in volume component\n");
                exit(1);
            }
            err = OMX_AllocateBuffer(appPriv->volume_handle, &pOutBufferVolc[1], 1, NULL, buffer_out_size);
            if(err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in colro conv\n");
                exit(1);
            }

            DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
            tsem_down(appPriv->volumeEventSem);
            DEBUG(DEFAULT_MESSAGES, "volume Event Sem free\n");

            if(flagIsSinkRequested == 1) {
                err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
                err = OMX_UseBuffer(appPriv->alsasink_handle, &pInBufferSink[0], 0, NULL, buffer_out_size, pOutBufferVolc[0]->pBuffer);
                if(err != OMX_ErrorNone) {
                    DEBUG(DEB_LEV_ERR, "Unable to use the alsasink_handle comp allocate buffer\n");
                    exit(1);
                }
                err = OMX_UseBuffer(appPriv->alsasink_handle, &pInBufferSink[1], 0, NULL, buffer_out_size, pOutBufferVolc[1]->pBuffer);
                if(err != OMX_ErrorNone) {
                    DEBUG(DEB_LEV_ERR, "Unable to use the alsasink_handle comp allocate buffer\n");
                    exit(1);
                }

                DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
                tsem_down(appPriv->alsasinkEventSem);
                DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink comp Sem free\n");
            }
        }

        if(flagIsVolCompRequested == 1) {
            err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
            tsem_down(appPriv->volumeEventSem);
            if(flagIsSinkRequested == 1) {
                err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
                tsem_down(appPriv->alsasinkEventSem);
            }
        }
    }

    /** send command to change color onv and sink comp in executing state */
    if(flagIsVolCompRequested == 1 && flagSetupTunnel) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
        tsem_down(appPriv->volumeEventSem);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
            tsem_down(appPriv->alsasinkEventSem);
        }
    }

    /** sending command to audio source component to go to executing state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    tsem_down(appPriv->sourceEventSem);

    if(flagIsVolCompRequested == 1 && !flagSetupTunnel) {
        err = OMX_FillThisBuffer(appPriv->volume_handle, pOutBufferVolc[0]);
        err = OMX_FillThisBuffer(appPriv->volume_handle, pOutBufferVolc[1]);
        DEBUG(DEFAULT_MESSAGES, "---> After fill this buffer function calls to the volume component output buffers\n");
    }
    if (!flagSetupTunnel) {
        err = OMX_FillThisBuffer(appPriv->audiosrchandle, pOutBuffer[0]);
        err = OMX_FillThisBuffer(appPriv->audiosrchandle, pOutBuffer[1]);
    }

    DEBUG(DEB_LEV_SIMPLE_SEQ, "---> Before locking on condition and sourceMutex\n");

    DEBUG(DEFAULT_MESSAGES,"Enter 'q' or 'Q' to exit\n");

    while(1) {
        if('Q' == toupper(getchar())) {
            DEBUG(DEFAULT_MESSAGES,"Stoping capture\n");
            bEOS = OMX_TRUE;
            usleep(10000);
            break;
        }
    }

    DEBUG(DEFAULT_MESSAGES, "The execution of the audio decoding process is terminated\n");

    /** state change of all components from executing to idle */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    if(flagIsVolCompRequested == 1) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
        }
    }

    tsem_down(appPriv->sourceEventSem);
    if(flagIsVolCompRequested == 1) {
        tsem_down(appPriv->volumeEventSem);
        if(flagIsSinkRequested == 1) {
            tsem_down(appPriv->alsasinkEventSem);
        }
    }

    DEBUG(DEFAULT_MESSAGES, "All audio components Transitioned to Idle\n");

    /** sending command to all components to go to loaded state */
    err = OMX_SendCommand(appPriv->audiosrchandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
    if(flagIsVolCompRequested == 1) {
        err = OMX_SendCommand(appPriv->volume_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
        if(flagIsSinkRequested == 1) {
            err = OMX_SendCommand(appPriv->alsasink_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
        }
    }

    /** freeing buffers of volume component and sink component */
    if(flagIsVolCompRequested == 1 && !flagSetupTunnel) {

        DEBUG(DEB_LEV_SIMPLE_SEQ, "volume component to loaded\n");
        err = OMX_FreeBuffer(appPriv->volume_handle, 0, pInBufferVolc[0]);
        err = OMX_FreeBuffer(appPriv->volume_handle, 0, pInBufferVolc[1]);

        err = OMX_FreeBuffer(appPriv->volume_handle, 1, pOutBufferVolc[0]);
        err = OMX_FreeBuffer(appPriv->volume_handle, 1, pOutBufferVolc[1]);

        if(flagIsSinkRequested == 1) {
            DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio sink to loaded\n");
            err = OMX_FreeBuffer(appPriv->alsasink_handle, 0, pInBufferSink[0]);
            err = OMX_FreeBuffer(appPriv->alsasink_handle, 0, pInBufferSink[1]);
        }
    }

    /** freeing buffers of audio source input ports */
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio dec to loaded\n");
    if(!flagSetupTunnel) {
        DEBUG(DEB_LEV_PARAMS, "Free Audio dec output ports\n");
        err = OMX_FreeBuffer(appPriv->audiosrchandle, 0, pOutBuffer[0]);
        err = OMX_FreeBuffer(appPriv->audiosrchandle, 0, pOutBuffer[1]);
    }

    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            tsem_down(appPriv->alsasinkEventSem);
        }
        tsem_down(appPriv->volumeEventSem);
    }
    tsem_down(appPriv->sourceEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "All components released\n");

    OMX_FreeHandle(appPriv->audiosrchandle);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            OMX_FreeHandle(appPriv->alsasink_handle);
        }
        OMX_FreeHandle(appPriv->volume_handle);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audio dec freed\n");

    OMX_Deinit();

    DEBUG(DEFAULT_MESSAGES, "All components freed. Closing...\n");
    free(appPriv->sourceEventSem);
    if(flagIsVolCompRequested == 1) {
        if(flagIsSinkRequested == 1) {
            free(appPriv->alsasinkEventSem);
        }
        free(appPriv->volumeEventSem);
    }
    free(appPriv->eofSem);
    free(appPriv);

    free(full_component_name);

    /** closing the output file */
    if(!flagIsSinkRequested) {
        fclose(outfile);
    }
    if(output_file) {
        free(output_file);
    }

    return 0;
}
    OMX_ERRORTYPE PortCommTest_OperateOnPorts(PortCommTestCtxt* pContext, PortOpType eOp)
    {
        OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
        OMX_ERRORTYPE eError = OMX_ErrorNone;
        OMX_U32 i, j;
        OMX_BUFFERHEADERTYPE sBufHdr;

        for (j = 0; j < NUM_DOMAINS; j++)
        {
            for (i = pContext->sPortParam[j].nStartPortNumber;
                    i < pContext->sPortParam[j].nStartPortNumber + pContext->sPortParam[j].nPorts; i++)
            {

                OMX_CONF_INIT_STRUCT(sPortDef, OMX_PARAM_PORTDEFINITIONTYPE);
                sPortDef.nPortIndex = i;
                OMX_CONF_BAIL_IF_ERROR(OMX_GetParameter(pContext->hWComp, OMX_IndexParamPortDefinition ,
                                                        (OMX_PTR)&sPortDef));
                switch (eOp)
                {
                    case AllocBuf:
                        if (0x0 == sPortDef.nBufferCountMin || sPortDef.nBufferCountMin > sPortDef.nBufferCountActual)
                        {
                            OMX_CONF_SET_ERROR_BAIL("PortDefinition nBufferCount incorrect\n", OMX_ErrorUndefined);
                        }
                        OMX_CONF_BAIL_IF_ERROR(PortCommTest_AllocateBuffers(pContext, &sPortDef));
                        break;

                    case NonTunnelTest:
                        if (sPortDef.eDir == OMX_DirInput)
                        {
                            eError = OMX_SetupTunnel(NULL, 0, pContext->hWComp, sPortDef.nPortIndex);
                            OMX_CONF_ErrorToString(eError, szDesc);
                            OMX_OSAL_Trace(OMX_OSAL_TRACE_INFO, "Setup tunnel reported error code %s\n", szDesc);
                        }
                        else
                        {
                            eError = OMX_SetupTunnel(pContext->hWComp, sPortDef.nPortIndex, NULL, 0);
                            OMX_CONF_ErrorToString(eError, szDesc);
                            OMX_OSAL_Trace(OMX_OSAL_TRACE_INFO, "Setup tunnel reported error code %s\n", szDesc);
                        }
                        eError = OMX_ErrorNone;
                        break;

                    case OpenFile:
                        /* set buffercount actual */
                        if (0x0 == sPortDef.nBufferCountMin || sPortDef.nBufferCountMin > sPortDef.nBufferCountActual)
                        {
                            OMX_CONF_SET_ERROR_BAIL("PortDefinition nBufferCount incorrect\n", OMX_ErrorUndefined);
                        }
                        sPortDef.nBufferCountActual = sPortDef.nBufferCountMin + 1;
                        OMX_CONF_BAIL_IF_ERROR(OMX_SetParameter(pContext->hWComp, OMX_IndexParamPortDefinition,
                                                                (OMX_PTR)&sPortDef));
                        /* open files for input ports */
                        if (sPortDef.eDir == OMX_DirInput)
                        {
                            OMX_OSAL_Trace(OMX_OSAL_TRACE_INFO, "Opened input file for port %d\n", i);
                            OMX_CONF_BAIL_IF_ERROR(OMX_OSAL_OpenInputFile(i));
                        }
                        break;

                    case CloseFile:
                        if (sPortDef.eDir == OMX_DirInput)
                        {
                            OMX_CONF_BAIL_IF_ERROR(OMX_OSAL_CloseInputFile(i));
                        }
                        break;

                    case EmptyFill:
                        OMX_CONF_INIT_STRUCT(sBufHdr, OMX_BUFFERHEADERTYPE);
                        if (sPortDef.eDir == OMX_DirInput)
                        {
                            sBufHdr.nInputPortIndex = i;
                            eError = OMX_EmptyThisBuffer(pContext->hWComp, &sBufHdr);
                        }
                        else
                        {
                            sBufHdr.nOutputPortIndex = i;
                            eError = OMX_FillThisBuffer(pContext->hWComp, &sBufHdr);
                        }
                        if (eError != OMX_ErrorIncorrectStateOperation)
                            OMX_CONF_SET_ERROR_BAIL("Buffer handling while stopped\n", OMX_ErrorUndefined);
                        eError = OMX_ErrorNone;
                        break;

                    default:
                        eError = OMX_ErrorBadParameter;
                }
            }
        }
OMX_CONF_TEST_BAIL:
        return eError;
    }
예제 #9
0
파일: jpeg.c 프로젝트: 1234sv/firmware
// this function cleans up the decoder.
void
cleanup(OPENMAX_JPEG_DECODER * decoder)
{
    // flush everything through
    OMX_SendCommand(decoder->imageDecoder->handle,
		    OMX_CommandFlush, decoder->imageDecoder->outPort,
		    NULL);
    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete, OMX_CommandFlush, 0,
			    decoder->imageDecoder->outPort, 0, 0,
			    TIMEOUT_MS);
    OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandFlush,
		    decoder->imageResizer->inPort, NULL);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandFlush, 0,
			    decoder->imageResizer->inPort, 1, 0,
			    TIMEOUT_MS);

    OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortDisable,
		    decoder->imageDecoder->inPort, NULL);

    int             i = 0;
    for (i = 0; i < decoder->inputBufferHeaderCount; i++) {
	OMX_BUFFERHEADERTYPE *vpBufHeader =
	    decoder->ppInputBufferHeader[i];

	OMX_FreeBuffer(decoder->imageDecoder->handle,
		       decoder->imageDecoder->inPort, vpBufHeader);
    }

    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete, OMX_CommandPortDisable,
			    0, decoder->imageDecoder->inPort, 0, 0,
			    TIMEOUT_MS);

    OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortDisable,
		    decoder->imageResizer->outPort, NULL);

    OMX_FreeBuffer(decoder->imageResizer->handle,
		   decoder->imageResizer->outPort,
		   decoder->pOutputBufferHeader);

    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandPortDisable,
			    0, decoder->imageResizer->outPort, 0, 0,
			    TIMEOUT_MS);

    OMX_SendCommand(decoder->imageDecoder->handle, OMX_CommandPortDisable,
		    decoder->imageDecoder->outPort, NULL);
    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete, OMX_CommandPortDisable,
			    0, decoder->imageDecoder->outPort, 0, 0,
			    TIMEOUT_MS);

    OMX_SendCommand(decoder->imageResizer->handle, OMX_CommandPortDisable,
		    decoder->imageResizer->inPort, NULL);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandPortDisable,
			    0, decoder->imageResizer->inPort, 0, 0,
			    TIMEOUT_MS);

    OMX_SetupTunnel(decoder->imageDecoder->handle,
		    decoder->imageDecoder->outPort, NULL, 0);
    OMX_SetupTunnel(decoder->imageResizer->handle,
		    decoder->imageResizer->inPort, NULL, 0);

    ilclient_change_component_state(decoder->imageDecoder->component,
				    OMX_StateIdle);
    ilclient_change_component_state(decoder->imageResizer->component,
				    OMX_StateIdle);

    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete, OMX_CommandStateSet, 0,
			    OMX_StateIdle, 0, 0, TIMEOUT_MS);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandStateSet, 0,
			    OMX_StateIdle, 0, 0, TIMEOUT_MS);

    ilclient_change_component_state(decoder->imageDecoder->component,
				    OMX_StateLoaded);
    ilclient_change_component_state(decoder->imageResizer->component,
				    OMX_StateLoaded);

    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete, OMX_CommandStateSet, 0,
			    OMX_StateLoaded, 0, 0, TIMEOUT_MS);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandStateSet, 0,
			    OMX_StateLoaded, 0, 0, TIMEOUT_MS);

    OMX_Deinit();

    if (decoder->client != NULL) {
	ilclient_destroy(decoder->client);
    }
}
예제 #10
0
OMX_ERRORTYPE omx_setup_pipeline(struct omx_pipeline_t* pipe, OMX_VIDEO_CODINGTYPE video_codec, char* audio_dest, int is_hd)
{
  OMX_VIDEO_PARAM_PORTFORMATTYPE format;
  OMX_TIME_CONFIG_CLOCKSTATETYPE cstate;

  OMX_CONFIG_BOOLEANTYPE configBoolTrue;
  OMX_INIT_STRUCTURE(configBoolTrue);
  configBoolTrue.bEnabled = OMX_TRUE;

  pipe->do_deinterlace = 0;

  if (((is_hd == 0) && (global_settings.deinterlace_sd)) || ((is_hd == 1) && (global_settings.deinterlace_hd))) {
    DEBUGF("Enabling de-interlace\n");
    pipe->do_deinterlace = 1;
  }

  omx_init_component(pipe, &pipe->video_decode, "OMX.broadcom.video_decode");
  omx_init_component(pipe, &pipe->video_render, "OMX.broadcom.video_render");

  if (pipe->do_deinterlace) {
    DEBUGF("Enabling de-interlacer\n");
    /* De-interlacer.  Input port 190, Output port 191.  Insert between decoder and scheduler */
    omx_init_component(pipe, &pipe->image_fx, "OMX.broadcom.image_fx");

    /* Configure image_fx */
    omx_send_command_and_wait(&pipe->image_fx, OMX_CommandStateSet, OMX_StateIdle, NULL);

    OMX_CONFIG_IMAGEFILTERPARAMSTYPE imagefilter;
    OMX_INIT_STRUCTURE(imagefilter);
    imagefilter.nPortIndex=191;
    imagefilter.nNumParams=1;
    imagefilter.nParams[0]=3; //???
    imagefilter.eImageFilter=OMX_ImageFilterDeInterlaceAdvanced;

    OERR(OMX_SetConfig(pipe->image_fx.h, OMX_IndexConfigCommonImageFilterParameters, &imagefilter));
  } else {
    memset(&pipe->image_fx,0,sizeof(struct omx_component_t));
  }


  omx_init_component(pipe, &pipe->clock, "OMX.broadcom.clock");

  OMX_INIT_STRUCTURE(cstate);
  cstate.eState = OMX_TIME_ClockStateWaitingForStartTime;
  cstate.nWaitMask = OMX_CLOCKPORT0|OMX_CLOCKPORT1;
  OERR(OMX_SetParameter(pipe->clock.h, OMX_IndexConfigTimeClockState, &cstate));

  OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE refClock;
  OMX_INIT_STRUCTURE(refClock);
  refClock.eClock = OMX_TIME_RefClockAudio;
  OERR(OMX_SetConfig(pipe->clock.h, OMX_IndexConfigTimeActiveRefClock, &refClock));

  omx_init_component(pipe, &pipe->video_scheduler, "OMX.broadcom.video_scheduler");

  /* Initialise audio output - hardcoded to 48000/Stereo/16-bit */
  omx_init_component(pipe, &pipe->audio_render, "OMX.broadcom.audio_render");

  OMX_PARAM_PORTDEFINITIONTYPE param;
  OMX_INIT_STRUCTURE(param);
  param.nPortIndex = 100;

  OERR(OMX_GetParameter(pipe->audio_render.h, OMX_IndexParamPortDefinition, &param));
  param.nBufferSize = 8192;  /* Needs to be big enough for one frame of data */
  param.nBufferCountActual = 32; /* Arbitrary */
  OERR(OMX_SetParameter(pipe->audio_render.h, OMX_IndexParamPortDefinition, &param));

  omx_config_pcm(&pipe->audio_render, 48000, 2, 16, audio_dest);

  OERR(OMX_SetConfig(pipe->audio_render.h, OMX_IndexConfigBrcmClockReferenceSource, &configBoolTrue));

  omx_send_command_and_wait(&pipe->audio_render, OMX_CommandStateSet, OMX_StateIdle, NULL);

  omx_send_command_and_wait0(&pipe->audio_render, OMX_CommandPortEnable, 100, NULL);
  omx_alloc_buffers(&pipe->audio_render, 100);
  omx_send_command_and_wait1(&pipe->audio_render, OMX_CommandPortEnable, 100, NULL);


  /* Setup clock tunnels first */
  omx_send_command_and_wait(&pipe->clock, OMX_CommandStateSet, OMX_StateIdle, NULL);

  OERR(OMX_SetupTunnel(pipe->clock.h, 80, pipe->audio_render.h, 101));
  OERR(OMX_SetupTunnel(pipe->clock.h, 81, pipe->video_scheduler.h, 12));

  OERR(OMX_SendCommand(pipe->clock.h, OMX_CommandPortEnable, 80, NULL));
  OERR(OMX_SendCommand(pipe->video_scheduler.h, OMX_CommandPortEnable, 12, NULL));

  OERR(OMX_SendCommand(pipe->clock.h, OMX_CommandPortEnable, 81, NULL));
  OERR(OMX_SendCommand(pipe->audio_render.h, OMX_CommandPortEnable, 101, NULL));

  omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandStateSet, OMX_StateIdle, NULL);

  omx_send_command_and_wait(&pipe->clock, OMX_CommandStateSet, OMX_StateExecuting, NULL);

  /* Configure video_decoder */
  omx_send_command_and_wait(&pipe->video_decode, OMX_CommandStateSet, OMX_StateIdle, NULL);

  /* Enable lazy image pool destroying */
  OERR(OMX_SetConfig(pipe->video_decode.h, OMX_IndexParamBrcmLazyImagePoolDestroy, &configBoolTrue));

  OMX_INIT_STRUCTURE(format);
  format.nPortIndex = 130;
  format.eCompressionFormat = video_codec;

  OERR(OMX_SetParameter(pipe->video_decode.h, OMX_IndexParamVideoPortFormat, &format));

   /* Enable error concealment for H264 only - without this, HD channels don't work reliably */
  if (video_codec == OMX_VIDEO_CodingAVC) {
     OMX_PARAM_BRCMVIDEODECODEERRORCONCEALMENTTYPE ec;
     OMX_INIT_STRUCTURE(ec);
     ec.bStartWithValidFrame = OMX_FALSE;
     OERR(OMX_SetParameter(pipe->video_decode.h, OMX_IndexParamBrcmVideoDecodeErrorConcealment, &ec));
  }

  /* Enable video decoder input port */
  omx_send_command_and_wait0(&pipe->video_decode, OMX_CommandPortEnable, 130, NULL);

  /* Allocate input buffers */
  omx_alloc_buffers(&pipe->video_decode, 130);

  /* Wait for input port to be enabled */
  omx_send_command_and_wait1(&pipe->video_decode, OMX_CommandPortEnable, 130, NULL);

  /* Change video_decode to OMX_StateExecuting */
  omx_send_command_and_wait(&pipe->video_decode, OMX_CommandStateSet, OMX_StateExecuting, NULL);

  /* Change audio_render to OMX_StateExecuting */
  omx_send_command_and_wait(&pipe->audio_render, OMX_CommandStateSet, OMX_StateExecuting, NULL);

  /* Enable passing of buffer marks */
  OERR(OMX_SetParameter(pipe->video_decode.h, OMX_IndexParamPassBufferMarks, &configBoolTrue));
  OERR(OMX_SetParameter(pipe->video_render.h, OMX_IndexParamPassBufferMarks, &configBoolTrue));

  return OMX_ErrorNone;
}
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;
}
예제 #12
0
파일: omxtxres.c 프로젝트: arjenv/omxtx
static void configure(struct context *ctx)
{
	pthread_t	fpst;
	pthread_attr_t	fpsa;
	OMX_CONFIG_FRAMERATETYPE	*framerate;
	OMX_VIDEO_PARAM_PROFILELEVELTYPE *level;
	OMX_VIDEO_PARAM_BITRATETYPE	*bitrate;
	OMX_BUFFERHEADERTYPE		*encbufs;
	OMX_PARAM_PORTDEFINITIONTYPE	*portdef, *portimgdef;
	OMX_VIDEO_PORTDEFINITIONTYPE	*viddef;
	OMX_VIDEO_PARAM_PORTFORMATTYPE	*pfmt;
	OMX_CONFIG_POINTTYPE		*pixaspect;
	int encportidx, decportidx, resizeportidx;
	OMX_HANDLETYPE	m2, m4, resize;

	encportidx = ctx->encportidx;
	decportidx = ctx->decportidx;
	resizeportidx = ctx->resizeportidx;
	m2 = ctx->m2;
	m4 = ctx->m4;
	resize = ctx->resize;

	MAKEME(portdef, OMX_PARAM_PORTDEFINITIONTYPE);
	MAKEME(portimgdef, OMX_PARAM_PORTDEFINITIONTYPE);
	viddef = &portdef->format.video;
	MAKEME(pixaspect, OMX_CONFIG_POINTTYPE);

	printf("Decoder has changed settings.  Setting up resizer.\n");

/*	We need some parameters from de decoder output to put in the resizer:
	eColorFormat (= YUV42-PackedPlanar)
	Width of the frame
	Height of the frame
*/
	portdef->nPortIndex = decportidx+1;
	OERR(OMX_GetParameter(m2, OMX_IndexParamPortDefinition, portdef), ctx->verbose);
	portimgdef->nPortIndex = resizeportidx;

	OERR(OMX_GetParameter(resize, OMX_IndexParamPortDefinition, portimgdef), ctx->verbose);

	portimgdef->format.image.eColorFormat = portdef->format.video.eColorFormat;
	portimgdef->format.image.nFrameWidth = portdef->format.video.nFrameWidth;
	portimgdef->format.image.nFrameHeight = portdef->format.video.nFrameHeight;
	portimgdef->format.image.nStride = 0;
	portimgdef->format.image.nSliceHeight = 0;
	OERR(OMX_SetParameter(resize, OMX_IndexParamPortDefinition, portimgdef), ctx->verbose);

//	The actual resizing if set at call
	if(ctx->width) {
	 	portimgdef->format.image.nFrameWidth = ctx->width;
		portimgdef->format.image.nFrameHeight = ctx->height;
	}
	portimgdef->format.image.nStride = 0;
	portimgdef->format.image.nSliceHeight = 0;
	portimgdef->nPortIndex = resizeportidx+1;
	OERR(OMX_SetParameter(resize, OMX_IndexParamPortDefinition, portimgdef), ctx->verbose);
	free (portimgdef);

/*	Now set the input parameters for the encoder to the scaled height/width */
	portdef->format.video.nFrameWidth = portimgdef->format.image.nFrameWidth;
	portdef->format.video.nFrameHeight = portimgdef->format.image.nFrameHeight;
	portdef->format.video.nStride = 0;
	portdef->format.video.nSliceHeight = 0;
	portdef->nPortIndex = encportidx;
	OERR(OMX_SetParameter(m4, OMX_IndexParamPortDefinition, portdef), ctx->verbose);

/*	setup tunnels */
	OERR(OMX_SetupTunnel(m2, decportidx+1, resize, resizeportidx), ctx->verbose);
	OERR(OMX_SetupTunnel(resize, resizeportidx+1, m4, encportidx), ctx->verbose);

//	OERR(OMX_SendCommand(m2, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx->verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx->verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx->verbose);

	viddef = &portdef->format.video;
	if (viddef->nBitrate != 0) {
		viddef->nBitrate *= 3;
		viddef->nBitrate /= 4;
	} else {
		viddef->nBitrate = (1*1024*1024/2);
	}
//		viddef->nBitrate = (2*1024*1024);
//	viddef->nFrameWidth  /= 2;
//	viddef->nFrameHeight /= 2;

	viddef->eCompressionFormat = OMX_VIDEO_CodingAVC;
	viddef->nStride = viddef->nSliceHeight = viddef->eColorFormat = 0;
	portdef->nPortIndex = encportidx+1;
	OERR(OMX_SetParameter(m4, OMX_IndexParamPortDefinition, portdef), ctx->verbose);
	free(portdef);

	MAKEME(bitrate, OMX_VIDEO_PARAM_BITRATETYPE);
	bitrate->nPortIndex = encportidx+1;
	bitrate->eControlRate = OMX_Video_ControlRateVariable;
	bitrate->nTargetBitrate = viddef->nBitrate;
	OERR(OMX_SetParameter(m4, OMX_IndexParamVideoBitrate, bitrate), ctx->verbose);
	free(bitrate);

	MAKEME(pfmt, OMX_VIDEO_PARAM_PORTFORMATTYPE);
	pfmt->nPortIndex = encportidx+1;
	pfmt->nIndex = 0;
	pfmt->eCompressionFormat = OMX_VIDEO_CodingAVC;
	pfmt->eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
	pfmt->xFramerate = viddef->xFramerate;

	pixaspect->nPortIndex = encportidx+1;
	pixaspect->nX = 118;
	pixaspect->nY = 81;
	OERR(OMX_SetConfig(m4, OMX_IndexParamBrcmPixelAspectRatio, pixaspect), ctx->verbose);
	free(pixaspect);

//		DUMPPORT(m4, encportidx+1); exit(0);
	pfmt->nPortIndex = encportidx+1;
	pfmt->nIndex = 1;
	pfmt->eCompressionFormat = OMX_VIDEO_CodingAVC;
	pfmt->eColorFormat = 0;
	pfmt->xFramerate = 0; //viddef->xFramerate;
	OERR(OMX_SetParameter(m4, OMX_IndexParamVideoPortFormat, pfmt), ctx->verbose);
	free(pfmt);
	
	MAKEME(framerate, OMX_CONFIG_FRAMERATETYPE);
	framerate->nPortIndex = encportidx+1;
	framerate->xEncodeFramerate = viddef->xFramerate;
	OERR(OMX_SetParameter(m4, OMX_IndexConfigVideoFramerate, framerate), ctx->verbose);
	free(framerate);

#if 0 /* Doesn't seem to apply to video? */
printf("Interlacing: %d\n", ic->streams[vidindex]->codec->field_order);
	if (0 || ic->streams[vidindex]->codec->field_order == AV_FIELD_TT) {
		interlace->nPortIndex = encportidx+1;
		interlace->eMode = OMX_InterlaceFieldsInterleavedUpperFirst;
		interlace->bRepeatFirstField = 0;
		OERR(OMX_SetParameter(m4, OMX_IndexConfigCommonInterlace,
			interlace), ctx->verbose);
	}
#endif

	MAKEME(level, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
	level->nPortIndex = encportidx+1;
	OERR(OMX_GetParameter(m4, OMX_IndexParamVideoProfileLevelCurrent, level), ctx->verbose);
	if (ctx->verbose) printf("Current level:\t\t%d\nCurrent profile:\t%d\n",
		level->eLevel, level->eProfile);
	OERR(OMX_SetParameter(m4, OMX_IndexParamVideoProfileLevelCurrent, level), ctx->verbose);
	free(level);
	ctx->encbufs = encbufs = allocbufs(m4, encportidx+1, 1);
	OERR(OMX_SendCommand(m2, OMX_CommandPortEnable, decportidx+1, NULL), ctx->verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortEnable, resizeportidx, NULL), ctx->verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortEnable, resizeportidx+1, NULL), ctx->verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandPortEnable, encportidx, NULL), ctx->verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandStateSet, OMX_StateExecuting, NULL), ctx->verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandStateSet, OMX_StateExecuting, NULL), ctx->verbose);
	sleep(1);
	OERR(OMX_FillThisBuffer(m4, encbufs), ctx->verbose);

/* Dump current port states: */
	if (ctx->verbose) {
		dumpport(m2, decportidx);
		dumpport(m2, decportidx+1);
		dumpport(resize, resizeportidx);
		dumpport(resize, resizeportidx+1);
		dumpport(m4, encportidx);
		dumpport(m4, encportidx+1);
	}

	if (ctx->verbose) atexit(dumpportstate);
	pthread_attr_init(&fpsa);
	pthread_attr_setdetachstate(&fpsa, PTHREAD_CREATE_DETACHED);
	pthread_create(&fpst, &fpsa, fps, NULL);
}
예제 #13
0
파일: video.c 프로젝트: drhastings/balance
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;
}
예제 #14
0
		CTunnel(CComponentPort* pSource, CComponentPort* pSink)
		{
			OMX_HANDLETYPE hSource = pSource ? pSource->m_hComponent : 0, hSink = pSink ? pSink->m_hComponent : 0;
			unsigned int nSourcePort = pSource ? pSource->m_nId : 0, nSinkPort = pSink ? pSink->m_nId : 0;
			CHECK_OMX(OMX_SetupTunnel(hSource, nSourcePort, hSink, nSinkPort), "failed to setup tunnel");
		}
예제 #15
0
OMXCAM_ERROR OMXCAM_still (OMXCAM_STILL_SETTINGS* settings){
  OMXCAM_trace ("Capturing still");
  
  if (!settings->bufferCallback){
    OMXCAM_error ("The 'bufferCallback' field must be defined");
    return OMXCAM_ErrorBadParameter;
  }
  
  OMXCAM_ERROR err;
  
  if ((err = OMXCAM_init ())) return err;
  
  int useEncoder;
  OMX_COLOR_FORMATTYPE colorFormat;
  OMX_U32 stride;
  OMXCAM_COMPONENT* fillComponent;
  OMX_ERRORTYPE error;
  
  //Stride is byte-per-pixel*width
  //See mmal/util/mmal_util.c, mmal_encoding_width_to_stride()
  
  switch (settings->format){
    case OMXCAM_FormatRGB888:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_Format24bitRGB888;
      stride = settings->camera.width*3;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatRGBA8888:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_Format32bitABGR8888;
      stride = settings->camera.width*4;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatYUV420:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
      stride = settings->camera.width;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatJPEG:
      OMXCAM_ctx.image_encode.bufferCallback = settings->bufferCallback;
      useEncoder = 1;
      colorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
      stride = settings->camera.width;
      fillComponent = &OMXCAM_ctx.image_encode;
      break;
    default:
      return OMXCAM_ErrorFormat;
  }

  if (OMXCAM_initComponent (&OMXCAM_ctx.camera)){
    return OMXCAM_ErrorInitCamera;
  }
  if (useEncoder && OMXCAM_initComponent (&OMXCAM_ctx.image_encode)){
    return OMXCAM_ErrorInitImageEncoder;
  }
  
  if (OMXCAM_loadCameraDrivers ()) return OMXCAM_ErrorInitCamera;
  
  //Configure camera sensor
  OMXCAM_trace ("Configuring '%s' sensor", OMXCAM_ctx.camera.name);
  
  OMX_PARAM_SENSORMODETYPE sensor;
  OMX_INIT_STRUCTURE (sensor);
  sensor.nPortIndex = OMX_ALL;
  OMX_INIT_STRUCTURE (sensor.sFrameSize);
  sensor.sFrameSize.nPortIndex = OMX_ALL;
  if ((error = OMX_GetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamCommonSensorMode, &sensor))){
    OMXCAM_error ("OMX_GetParameter - OMX_IndexParamCommonSensorMode: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorInitCamera;
  }
  sensor.bOneShot = OMX_TRUE;
  //sensor.sFrameSize.nWidth and sensor.sFrameSize.nHeight can be ignored,
  //they are configured with the port definition
  if ((error = OMX_SetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamCommonSensorMode, &sensor))){
    OMXCAM_error ("OMX_SetParameter - OMX_IndexParamCommonSensorMode: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorInitCamera;
  }

  //Change to Idle
  if (changeStillState (OMX_StateIdle, useEncoder)){
    return OMXCAM_ErrorIdle;
  }
  
  //Configure camera port definition
  OMXCAM_trace ("Configuring '%s' port definition", OMXCAM_ctx.camera.name);
  
  OMX_PARAM_PORTDEFINITIONTYPE def;
  OMX_INIT_STRUCTURE (def);
  def.nPortIndex = 72;
  if ((error = OMX_GetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamPortDefinition, &def))){
    OMXCAM_error ("OMX_GetParameter - OMX_IndexParamPortDefinition: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorStill;
  }
  
  def.format.image.nFrameWidth = settings->camera.width;
  def.format.image.nFrameHeight = settings->camera.height;
  def.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
  def.format.image.eColorFormat = colorFormat;
  
  //TODO: stride, sliceHeight? http://www.raspberrypi.org/phpBB3/viewtopic.php?f=28&t=22019
  def.format.image.nStride = stride;
  if ((error = OMX_SetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamPortDefinition, &def))){
    OMXCAM_error ("OMX_SetParameter - OMX_IndexParamPortDefinition: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorBadParameter;
  }
  
  //Configure camera settings
  if (OMXCAM_setCameraSettings (&settings->camera)){
    return OMXCAM_ErrorBadParameter;
  }
  
  if (useEncoder){
    OMXCAM_trace ("Configuring '%s' port definition",
        OMXCAM_ctx.image_encode.name);
    
    OMX_INIT_STRUCTURE (def);
    def.nPortIndex = 341;
    if ((error = OMX_GetParameter (OMXCAM_ctx.image_encode.handle,
        OMX_IndexParamPortDefinition, &def))){
      OMXCAM_error ("OMX_GetParameter - OMX_IndexParamPortDefinition: %s",
          OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorStill;
    }
    def.format.image.nFrameWidth = settings->camera.width;
    def.format.image.nFrameHeight = settings->camera.height;
    def.format.image.eCompressionFormat = OMX_IMAGE_CodingJPEG;
    def.format.image.eColorFormat = OMX_COLOR_FormatUnused;
    if ((error = OMX_SetParameter (OMXCAM_ctx.image_encode.handle,
        OMX_IndexParamPortDefinition, &def))){
      OMXCAM_error ("OMX_SetParameter - OMX_IndexParamPortDefinition: %s",
          OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorBadParameter;
    }
    
    //Configure JPEG settings
    if (OMXCAM_setJpegSettings (&settings->jpeg)){
      return OMXCAM_ErrorBadParameter;
    }
    
    //Setup tunnel: camera (still) -> image_encode
    OMXCAM_trace ("Configuring tunnel '%s' -> '%s'", OMXCAM_ctx.camera.name,
        OMXCAM_ctx.image_encode.name);
    
    if ((error = OMX_SetupTunnel (OMXCAM_ctx.camera.handle, 72,
        OMXCAM_ctx.image_encode.handle, 340))){
      OMXCAM_error ("OMX_SetupTunnel: %s", OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorSetupTunnel;
    }
  }
  
  //Enable the ports
  if (OMXCAM_enablePort (&OMXCAM_ctx.camera, 72)){
    return OMXCAM_ErrorStill;
  }
  if (!useEncoder && OMXCAM_allocateBuffer (&OMXCAM_ctx.camera, 72)){
    return OMXCAM_ErrorStill;
  }
  if (OMXCAM_wait (&OMXCAM_ctx.camera, OMXCAM_EventPortEnable, 0)){
    return OMXCAM_ErrorStill;
  }
  
  if (useEncoder){
    if (OMXCAM_enablePort (&OMXCAM_ctx.image_encode, 340)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.image_encode, OMXCAM_EventPortEnable, 0)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_enablePort (&OMXCAM_ctx.image_encode, 341)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_allocateBuffer (&OMXCAM_ctx.image_encode, 341)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.image_encode, OMXCAM_EventPortEnable, 0)){
      return OMXCAM_ErrorStill;
    }
  }
  
  //Change to Executing
  if (changeStillState (OMX_StateExecuting, useEncoder)){
    return OMXCAM_ErrorExecuting;
  }
  
  //Set camera capture port
  if (OMXCAM_setCapturePort (72)){
    return OMXCAM_ErrorStill;
  }
  
  //Start consuming the buffers
  VCOS_UNSIGNED endFlags = OMXCAM_EventBufferFlag | OMXCAM_EventFillBufferDone;
  VCOS_UNSIGNED retrievedEvents;
  
  while (1){
    //Get the buffer data (a slice of the image)
    if ((error = OMX_FillThisBuffer (fillComponent->handle,
        OMXCAM_ctx.outputBuffer))){
      OMXCAM_error ("OMX_FillThisBuffer: %s",
          OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorStill;
    }
    
    //Wait until it's filled
    if (OMXCAM_wait (fillComponent, OMXCAM_EventFillBufferDone,
        &retrievedEvents)){
      return OMXCAM_ErrorStill;
    }
    
    //Emit the buffer
    if (OMXCAM_ctx.outputBuffer->nFilledLen){
      settings->bufferCallback (OMXCAM_ctx.outputBuffer->pBuffer,
          OMXCAM_ctx.outputBuffer->nFilledLen);
    }
    
    //When it's the end of the stream, an OMX_EventBufferFlag is emitted in all
    //the components in use. Then the FillBufferDone function is called in the
    //last component in the component's chain
    if (retrievedEvents == endFlags){
      //Clear the EOS flags
      if (OMXCAM_wait (&OMXCAM_ctx.camera, OMXCAM_EventBufferFlag, 0)){
        return OMXCAM_ErrorStill;
      }
      if (useEncoder &&
          OMXCAM_wait (&OMXCAM_ctx.image_encode, OMXCAM_EventBufferFlag, 0)){
        return OMXCAM_ErrorStill;
      }
      break;
    }
  }
  
  //Reset camera capture port
  if (OMXCAM_resetCapturePort (72)){
    return OMXCAM_ErrorStill;
  }
  
  //Change to Idle
  if (changeStillState (OMX_StateIdle, useEncoder)){
    return OMXCAM_ErrorIdle;
  }
  
  //Disable the ports
  if (OMXCAM_disablePort (&OMXCAM_ctx.camera, 72)){
    return OMXCAM_ErrorStill;
  }
  if (!useEncoder && OMXCAM_freeBuffer (&OMXCAM_ctx.camera, 72)){
    return OMXCAM_ErrorStill;
  }
  if (OMXCAM_wait (&OMXCAM_ctx.camera, OMXCAM_EventPortDisable, 0)){
    return OMXCAM_ErrorStill;
  }
  
  if (useEncoder){
    if (OMXCAM_disablePort (&OMXCAM_ctx.image_encode, 340)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.image_encode, OMXCAM_EventPortDisable, 0)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_disablePort (&OMXCAM_ctx.image_encode, 341)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_freeBuffer (&OMXCAM_ctx.image_encode, 341)){
      return OMXCAM_ErrorStill;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.image_encode, OMXCAM_EventPortDisable, 0)){
      return OMXCAM_ErrorStill;
    }
  }
  
  //Change to Loaded
  if (changeStillState (OMX_StateLoaded, useEncoder)){
    return OMXCAM_ErrorLoaded;
  }
  
  if (OMXCAM_deinitComponent (&OMXCAM_ctx.camera)){
    return OMXCAM_ErrorDeinitCamera;
  }
  if (useEncoder && OMXCAM_deinitComponent (&OMXCAM_ctx.image_encode)){
    return OMXCAM_ErrorDeinitImageEncoder;
  }
  
  return OMXCAM_deinit ();
}
int main(int argc, char** argv) {
  OMX_ERRORTYPE err = OMX_ErrorNone;
  OMX_BOOL bOmxInitialized = OMX_FALSE;
  OMX_PARAM_PORTDEFINITIONTYPE sOmxPortDefinition;
  OMX_CONFIG_BOOLEANTYPE sOmxCapturing;
  OMX_CONFIG_BOOLEANTYPE sOmxAutoPause;
  OMX_STATETYPE sOmxState;
  OMX_U32 nBufferCount;
  OMX_U32 nBufferSize;
  OMX_U32 nPortIndex;
  OMX_U32 i;
  unsigned int nPreviewTime = 5;/* By default, running for 5 sec for preview */
  unsigned int nCaptureTime = 5;/* By default, running for 5 sec for video capture */
  char *cCaptureFileName = g_DefaultCaptureFileName;
  char *cThumbnailFileName = g_DefaultThumbnailFileName;
  OMX_BOOL bCameraStillImageMode = OMX_FALSE; /* By default, the camera is running in video capture mode */
  OMX_BOOL bCameraAutoPause = OMX_FALSE; /* By default, the camera is not running in autopause mode */
  unsigned int nMaxRunCount = 1;/* By default, running once */
  unsigned int nRunCount = 0;

  /* Parse arguments */
  for ( i = 1; i < argc && argv[i][0] == '-'; i++) {
    switch (argv[i][1]) {
      case 'i':
        bCameraStillImageMode = OMX_TRUE;
        break;

      case 'p':
        bCameraAutoPause = OMX_TRUE;
        break;

      case 't':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "preview_time expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nPreviewTime = (unsigned int)atoi(argv[i]);
        break;

      case 's':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "capture_time expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nCaptureTime = (unsigned int)atoi(argv[i]);
        break;

      case 'c':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "capture_file expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        cCaptureFileName = argv[i];
        break;

      case 'm':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "thumbnail_file expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        cThumbnailFileName = argv[i];
        break;

      case 'n':
        i++;
        if (i>=argc ||argv[i][0] == '-') {
          DEBUG(DEB_LEV_ERR, "run_count expected!\n");
          display_help(argv[0]);
          exit(-1);
        }
        nMaxRunCount = (unsigned int)atoi(argv[i]);
        break;

      case 'h':
        display_help(argv[0]);
        exit(0);
        break;

      default:
        DEBUG(DEB_LEV_ERR, "Unrecognized option -%c!\n", argv[i][1]);
        display_help(argv[0]);
        exit(-1);
      }
   }


  /* Init the Omx core */
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the OMX core\n");
  if ((err = OMX_Init()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
    goto EXIT;
  }
  bOmxInitialized =  OMX_TRUE;

  /* Initialize application private data */
  appPriv = malloc(sizeof(appPrivateType));
  if (appPriv == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate app private data failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  memset(appPriv, 0, sizeof(appPrivateType));

  memset(&sCameraPortBufferList, 0, NUM_CAMERAPORTS*sizeof(OMX_PORTBUFFERCTXT));

  /* Open output file for camera capture and thumbnail port */
  fCapture=fopen(cCaptureFileName, "wb");
  fThumbnail=fopen(cThumbnailFileName, "wb");


  /* Getting camera component handle */
  if ((err = OMX_GetHandle(&appPriv->camerahandle, "OMX.st.v4l.camera_source", appPriv, &camera_source_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting camera component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Getting fbsink component handle */
  if ((err = OMX_GetHandle(&appPriv->colorconvhandle, "OMX.st.video_colorconv.ffmpeg", appPriv, &colorconv_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting color conv component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Getting fbsink component handle */
  if ((err = OMX_GetHandle(&appPriv->fbsinkhandle, "OMX.st.fbdev.fbdev_sink", appPriv, &fbsink_callbacks)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Getting fbsink component handle failed!Exiting...\n");
    goto EXIT;
  }

  /* Setting parameters for camera component */
  if ((err = setCameraParameters(bCameraStillImageMode)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set camera parameters failed! Use default settings...\n");
    /* Do not exit! */
  }

  /* Setting parameters for color converter component */
  if ((err = setColorConvParameters()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set fbsink parameters failed! Use default settings...\n");
    /* Do not exit! */
  }


  /* Setting parameters for fbsink component */
  if ((err = setFbsinkParameters()) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set fbsink parameters failed! Use default settings...\n");
    /* Do not exit! */
  }

  /* Allocate and init semaphores */
  appPriv->cameraSourceEventSem = malloc(sizeof(tsem_t));
  if (appPriv->cameraSourceEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate camera event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->cameraSourceEventSem, 0);

  appPriv->fbsinkEventSem = malloc(sizeof(tsem_t));
  if (appPriv->fbsinkEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate fbsink event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->fbsinkEventSem, 0);

  appPriv->colorconvEventSem = malloc(sizeof(tsem_t));
  if (appPriv->colorconvEventSem == NULL) {
    DEBUG(DEB_LEV_ERR, "Allocate colorconv event semaphore failed!Exiting...\n");
    err = OMX_ErrorInsufficientResources;
    goto EXIT;
  }
  tsem_init(appPriv->colorconvEventSem, 0);

  /* Setup tunnel between camera preview port, color converter and fbsink */
  if ((err = OMX_SetupTunnel(appPriv->camerahandle, OMX_CAMPORT_INDEX_VF, appPriv->colorconvhandle, 0)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Setup tunnel between camera preview port and color converter failed!Exiting...\n");
    goto EXIT;
  }
  if ((err = OMX_SetupTunnel(appPriv->colorconvhandle, 1, appPriv->fbsinkhandle, 0)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Setup tunnel between color conv port and fbsink failed!Exiting...\n");
    goto EXIT;
  }

RUN_AGAIN:

  /* Transition camera component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color Conv Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Loaded-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Loaded-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Allocate port buffers for camera component */
  for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex <= OMX_CAMPORT_INDEX_CP_T; nPortIndex++) {
    setHeader(&sOmxPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    sOmxPortDefinition.nPortIndex = nPortIndex;
    if ((err = OMX_GetParameter(appPriv->camerahandle, OMX_IndexParamPortDefinition, &sOmxPortDefinition)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "OMX_GetParameter for camera on OMX_IndexParamPortDefinition index failed!Exiting...\n");
      goto EXIT;
    }
    nBufferCount = sOmxPortDefinition.nBufferCountActual;
    nBufferSize = sOmxPortDefinition.nBufferSize;
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Camera port[%ld] needs %ld buffers each of which is %ld bytes\n", nPortIndex, nBufferCount, nBufferSize);

    for (i = 0; i < nBufferCount; i++) {
      if ((err = OMX_AllocateBuffer(appPriv->camerahandle, &sCameraPortBufferList[nPortIndex].pBufHeaderList[i], nPortIndex, NULL, nBufferSize)) != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "Allocate port buffer for camera failed!Exiting...\n");
        goto EXIT;
      }
      sCameraPortBufferList[nPortIndex].nBufferCountActual++;
    }
  }

  /* Wait camera (Loaded-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait fbsink (Loaded-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Loaded-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);



  /* Transition camera component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Colorconv Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Idle-->Exec) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Idle-->Exec) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Exec) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  fprintf(stdout, "Start preview, for %d sec...\n", nPreviewTime);
  sleep(nPreviewTime);

  /* Fill buffers to camera capture port */
  for (i = 0; i < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].nBufferCountActual; i++) {
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nFilledLen = 0;
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]->nOffset = 0;
    if ((err = OMX_FillThisBuffer(appPriv->camerahandle, sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i])) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Fill buffer to camera capture port failed!Exiting...\n");
      goto EXIT;
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n", __func__, i, (OMX_U32)sCameraPortBufferList[OMX_CAMPORT_INDEX_CP].pBufHeaderList[i]);
  }

  /* Fill buffers to camera thumbnail port */
  for (i = 0; i < sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].nBufferCountActual; i++) {
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]->nFilledLen = 0;
    sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]->nOffset = 0;
    if ((err = OMX_FillThisBuffer(appPriv->camerahandle, sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i])) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Fill buffer to camera capture port failed!Exiting...\n");
      goto EXIT;
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Fill buffer[%ld] (0x%lX) to camera capture port\n", __func__, i, (OMX_U32)sCameraPortBufferList[OMX_CAMPORT_INDEX_CP_T].pBufHeaderList[i]);
  }

  /* Set up autopause mode */
  setHeader(&sOmxAutoPause, sizeof(OMX_CONFIG_BOOLEANTYPE));
  sOmxAutoPause.bEnabled = bCameraAutoPause;
  if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexAutoPauseAfterCapture, &sOmxAutoPause)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Set autopause mode failed!Use default settings...\n");
    /* Do not exit */
  }

  /*  Start capturing */
  setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
  sOmxCapturing.bEnabled = OMX_TRUE;
  if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexConfigCapturing, &sOmxCapturing)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Start capturing failed!Exiting...\n");
    goto EXIT;
  }

  fprintf(stdout, "Start capturing, for %d sec...\n", nCaptureTime);
  sleep(nCaptureTime);

  /*  Stop capturing */
  if (!bCameraStillImageMode) {
    setHeader(&sOmxCapturing, sizeof(OMX_CONFIG_BOOLEANTYPE));
    sOmxCapturing.bEnabled = OMX_FALSE;
    if ((err = OMX_SetConfig(appPriv->camerahandle, OMX_IndexConfigCapturing, &sOmxCapturing)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Stop capturing failed!Exiting...\n");
      goto EXIT;
    }
    fprintf(stdout, "Stop capturing...\n");
  }

  /* If in autopause mode, stay for a while before exit */
  if (bCameraAutoPause) {
    fprintf(stdout, "Now the camera is in autopause mode, wait for %d sec before out of this mode...\n", 5);
    sleep(5);
    /* Stop autopause mode */
    if ((err = OMX_GetState(appPriv->camerahandle,&sOmxState)) != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Get camera state failed!Exiting...\n");
      goto EXIT;
    }
    if (sOmxState == OMX_StatePause) {
      if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet,
                                                      OMX_StateExecuting, 0 )) != OMX_ErrorNone ) {
        DEBUG(DEB_LEV_ERR, "Pause-->Exec failed!Exiting...\n");
        goto EXIT;
      }
      /* Wait camera (Pause-->Exec) to complete */
      tsem_down(appPriv->cameraSourceEventSem);
      fprintf(stdout, "Now the camera is out of autopause mode, wait for %d sec before exit...\n", 5);
      sleep(5);
    }
    else {
      DEBUG(DEB_LEV_ERR, "The camera is not in Pause state in autopause mode, ignore...\n");
    }
  }

  /* Transition camera component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition colorconv component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Exec-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Exec-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  /* Transition camera component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Colorconv Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Exec */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Exec failed!Exiting...\n");
    goto EXIT;
  }

  /* Wait camera (Idle-->Exec) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Exec) to complete */
  tsem_down(appPriv->fbsinkEventSem);

  fprintf(stdout, "Continue to preview, for %d sec...\n", nPreviewTime);
  sleep(nPreviewTime);

  /* Transition camera component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Exec-->Idle */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }


  /* Wait camera (Exec-->Idle) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Exec-->Idle) to complete */
  tsem_down(appPriv->fbsinkEventSem);


  /* Transition camera component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->camerahandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Camera Idle-->Loaded failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition color conv component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->colorconvhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Color conv Exec-->Idle failed!Exiting...\n");
    goto EXIT;
  }

  /* Transition fbsink component Idle-->Loaded */
  if ((err = OMX_SendCommand(appPriv->fbsinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Fbsink Idle-->Loaded failed!Exiting...\n");
    goto EXIT;
  }

  /* Free bufers for each non-tunneled port of camera component */
  for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex <= OMX_CAMPORT_INDEX_CP_T; nPortIndex++) {
    for (i = 0; i < sCameraPortBufferList[nPortIndex].nBufferCountActual; i++) {
      if (sCameraPortBufferList[nPortIndex].pBufHeaderList[i] != NULL) {
        OMX_FreeBuffer(appPriv->camerahandle, nPortIndex, sCameraPortBufferList[nPortIndex].pBufHeaderList[i]);
      }
    }
    sCameraPortBufferList[nPortIndex].nBufferCountActual = 0;
  }

  /* Wait camera (Idle-->Loaded) to complete */
  tsem_down(appPriv->cameraSourceEventSem);
  /* Wait color conv (Exec-->Idle) to complete */
  tsem_down(appPriv->colorconvEventSem);
  /* Wait fbsink (Idle-->Loaded) to complete */
  tsem_down(appPriv->fbsinkEventSem);

  nRunCount++;
  if (nRunCount < nMaxRunCount) {
    goto RUN_AGAIN;
  }

  fprintf(stdout, "The captured videos are saved in file \"%s\"\n", cCaptureFileName);
  fprintf(stdout, "The thumbnail image is saved in file \"%s\"\n", cThumbnailFileName);

EXIT:
  if (fCapture != NULL) {
    fclose(fCapture);
  }
  if (fThumbnail != NULL) {
    fclose(fThumbnail);
  }

  /* Free app private data */
  if (appPriv != NULL) {
    /* Free semaphores */
    if (appPriv->cameraSourceEventSem != NULL) {
      tsem_deinit(appPriv->cameraSourceEventSem);
      free(appPriv->cameraSourceEventSem);
    }

    if (appPriv->colorconvEventSem != NULL) {
      tsem_deinit(appPriv->colorconvEventSem);
      free(appPriv->colorconvEventSem);
    }

    if (appPriv->fbsinkEventSem != NULL) {
      tsem_deinit(appPriv->fbsinkEventSem);
      free(appPriv->fbsinkEventSem);
    }

    /* Free camera component handle */
    if (appPriv->camerahandle != NULL) {
      OMX_FreeHandle(appPriv->camerahandle);
    }
    /* Free Color conv component handle */
    if (appPriv->colorconvhandle != NULL) {
      OMX_FreeHandle(appPriv->colorconvhandle);
    }

    /* Free fbsink component handle */
    if (appPriv->fbsinkhandle != NULL) {
      OMX_FreeHandle(appPriv->fbsinkhandle);
    }

    free(appPriv);
  }

  /* Deinit the Omx core */
  if (bOmxInitialized) {
    OMX_Deinit();
  }

  return (int) err;
}
예제 #17
0
OMX_ERRORTYPE Tunnel::Deestablish(string caller)
{
    string debugString = sourceComponent->getName() + " : " + destinationComponent->getName();
    ofLogVerbose(__func__)<< " caller: " << caller << " components: " << debugString;
    if (!isEstablished)
    {
        return OMX_ErrorNone;
    }
    
    if(!sourceComponent || !destinationComponent)
    {
        return OMX_ErrorUndefined;
    }
    
    lock();
    OMX_ERRORTYPE error = OMX_ErrorNone;
    if(havePortSettingsChanged)
    {
        error = sourceComponent->waitForEvent(OMX_EventPortSettingsChanged);
        OMX_TRACE(error);
    }

    
    bool didTearDownTunnel = sourceComponent->tunnelToNull(sourcePort);
    didTearDownTunnel = destinationComponent->tunnelToNull(destinationPort);


    
#if 0 
    error = sourceComponent->disableAllPorts();
    OMX_TRACE(error, debugString);
    
    error = destinationComponent->disableAllPorts();
    OMX_TRACE(error, debugString);

   
    error = sourceComponent->disablePort(sourcePort);
    OMX_TRACE(error);
    
    error = destinationComponent->disablePort(destinationPort);
    OMX_TRACE(error, debugString);
      
    
    sourceComponent->setToStateLoaded();
    destinationComponent->setToStateLoaded();
    

    
    error = OMX_SetupTunnel(destinationComponent->getHandle(), destinationPort, NULL, 0);
    OMX_TRACE(error, debugString);
    if(error == OMX_ErrorNone)
    {
        ofLogVerbose(__func__) << destinationComponent->getName() << " TUNNELED TO NULL SUCCESS";
    }else
    {
         ofLogVerbose(__func__) << destinationComponent->getName() << " TUNNELED TO NULL FAIL";
        if(error == OMX_ErrorIncorrectStateOperation)
        {
            ofLogVerbose(__func__) << GetOMXStateString(destinationComponent->getState());

        }
    }
    
    error = OMX_SetupTunnel(sourceComponent->getHandle(), sourcePort, NULL, 0);
    OMX_TRACE(error, debugString);
    if(error == OMX_ErrorNone)
    {
        ofLogVerbose(__func__) << sourceComponent->getName() << " TUNNELED TO NULL SUCCESS";
    }else
    {
        ofLogVerbose(__func__) << sourceComponent->getName() << " TUNNELED TO NULL FAIL";
        if(error == OMX_ErrorIncorrectStateOperation)
        {
            ofLogVerbose(__func__) << GetOMXStateString(sourceComponent->getState());
            
        }
    }
    
 #endif    
    

    
    unlock();
    isEstablished = false;
    return error;
}
예제 #18
0
OMX_ERRORTYPE Tunnel::Establish(bool portSettingsChanged)
{
    lock();
    
    OMX_ERRORTYPE error = OMX_ErrorNone;
    OMX_PARAM_U32TYPE param;
    OMX_INIT_STRUCTURE(param);
    if(!sourceComponent || !destinationComponent || !sourceComponent->getHandle() || !destinationComponent->getHandle())
    {
        unlock();
        return OMX_ErrorUndefined;
    }
    
    error = sourceComponent->setState(OMX_StateIdle);
    OMX_TRACE(error);
    if(error != OMX_ErrorNone)
    {
        unlock();
        return error;
    }
#ifdef DEBUG_TUNNELS
    ofLogVerbose(__func__) << sourceComponent->getName() << " TUNNELING TO " << destinationComponent->getName();
    ofLogVerbose(__func__) << "portSettingsChanged: " << portSettingsChanged;
#endif
    if(portSettingsChanged)
    {
        error = sourceComponent->waitForEvent(OMX_EventPortSettingsChanged);
        OMX_TRACE(error);
        if(error != OMX_ErrorNone)
        {
            unlock();
            return error;
        }
    }
    
    error = sourceComponent->disablePort(sourcePort);
    OMX_TRACE(error);
    
    
    error = destinationComponent->disablePort(destinationPort);
    OMX_TRACE(error);
    
    error = OMX_SetupTunnel(sourceComponent->getHandle(), sourcePort, destinationComponent->getHandle(), destinationPort);
    OMX_TRACE(error);
    if(error != OMX_ErrorNone)
    {
        unlock();
        return error;
    }
    else
    {
        isEstablished =true;
    }
    
    error = sourceComponent->enablePort(sourcePort);
    OMX_TRACE(error);
    if(error != OMX_ErrorNone)
    {
        unlock();
        return error;
    }
    
    error = destinationComponent->enablePort(destinationPort);
    OMX_TRACE(error);
    if(error != OMX_ErrorNone)
    {
        unlock();
        return error;
    }
    
    if(destinationComponent->getState() == OMX_StateLoaded)
    {
        //important to wait for audio
        error = destinationComponent->waitForCommand(OMX_CommandPortEnable, destinationPort);
        OMX_TRACE(error);
        if(error != OMX_ErrorNone)
        {
            unlock();
            return error;
        }
        error = destinationComponent->setState(OMX_StateIdle);
        OMX_TRACE(error);
        if(error != OMX_ErrorNone)
        {
            unlock();
            return error;
        }
    }
    
    error = sourceComponent->waitForCommand(OMX_CommandPortEnable, sourcePort);
    if(error != OMX_ErrorNone)
    {
        unlock();
        return error;
    }
    
    havePortSettingsChanged = portSettingsChanged;
    
    unlock();
    
    
    return error;
}
예제 #19
0
void omx_teardown_pipeline(struct omx_pipeline_t* pipe)
{
   OMX_BUFFERHEADERTYPE *buf;
   int i=1;

   DEBUGF("[vcodec] omx_teardown pipeline:\n");
   DEBUGF("pipe->video_decode.port_settings_changed = %d\n",pipe->video_decode.port_settings_changed);
   DEBUGF("pipe->image_fx.port_settings_changed = %d\n",pipe->image_fx.port_settings_changed);
   DEBUGF("pipe->video_scheduler.port_settings_changed = %d\n",pipe->video_scheduler.port_settings_changed);
   //dumpport(pipe->video_decode.h,130);

#if 0
   /* Indicate end of video stream */
   buf = get_next_buffer(&pipe->video_decode);

   buf->nFilledLen = 0;
   buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;
   
   OERR(OMX_EmptyThisBuffer(pipe->video_decode.h, buf));

   /* NOTE: Three events are sent after the previous command:

      [EVENT] Got an event of type 4 on video_decode 0x426a10 (d1: 83, d2 1)
      [EVENT] Got an event of type 4 on video_scheduler 0x430d10 (d1: b, d2 1)
      [EVENT] Got an event of type 4 on video_render 0x430b30 (d1: 5a, d2 1)  5a = port (90) 1 = OMX_BUFFERFLAG_EOS
   */

#endif

#if 0
   DEBUGF("[vcodec] omx_teardown pipeline 2\n");
   /* Wait for video_decode to shutdown */
   pthread_mutex_lock(&pipe->video_decode.eos_mutex);
   while (!pipe->video_decode.eos)
     pthread_cond_wait(&pipe->video_decode.eos_cv,&pipe->video_decode.eos_mutex);
   pthread_mutex_unlock(&pipe->video_decode.eos_mutex);
#endif
         
   DEBUGF("[vcodec] omx_teardown pipeline 1\n");

   /* Transition all components to Idle, if they have been initialised */
   omx_send_command_and_wait(&pipe->video_decode, OMX_CommandStateSet, OMX_StateIdle, NULL); 
   omx_send_command_and_wait(&pipe->clock, OMX_CommandStateSet, OMX_StateIdle, NULL);
   DEBUGF("pipe->do_deinterlace=%d, pipe->image_fx=%d\n",pipe->do_deinterlace,(int)pipe->image_fx.h);
   if (pipe->video_decode.port_settings_changed == 2) {
      if (pipe->do_deinterlace) { 
        omx_send_command_and_wait(&pipe->image_fx, OMX_CommandStateSet, OMX_StateIdle, NULL); 
      } else {
        omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandStateSet, OMX_StateIdle, NULL); 
      }
   }
   if (pipe->image_fx.port_settings_changed == 2) {
     omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandStateSet, OMX_StateIdle, NULL);
   }
   if (pipe->video_scheduler.port_settings_changed == 2) {
     omx_send_command_and_wait(&pipe->video_render, OMX_CommandStateSet, OMX_StateIdle, NULL);
   }
   omx_send_command_and_wait(&pipe->audio_render, OMX_CommandStateSet, OMX_StateIdle, NULL);

#if 0
   DEBUGF("[vcodec] omx_teardown pipeline 2\n");
   /* Wait for video_render to shutdown */
   pthread_mutex_lock(&pipe->video_render.eos_mutex);
   while (!pipe->video_render.eos)
     pthread_cond_wait(&pipe->video_render.eos_cv,&pipe->video_render.eos_mutex);
   pthread_mutex_unlock(&pipe->video_render.eos_mutex);
#endif

/* 
  Pipeline is as follows:

[video data] -> 130 video_decode 131 -> 190 image_fx 191 -> 10 video_scheduler 11 -> 90 video_render
                                                clock 81 -> 12 video_scheduler
                                                clock 80 -> 101 audio_render
                                            [audio data] -> 100 audio_render
*/

   /* Flush entrances to pipeline */
   omx_send_command_and_wait(&pipe->video_decode,OMX_CommandFlush,130,NULL);
   omx_send_command_and_wait(&pipe->audio_render,OMX_CommandFlush,100,NULL);

   /* Flush all tunnels */
   DEBUGF("[vcodec] omx_teardown pipeline 3\n");
   if (pipe->do_deinterlace) {
     omx_flush_tunnel(&pipe->video_decode, 131, &pipe->image_fx, 190);
     omx_flush_tunnel(&pipe->image_fx, 191, &pipe->video_scheduler, 10);
   } else {
     omx_flush_tunnel(&pipe->video_decode, 131, &pipe->video_scheduler, 10);
   }
   DEBUGF("[vcodec] omx_teardown pipeline 4\n");
   omx_flush_tunnel(&pipe->video_scheduler, 11, &pipe->video_render, 90);
   omx_flush_tunnel(&pipe->clock, 81, &pipe->video_scheduler, 12);

   DEBUGF("[vcodec] omx_teardown pipeline 2b\n");

   omx_send_command_and_wait(&pipe->video_scheduler,OMX_CommandFlush,10,NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 5\n");

   omx_flush_tunnel(&pipe->clock, 80, &pipe->audio_render, 101);

   /* Disable audio_render input port and buffers */
   omx_send_command_and_wait0(&pipe->audio_render, OMX_CommandPortDisable, 100, NULL);
   omx_free_buffers(&pipe->audio_render, 100);
   omx_send_command_and_wait1(&pipe->audio_render, OMX_CommandPortDisable, 100, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 9\n");

   /* Scheduler -> render tunnel */
   if (pipe->video_scheduler.port_settings_changed == 2) {
     omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandPortDisable, 11, NULL);
     omx_send_command_and_wait(&pipe->video_render, OMX_CommandPortDisable, 90, NULL);

     omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandPortDisable, 10, NULL);
   }

   if ((pipe->image_fx.port_settings_changed == 2) && (pipe->do_deinterlace)) {
     omx_send_command_and_wait(&pipe->image_fx, OMX_CommandPortDisable, 190, NULL);
     omx_send_command_and_wait(&pipe->image_fx, OMX_CommandPortDisable, 191, NULL);
   }

   DEBUGF("[vcodec] omx_teardown pipeline 8a\n");

   //dumpport(pipe->video_scheduler.h,10);

   /* Teardown tunnels */
/* 
  Pipeline is as follows:

[video data] -> 130 video_decode 131 -> 190 image_fx 191 -> 10 video_scheduler 11 -> 90 video_render
                                                clock 81 -> 12 video_scheduler
                                                clock 80 -> 101 audio_render
                                            [audio data] -> 100 audio_render
*/
   //dumpport(pipe->video_decode.h,131);
   OERR(OMX_SetupTunnel(pipe->video_scheduler.h, 10, NULL, 0));

   DEBUGF("[vcodec] omx_teardown pipeline 10\n");

   /* NOTE: The clock disable doesn't complete until after the video scheduler port is 
      disabled (but it completes before the video scheduler port disabling completes). */
   OERR(OMX_SendCommand(pipe->clock.h, OMX_CommandPortDisable, 80, NULL));
   omx_send_command_and_wait(&pipe->audio_render, OMX_CommandPortDisable, 101, NULL);
   OERR(OMX_SendCommand(pipe->clock.h, OMX_CommandPortDisable, 81, NULL));
   omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandPortDisable, 12, NULL);

   DEBUGF("[vcodec] omx_teardown pipeline 12b\n");

   if (pipe->do_deinterlace) {
     OERR(OMX_SetupTunnel(pipe->image_fx.h, 190, NULL, 0));
     OERR(OMX_SetupTunnel(pipe->image_fx.h, 191, NULL, 0));
   }

   DEBUGF("[vcodec] omx_teardown pipeline 13\n");

   OERR(OMX_SetupTunnel(pipe->video_scheduler.h, 11, NULL, 0));
   OERR(OMX_SetupTunnel(pipe->video_render.h, 90, NULL, 0));

   OERR(OMX_SetupTunnel(pipe->clock.h, 81, NULL, 0));
   OERR(OMX_SetupTunnel(pipe->video_scheduler.h, 12, NULL, 0));

   DEBUGF("[vcodec] omx_teardown pipeline 13b\n");

   OERR(OMX_SetupTunnel(pipe->clock.h, 80, NULL, 0));
   OERR(OMX_SetupTunnel(pipe->audio_render.h, 101, NULL, 0));

   DEBUGF("[vcodec] omx_teardown pipeline 8b\n");


/* 
  Pipeline is as follows:

[video data] -> 130 video_decode 131 -> 190 image_fx 191 -> 10 video_scheduler 11 -> 90 video_render
                                                clock 81 -> 12 video_scheduler
                                                clock 80 -> 101 audio_render
                                            [audio data] -> 100 audio_render
*/

   omx_show_state(&pipe->video_decode,130,131,0);
   dumpport(pipe->video_decode.h,131);
   omx_show_state(&pipe->video_scheduler,10,11,12);
   if (pipe->do_deinterlace) { omx_show_state(&pipe->image_fx,190,191,0); }
   omx_show_state(&pipe->video_render,90,0,0);
   omx_show_state(&pipe->audio_render,100,101,0);
   omx_show_state(&pipe->clock,80,81,0);

   if (pipe->video_decode.port_settings_changed == 2) {
     //dumpport(pipe->video_decode.h,131);
     omx_send_command_and_wait(&pipe->video_decode, OMX_CommandPortDisable, 131, NULL);
   }

   DEBUGF("[vcodec] omx_teardown pipeline 11\n");

   /* Disable video_decode input port and buffers */
   //dumpport(pipe->video_decode.h,130);
   omx_send_command_and_wait0(&pipe->video_decode, OMX_CommandPortDisable, 130, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 6\n");
   omx_free_buffers(&pipe->video_decode, 130);
   DEBUGF("[vcodec] omx_teardown pipeline 7\n");
   //omx_send_command_and_wait1(&pipe->video_decode, OMX_CommandPortDisable, 130, NULL);

   //dumpport(pipe->video_decode.h,130);
   if (is_port_enabled(pipe->video_decode.h, 130)) {
     fprintf(stderr,"Unexpected error video_decode port 130 is not disabled\n");
     exit(1);
   }

   DEBUGF("[vcodec] omx_teardown pipeline 12\n");

   OERR(OMX_SetupTunnel(pipe->video_decode.h, 131, NULL, 0));

   DEBUGF("[vcodec] omx_teardown pipeline 15\n");

   omx_show_state(&pipe->video_decode,130,131,0);

   /* Transition all components to Loaded */
   DEBUGF("[vcodec] omx_teardown pipeline 15a\n");
   omx_send_command_and_wait(&pipe->video_decode, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 15b\n");
   omx_send_command_and_wait(&pipe->video_scheduler, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 15c\n");
   if (((pipe->video_decode.port_settings_changed == 2) && (pipe->do_deinterlace)) || (pipe->image_fx.port_settings_changed == 2)) {
     omx_send_command_and_wait(&pipe->video_render, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   }
   DEBUGF("[vcodec] omx_teardown pipeline 15d\n");
   omx_send_command_and_wait(&pipe->audio_render, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 15e\n");
   omx_send_command_and_wait(&pipe->clock, OMX_CommandStateSet, OMX_StateLoaded, NULL);
   DEBUGF("[vcodec] omx_teardown pipeline 15f\n");
   if (pipe->do_deinterlace) { omx_send_command_and_wait(&pipe->image_fx, OMX_CommandStateSet, OMX_StateLoaded, NULL); }

   DEBUGF("[vcodec] omx_teardown pipeline 16\n");
   /* Finally free the component handles */
   OERR(OMX_FreeHandle(pipe->video_decode.h));
   OERR(OMX_FreeHandle(pipe->video_scheduler.h));
   OERR(OMX_FreeHandle(pipe->video_render.h));
   OERR(OMX_FreeHandle(pipe->audio_render.h));
   OERR(OMX_FreeHandle(pipe->clock.h));
   if (pipe->do_deinterlace) { OERR(OMX_FreeHandle(pipe->image_fx.h)); }
   DEBUGF("[vcodec] omx_teardown pipeline 17\n");
}
예제 #20
0
static OMXCAM_ERROR initOMX (OMXCAM_VIDEO_SETTINGS* settings){
  OMXCAM_trace ("Initializing video");
  
  OMX_COLOR_FORMATTYPE colorFormat;
  OMX_U32 stride;
  OMXCAM_COMPONENT* fillComponent;
  OMX_ERRORTYPE error;
  
  //Stride is byte-per-pixel*width
  //See mmal/util/mmal_util.c, mmal_encoding_width_to_stride()
  
  switch (settings->format){
    case OMXCAM_FormatRGB888:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_Format24bitRGB888;
      stride = settings->camera.width*3;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatRGBA8888:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_Format32bitABGR8888;
      stride = settings->camera.width*4;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatYUV420:
      OMXCAM_ctx.camera.bufferCallback = settings->bufferCallback;
      useEncoder = 0;
      colorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
      stride = settings->camera.width;
      fillComponent = &OMXCAM_ctx.camera;
      break;
    case OMXCAM_FormatH264:
      OMXCAM_ctx.video_encode.bufferCallback = settings->bufferCallback;
      useEncoder = 1;
      colorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
      stride = settings->camera.width;
      fillComponent = &OMXCAM_ctx.video_encode;
      break;
    default:
      return OMXCAM_ErrorFormat;
  }
  
  threadArg.bufferCallback = settings->bufferCallback;
  threadArg.fillComponent = fillComponent;
  
  if (OMXCAM_initComponent (&OMXCAM_ctx.camera)){
    return OMXCAM_ErrorInitCamera;
  }
  if (OMXCAM_initComponent (&OMXCAM_ctx.null_sink)){
    return OMXCAM_ErrorInitNullSink;
  }
  if (useEncoder && OMXCAM_initComponent (&OMXCAM_ctx.video_encode)){
    return OMXCAM_ErrorInitVideoEncoder;
  }
  
  if (OMXCAM_loadCameraDrivers ()){
    return OMXCAM_ErrorInitCamera;
  }
  
  //Configure camera port definition
  OMXCAM_trace ("Configuring '%s' port definition", OMXCAM_ctx.camera.name);
  
  OMX_PARAM_PORTDEFINITIONTYPE portDefinition;
  OMX_INIT_STRUCTURE (portDefinition);
  portDefinition.nPortIndex = 71;
  if ((error = OMX_GetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamPortDefinition, &portDefinition))){
    OMXCAM_error ("OMX_GetParameter - OMX_IndexParamPortDefinition: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorVideo;
  }
  
  portDefinition.format.video.nFrameWidth = settings->camera.width;
  portDefinition.format.video.nFrameHeight = settings->camera.height;
  portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
  portDefinition.format.video.eColorFormat = colorFormat;
  portDefinition.format.video.xFramerate = settings->camera.framerate << 16;
  
  //TODO: stride, sliceHeight? http://www.raspberrypi.org/phpBB3/viewtopic.php?f=28&t=22019
  portDefinition.format.video.nStride = stride;
  if ((error = OMX_SetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamPortDefinition, &portDefinition))){
    OMXCAM_error ("OMX_SetParameter - OMX_IndexParamPortDefinition: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorBadParameter;
  }
  
  //The preview port must be configured with the same settings as the video port
  portDefinition.nPortIndex = 70;
  if ((error = OMX_SetParameter (OMXCAM_ctx.camera.handle,
      OMX_IndexParamPortDefinition, &portDefinition))){
    OMXCAM_error ("OMX_SetParameter - OMX_IndexParamPortDefinition: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorBadParameter;
  }
  
  //The framerate must be configured (again) with its own structure in the video
  //and preview ports
  OMXCAM_trace ("Configuring %s framerate", OMXCAM_ctx.camera.name);
  
  OMX_CONFIG_FRAMERATETYPE framerate;
  OMX_INIT_STRUCTURE (framerate);
  framerate.nPortIndex = 71;
  framerate.xEncodeFramerate = portDefinition.format.video.xFramerate;
  if ((error = OMX_SetConfig (OMXCAM_ctx.camera.handle,
      OMX_IndexConfigVideoFramerate, &framerate))){
    OMXCAM_error ("OMX_SetConfig - OMX_IndexConfigVideoFramerate: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorBadParameter;
  }
  
  //Preview port
  framerate.nPortIndex = 70;
  if ((error = OMX_SetConfig (OMXCAM_ctx.camera.handle,
      OMX_IndexConfigVideoFramerate, &framerate))){
    OMXCAM_error ("OMX_SetConfig - OMX_IndexConfigVideoFramerate: %s",
        OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorBadParameter;
  }
  
  //Configure camera settings
  if (OMXCAM_setCameraSettings (&settings->camera)){
    return OMXCAM_ErrorBadParameter;
  }
  
  if (useEncoder){
    OMXCAM_trace ("Configuring '%s' port definition",
        OMXCAM_ctx.video_encode.name);
    
    OMX_INIT_STRUCTURE (portDefinition);
    portDefinition.nPortIndex = 201;
    if ((error = OMX_GetParameter (OMXCAM_ctx.video_encode.handle,
        OMX_IndexParamPortDefinition, &portDefinition))){
      OMXCAM_error ("OMX_GetParameter - OMX_IndexParamPortDefinition: %s",
          OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorStill;
    }
    
    portDefinition.format.video.nFrameWidth = settings->camera.width;
    portDefinition.format.video.nFrameHeight = settings->camera.height;
    portDefinition.format.video.xFramerate = settings->camera.framerate << 16;
    portDefinition.format.video.nStride = stride;
    
    //Despite being configured later, these two fields need to be set
    portDefinition.format.video.nBitrate = settings->h264.bitrate;
    portDefinition.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
    
    if ((error = OMX_SetParameter (OMXCAM_ctx.video_encode.handle,
        OMX_IndexParamPortDefinition, &portDefinition))){
      OMXCAM_error ("OMX_SetParameter - OMX_IndexParamPortDefinition: %s",
          OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorBadParameter;
    }
    
    //Configure H264 settings
    if (OMXCAM_setH264Settings (&settings->h264)){
      return OMXCAM_ErrorBadParameter;
    }
    
    //Setup tunnel: camera (video) -> video_encode
    OMXCAM_trace ("Configuring tunnel '%s' -> '%s'", OMXCAM_ctx.camera.name,
        OMXCAM_ctx.video_encode.name);
    
    if ((error = OMX_SetupTunnel (OMXCAM_ctx.camera.handle, 71,
        OMXCAM_ctx.video_encode.handle, 200))){
      OMXCAM_error ("OMX_SetupTunnel: %s", OMXCAM_dump_OMX_ERRORTYPE (error));
      return OMXCAM_ErrorSetupTunnel;
    }
  }
  
  //Setup tunnel: camera (preview) -> null_sink
  OMXCAM_trace ("Configuring tunnel '%s' -> '%s'", OMXCAM_ctx.camera.name,
      OMXCAM_ctx.null_sink.name);
  
  if ((error = OMX_SetupTunnel (OMXCAM_ctx.camera.handle, 70,
      OMXCAM_ctx.null_sink.handle, 240))){
    OMXCAM_error ("OMX_SetupTunnel: %s", OMXCAM_dump_OMX_ERRORTYPE (error));
    return OMXCAM_ErrorSetupTunnel;
  }
  
  //Change to Idle
  if (changeVideoState (OMX_StateIdle, useEncoder)){
    return OMXCAM_ErrorIdle;
  }
  
  //Enable the ports
  if (OMXCAM_enablePort (&OMXCAM_ctx.camera, 71)){
    return OMXCAM_ErrorVideo;
  }
  if (!useEncoder && OMXCAM_allocateBuffer (&OMXCAM_ctx.camera, 71)){
    return OMXCAM_ErrorVideo;
  }
  if (OMXCAM_wait (&OMXCAM_ctx.camera, OMXCAM_EventPortEnable, 0)){
    return OMXCAM_ErrorVideo;
  }
  if (OMXCAM_enablePort (&OMXCAM_ctx.camera, 70)){
    return OMXCAM_ErrorVideo;
  }
  if (OMXCAM_wait (&OMXCAM_ctx.camera, OMXCAM_EventPortEnable, 0)){
    return OMXCAM_ErrorVideo;
  }
  if (OMXCAM_enablePort (&OMXCAM_ctx.null_sink, 240)){
    return OMXCAM_ErrorVideo;
  }
  if (OMXCAM_wait (&OMXCAM_ctx.null_sink, OMXCAM_EventPortEnable, 0)){
    return OMXCAM_ErrorVideo;
  }
  
  if (useEncoder){
    if (OMXCAM_enablePort (&OMXCAM_ctx.video_encode, 200)){
      return OMXCAM_ErrorVideo;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.video_encode, OMXCAM_EventPortEnable, 0)){
      return OMXCAM_ErrorVideo;
    }
    if (OMXCAM_enablePort (&OMXCAM_ctx.video_encode, 201)){
      return OMXCAM_ErrorVideo;
    }
    if (OMXCAM_allocateBuffer (&OMXCAM_ctx.video_encode, 201)){
      return OMXCAM_ErrorVideo;
    }
    if (OMXCAM_wait (&OMXCAM_ctx.video_encode, OMXCAM_EventPortEnable, 0)){
      return OMXCAM_ErrorVideo;
    }
  }
  
  //Change to Executing
  if (changeVideoState (OMX_StateExecuting, useEncoder)){
    return OMXCAM_ErrorExecuting;
  }
  
  //Set camera capture port
  if (OMXCAM_setCapturePort (71)){
    return OMXCAM_ErrorVideo;
  }
  
  return OMXCAM_ErrorNone;
}
static void handle_msg(int fd, struct msg* m)
{
    switch (m->type) {
    case MSG_GET_HANDLE: {
        struct comp* c = (struct comp*) malloc(sizeof(struct comp));
        fprintf(stderr, "ILSRV: GetHandle '%s'\n", m->cmd.get_handle.name);
        m->result = OMX_GetHandle(&c->real_handle, m->cmd.get_handle.name, c, &callbacks);
        m->cmd.get_handle.out_srv_handle = (int) c;
        c->client_handle = m->cmd.get_handle.in_client_handle;
        c->client_fd     = fd;
        c->state         = OMX_StateLoaded;
        strncpy(c->name, m->cmd.get_handle.name, sizeof(c->name));
        c->name[sizeof(c->name)-1]=0;
        add_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] --> %s%s\n", c->real_handle, last_part(c->name), m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_SET_PARAM:{
        struct comp* c = (struct comp*) m->cmd.param.srv_handle;
        verify_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] SetParam %s\n", c->real_handle, last_part(c->name), adm_log_index2str(m->cmd.param.index));
        m->result = OMX_SetParameter(c->real_handle, (OMX_INDEXTYPE) m->cmd.param.index, m->cmd.param.buf); // TODO: Protect
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }
    case MSG_GET_PARAM:{
        struct comp* c = (struct comp*) m->cmd.param.srv_handle;
        verify_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] GetParam %s\n", c->real_handle, last_part(c->name), adm_log_index2str(m->cmd.param.index));
        m->result = OMX_GetParameter(c->real_handle, (OMX_INDEXTYPE)m->cmd.param.index, m->cmd.param.buf); // TODO: Protect
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_GET_CONFIG:{
        struct comp* c = (struct comp*) m->cmd.param.srv_handle;
        verify_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] GetConfig %s\n", c->real_handle, last_part(c->name), adm_log_index2str(m->cmd.param.index));
        m->result = OMX_GetConfig(c->real_handle, (OMX_INDEXTYPE)m->cmd.param.index, m->cmd.param.buf); // TODO: Protect
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_SET_CONFIG: {
        struct comp* c = (struct comp*) m->cmd.param.srv_handle;
        verify_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] SetConfig %s\n", c->real_handle, last_part(c->name), adm_log_index2str(m->cmd.param.index));
        m->result = OMX_SetConfig(c->real_handle, (OMX_INDEXTYPE)m->cmd.param.index, m->cmd.param.buf); // TODO: Protect
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_FREE_HANDLE: {
        struct comp* c = (struct comp*) m->cmd.free_handle.srv_handle;
        verify_component(c);
        if (c->state != OMX_StateLoaded) {
            fprintf(stderr, "ILSRV: FreeHandle called for %X which is in wrong state (%s)\m", c->real_handle, adm_log_state2str(c->state));
            error_found();
        }
        fprintf(stderr, "ILSRV: %08X [%20s] Freehandle (internal=%X)\n", c->real_handle, last_part(c->name), c);
        m->result = OMX_FreeHandle(c->real_handle);
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        del_component(c);
        memset(c, 0xFE, sizeof(*c));
        free(c);
        return;
    }

    case MSG_SEND_COMMAND: {
        struct comp* c = (struct comp*) m->cmd.free_handle.srv_handle;
        verify_component(c);
        if (m->cmd.command.cmd == OMX_CommandStateSet) {
            fprintf(stderr, "ILSRV: %08X [%20s] SendCommand StateSet %s\n", c->real_handle, last_part(c->name), adm_log_state2str((OMX_STATETYPE) m->cmd.command.nParam1));
        } else {
            fprintf(stderr, "ILSRV: %08X [%20s] SendCommand StateSet %s 0x%X\n", c->real_handle, last_part(c->name), adm_log_cmd2str(m->cmd.command.cmd), m->cmd.command.nParam1);
        }

        m->result = OMX_SendCommand(c->real_handle, m->cmd.command.cmd, m->cmd.command.nParam1, 0);
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_SETUP_TUNNEL: {
        struct comp* c_in = (struct comp*) m->cmd.tunnel.srv_handle_in;
        struct comp* c_out = (struct comp*) m->cmd.tunnel.srv_handle_out;
        verify_component(c_in);
        verify_component(c_out);

        fprintf(stderr, "ILSRV: SetupTunnel %08X [%20s].%d --> %08X [%20s].%d\n", c_out->real_handle, last_part(c_out->name), m->cmd.tunnel.port_out, c_in->real_handle, last_part(c_in->name), m->cmd.tunnel.port_in);
        m->result = OMX_SetupTunnel(c_out->real_handle, m->cmd.tunnel.port_out, c_in->real_handle, m->cmd.tunnel.port_in);
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_GET_STATE: {
        struct comp* c = (struct comp*) m->cmd.get_state.in_srv_handle;
        verify_component(c);
        fprintf(stderr, "ILSRV: %08X [%20s] GetState\n", c->real_handle, last_part(c->name));
        m->result = OMX_GetState(c->real_handle, &m->cmd.get_state.out_state);
        fprintf(stderr, "ILSRV: --> %s %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result), adm_log_state2str(m->cmd.get_state.out_state));
        return;
    }

    case MSG_ALLOC_BUFFER: {
        struct comp* c = (struct comp*) m->cmd.alloc_buffer.in_srv_handle;
        verify_component(c);

        OMX_BUFFERHEADERTYPE* bufhdr;
        fprintf(stderr, "ILSRV: %08X [%20s] AllocBuf port=%d size=%d\n", c->real_handle, last_part(c->name), m->cmd.alloc_buffer.port, m->cmd.alloc_buffer.size);
        m->result = OMX_AllocateBuffer(c->real_handle, &bufhdr, m->cmd.alloc_buffer.port,
                     (void*) m->cmd.alloc_buffer.in_client_buf_hdr, m->cmd.alloc_buffer.size);

        if (m->result == OMX_ErrorNone) {
            memcpy(&m->cmd.alloc_buffer.out_buf_hdr, bufhdr, sizeof(OMX_BUFFERHEADERTYPE));
            m->cmd.alloc_buffer.out_srv_buf_hdr = (int) bufhdr;
            add_bufhdr(bufhdr);
        }
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    case MSG_EMPTY_BUFFER: {
        struct comp* c = (struct comp*) m->cmd.empty_buffer.in_srv_handle;
        verify_component(c);

        OMX_BUFFERHEADERTYPE* client_bufhdr = (OMX_BUFFERHEADERTYPE*) &m->cmd.empty_buffer.in_buf_hdr;
        OMX_BUFFERHEADERTYPE* bufhdr = (OMX_BUFFERHEADERTYPE*) client_bufhdr->pPlatformPrivate;

        verify_bufhdr(bufhdr);

        if (bufhdr->nAllocLen <= sizeof(m->cmd.empty_buffer.in_buf)) {
            bufhdr->nOffset    = client_bufhdr->nOffset;
            bufhdr->nTimeStamp = client_bufhdr->nTimeStamp;
            bufhdr->nFilledLen = client_bufhdr->nFilledLen;
            bufhdr->nFlags     = client_bufhdr->nFlags;

            memcpy(bufhdr->pBuffer, &m->cmd.empty_buffer.in_buf, bufhdr->nAllocLen);
            fprintf(stderr, "ILSRV: %08X [%20s] EmptyBuffer port=%d size=%d\n", c->real_handle, last_part(c->name), bufhdr->nInputPortIndex, bufhdr->nAllocLen);
            m->result = OMX_EmptyThisBuffer(c->real_handle, bufhdr);
            fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        } else {
            assert(0);
        }

        return;
    }

    case MSG_FILL_BUFFER: {
        struct comp* c = (struct comp*) m->cmd.empty_buffer.in_srv_handle;
        verify_component(c);

        OMX_BUFFERHEADERTYPE* client_bufhdr = (OMX_BUFFERHEADERTYPE*) &m->cmd.fill_buffer.in_buf_hdr;
        OMX_BUFFERHEADERTYPE* bufhdr = (OMX_BUFFERHEADERTYPE*) client_bufhdr->pPlatformPrivate;

        verify_bufhdr(bufhdr);

        fprintf(stderr, "ILSRV: %08X [%20s] FillBuffer port=%d size=%d\n", c->real_handle, last_part(c->name), bufhdr->nOutputPortIndex, bufhdr->nAllocLen);
        m->result = OMX_FillThisBuffer(c->real_handle, bufhdr);
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));

        return;
    }

    case MSG_FREE_BUFFER: {
        struct comp* c = (struct comp*) m->cmd.empty_buffer.in_srv_handle;
        verify_component(c);

        OMX_BUFFERHEADERTYPE* bufhdr = (OMX_BUFFERHEADERTYPE*) m->cmd.free_buffer.in_srv_buf_hdr;
        verify_bufhdr(bufhdr);

        del_bufhdr(bufhdr);
        fprintf(stderr, "ILSRV: %08X [%20s] FreeBuffer\n", c->real_handle, last_part(c->name));
        m->result = OMX_FreeBuffer(c->real_handle, m->cmd.free_buffer.in_port, bufhdr);
        fprintf(stderr, "ILSRV: --> %s %s\n", m->result == OMX_ErrorNone ? "" : "ERROR ", adm_log_err2str(m->result));
        return;
    }

    default:
       fprintf(stderr, "ILSRV: Unhandled request received\n");
       m->result = OMX_ErrorNotImplemented;
       error_found();
       return;
    }
예제 #22
0
/* will be feeding stuff into the encoding pipeline */
void *
decode_thread(void *context) {

    OMX_BUFFERHEADERTYPE *input_buffer; // buffer taken from the OMX decoder
    OMX_PARAM_PORTDEFINITIONTYPE encoder_config;
    OMX_PARAM_PORTDEFINITIONTYPE decoder_config;
    OMX_PARAM_PORTDEFINITIONTYPE deinterlacer_config;
    OMX_VIDEO_PARAM_PORTFORMATTYPE encoder_format_config; //used for the output of the encoder
    OMX_VIDEO_PARAM_BITRATETYPE encoder_bitrate_config; //used for the output of the encoder
    struct transcoder_ctx_t *ctx = (struct transcoder_ctx_t *) context;
    struct packet_t *current_packet;
    int bytes_left;
    uint8_t *p; // points to currently copied buffer

    //    omx_setup_encoding_pipeline(&decoder_ctx->pipeline, OMX_VIDEO_CodingAVC);
    omx_setup_encoding_pipeline(&ctx->pipeline, OMX_VIDEO_CodingMPEG2);

    // main loop that will poll packets and render
    while (ctx->input_video_queue->queue_count != 0 || ctx->input_video_queue->queue_finished != 1) {
        //TODO a memory barrier is going to be needed so that we don't race
        current_packet = packet_queue_get_next_item(ctx->input_video_queue);
        p = current_packet->data;
        bytes_left = current_packet->data_length;

        while (bytes_left > 0) {

            fprintf(stderr, "OMX buffers: v: %02d/20, vcodec queue: %4d\r", omx_get_free_buffer_count(&ctx->pipeline.video_decode), ctx->input_video_queue->queue_count);
            input_buffer = omx_get_next_input_buffer(&ctx->pipeline.video_decode); // This will block if there are no empty buffers

            // copy at most the length of the OMX buf
            int copy_length = OMX_MIN(bytes_left, input_buffer->nAllocLen);

            memcpy(input_buffer->pBuffer, p, copy_length);
            p += copy_length;
            bytes_left -= copy_length;

            input_buffer->nFilledLen = copy_length;
            input_buffer->nTimeStamp = pts_to_omx(current_packet->PTS);

            if (ctx->first_packet) {
                input_buffer->nFlags = OMX_BUFFERFLAG_STARTTIME;
                ctx->first_packet = 0;
            } else {
                //taken from ilclient
                input_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN;
            }

            if (current_packet->flags & AV_PKT_FLAG_KEY) {
                input_buffer->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
            }

            if(bytes_left == 0) {
                input_buffer->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
            }

            //configure the resizer after the decoder has got output
            if (ctx->pipeline.video_decode.port_settings_changed == 1) {
                ctx->pipeline.video_decode.port_settings_changed = 0;
#if 0
                int x = 640;
                int y = 480;

                // rounding the dimensions up to the next multiple of 16.
                x += 0x0f;
                x &= ~0x0f;
                y += 0x0f;
                y &= ~0x0f;
                //the above code is used if resizer is used

                //get information about the decoded video
                OMX_INIT_STRUCTURE(decoder_config);
                decoder_config.nPortIndex = 131;
                OERR(OMX_GetParameter(ctx->pipeline.video_decode.h, OMX_IndexParamPortDefinition, &decoder_config));

                decoder_config.nPortIndex = 190;
                OERR(OMX_GetParameter(ctx->pipeline.image_fx.h, OMX_IndexParamPortDefinition, &decoder_config));
                decoder_config.nPortIndex = 191;
                OERR(OMX_GetParameter(ctx->pipeline.image_fx.h, OMX_IndexParamPortDefinition, &decoder_config));
#endif
                OERR(OMX_SetupTunnel(ctx->pipeline.video_decode.h, 131, ctx->pipeline.image_fx.h, 190));
                omx_send_command_and_wait(&ctx->pipeline.video_decode, OMX_CommandPortEnable, 131, NULL);
                omx_send_command_and_wait(&ctx->pipeline.image_fx, OMX_CommandPortEnable, 190, NULL);
                omx_send_command_and_wait(&ctx->pipeline.image_fx, OMX_CommandStateSet, OMX_StateExecuting, NULL);

                fprintf(stderr, "configuring deinterlacer done\n");
            }

            if(ctx->pipeline.image_fx.port_settings_changed == 1) {
                OMX_ERRORTYPE error;
                ctx->pipeline.image_fx.port_settings_changed = 0;
#if 0
                //get info from deinterlacer output
                OMX_INIT_STRUCTURE(deinterlacer_config);
                deinterlacer_config.nPortIndex = 191;
                OERR(OMX_GetParameter(ctx->pipeline.image_fx.h, OMX_IndexParamPortDefinition, &deinterlacer_config));

                //get default from encoder input
                OMX_INIT_STRUCTURE(encoder_config);
                encoder_config.nPortIndex = 200;
                OERR(OMX_GetParameter(ctx->pipeline.video_encode.h, OMX_IndexParamPortDefinition, &encoder_config));
                //modify it with deinterlacer
                encoder_config.format.video.nFrameHeight = deinterlacer_config.format.image.nFrameHeight;
                encoder_config.format.video.nFrameWidth = deinterlacer_config.format.image.nFrameWidth;
                encoder_config.format.video.eCompressionFormat = deinterlacer_config.format.image.eCompressionFormat;
                encoder_config.format.video.eColorFormat = deinterlacer_config.format.image.eColorFormat;
                encoder_config.format.video.nSliceHeight = deinterlacer_config.format.image.nSliceHeight;
                encoder_config.format.video.nStride = deinterlacer_config.format.image.nStride;
                //and feed it
                OERR(OMX_SetParameter(ctx->pipeline.video_encode.h, OMX_IndexParamPortDefinition, &encoder_config));
#endif
                //configure encoder output format
                OMX_INIT_STRUCTURE(encoder_format_config);
                encoder_format_config.nPortIndex = 201; //encoder output port
                encoder_format_config.eCompressionFormat = OMX_VIDEO_CodingAVC;
                OERR(OMX_SetParameter(ctx->pipeline.video_encode.h, OMX_IndexParamVideoPortFormat, &encoder_format_config));

                //configure encoder output bitrate
                OMX_INIT_STRUCTURE(encoder_bitrate_config);
                encoder_bitrate_config.nPortIndex = 201;
                encoder_bitrate_config.eControlRate = OMX_Video_ControlRateVariable; //var bitrate
                encoder_bitrate_config.nTargetBitrate = ENCODED_BITRATE; //1 mbit
                OERR(OMX_SetParameter(ctx->pipeline.video_encode.h, OMX_IndexParamVideoBitrate, &encoder_bitrate_config));

                //setup tunnel from decoder to encoder
                OERR(OMX_SetupTunnel(ctx->pipeline.image_fx.h, 191, ctx->pipeline.video_encode.h, 200));

                //set encoder to idle after we have finished configuring it
                omx_send_command_and_wait0(&ctx->pipeline.video_encode, OMX_CommandStateSet, OMX_StateIdle, NULL);

                //allocate buffers for output of the encoder
                //send the enable command, which won't complete until the bufs are alloc'ed
                omx_send_command_and_wait0(&ctx->pipeline.video_encode, OMX_CommandPortEnable, 201, NULL);
                omx_alloc_buffers(&ctx->pipeline.video_encode, 201); //allocate output buffers
                //block until the port is fully enabled
                omx_send_command_and_wait1(&ctx->pipeline.video_encode, OMX_CommandPortEnable, 201, NULL);

                omx_send_command_and_wait1(&ctx->pipeline.video_encode, OMX_CommandStateSet, OMX_StateIdle, NULL);

                //enable the two ports
                omx_send_command_and_wait0(&ctx->pipeline.image_fx, OMX_CommandPortEnable, 191, NULL);
                omx_send_command_and_wait0(&ctx->pipeline.video_encode, OMX_CommandPortEnable, 200, NULL);
                omx_send_command_and_wait1(&ctx->pipeline.video_encode, OMX_CommandPortEnable, 200, NULL);
                omx_send_command_and_wait1(&ctx->pipeline.image_fx, OMX_CommandPortEnable, 191, NULL);

                omx_send_command_and_wait(&ctx->pipeline.video_encode, OMX_CommandStateSet, OMX_StateExecuting, NULL);
                fprintf(stderr, "finished configuring encoder\n");
            }

            if(ctx->pipeline.video_encode.port_settings_changed == 1) {
                fprintf(stderr, "encoder enabled\n");
                ctx->pipeline.video_encode.port_settings_changed = 0;
                //signal the consumer thread it can start polling for data
                ctx->pipeline.video_encode.is_running = 1;
                pthread_cond_signal(&ctx->pipeline.video_encode.is_running_cv);
            }

            OERR(OMX_EmptyThisBuffer(ctx->pipeline.video_decode.h, input_buffer));
        }

        packet_queue_free_packet(current_packet, 1);
        current_packet = NULL;
    }

    printf("Finishing stream \n");
    /* Indicate end of video stream */
    input_buffer = omx_get_next_input_buffer(&ctx->pipeline.video_decode);

    input_buffer->nFilledLen = 0;
    input_buffer->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;

    OERR(OMX_EmptyThisBuffer(ctx->pipeline.video_decode.h, input_buffer));

    // omx_teardown_pipeline(&decoder_ctx->pipeline);
}
예제 #23
0
int main(int argc, char **argv)
{

    int i;
    char *decodeComponentName;
    char *renderComponentName;
    int err;
    ILCLIENT_T *handle;
    COMPONENT_T *decodeComponent;
    COMPONENT_T *renderComponent;
    COMPONENT_T *fxComponent;
    int do_deinterlace = 0;

    if (argc >= 2)
    {
        IMG = argv[1];
    }
    if (argc >= 3)
    {
        if (strcmp(argv[2],"d")==0)
            do_deinterlace = 1;
    }

    FILE *fp = fopen(IMG, "r");
    int toread = get_file_size(IMG);
    OMX_BUFFERHEADERTYPE *buff_header;

    decodeComponentName = "video_decode";
    renderComponentName = "video_render";

    bcm_host_init();

    handle = ilclient_init();
    if (handle == NULL)
    {
        fprintf(stderr, "IL client init failed\n");
        exit(1);
    }

    if (OMX_Init() != OMX_ErrorNone)
    {
        ilclient_destroy(handle);
        fprintf(stderr, "OMX init failed\n");
        exit(1);
    }

    ilclient_set_error_callback(handle,
                                error_callback,
                                NULL);
    ilclient_set_eos_callback(handle,
                              eos_callback,
                              NULL);

    setup_decodeComponent(handle, decodeComponentName, &decodeComponent);
    setup_renderComponent(handle, renderComponentName, &renderComponent);
    if (do_deinterlace)
        setup_fxComponent(handle, "image_fx", &fxComponent);
    // both components now in Idle state, no buffers, ports disabled

    // input port
    ilclient_enable_port_buffers(decodeComponent, 130,
                                 NULL, NULL, NULL);
    ilclient_enable_port(decodeComponent, 130);

    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change state to Executing\n");
        exit(1);
    }
    printState(ilclient_get_handle(decodeComponent));

    // Read the first block so that the decodeComponent can get
    // the dimensions of the video and call port settings
    // changed on the output port to configure it
    while (toread > 0)
    {
        buff_header =
            ilclient_get_input_buffer(decodeComponent,
                                      130,
                                      1 /* block */);
        if (buff_header != NULL)
        {
            read_into_buffer_and_empty(fp,
                                       decodeComponent,
                                       buff_header,
                                       &toread);

            // If all the file has been read in, then
            // we have to re-read this first block.
            // Broadcom bug?
            if (toread <= 0)
            {
                printf("Rewinding\n");
                // wind back to start and repeat
                fp = freopen(IMG, "r", fp);
                toread = get_file_size(IMG);
            }
        }

        if (toread > 0 && ilclient_remove_event(decodeComponent, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0)
        {
            printf("Removed port settings event\n");
            break;
        }
        else
        {
            printf("No port setting seen yet\n");
        }
        // wait for first input block to set params for output port
        if (toread == 0)
        {
            // wait for first input block to set params for output port
            err = ilclient_wait_for_event(decodeComponent,
                                          OMX_EventPortSettingsChanged,
                                          131, 0, 0, 1,
                                          ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED,
                                          2000);
            if (err < 0)
            {
                fprintf(stderr, "No port settings change\n");
                //exit(1);
            }
            else
            {
                printf("Port settings changed\n");
                break;
            }
        }
    }

    // set the decode component to idle and disable its ports
    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateIdle);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change state to Idle\n");
        exit(1);
    }
    ilclient_disable_port(decodeComponent, 131);
    ilclient_disable_port_buffers(decodeComponent, 131,
                                  NULL, NULL, NULL);

    if (do_deinterlace)
    {
        // set up the tunnel between decode and fx ports
        err = OMX_SetupTunnel(ilclient_get_handle(decodeComponent),
                            131,
                            ilclient_get_handle(fxComponent),
                            190);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel 1 %X\n", err);
            exit(1);
        }
        else
        {
            printf("Tunnel 1 set up ok\n");
        }

        // set up the tunnel between fx and render ports
        err = OMX_SetupTunnel(ilclient_get_handle(fxComponent),
                            191,
                            ilclient_get_handle(renderComponent),
                            90);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel 2 %X\n", err);
            exit(1);
        }
        else
        {
            printf("Tunnel 2 set up ok\n");
        }
    }
    else
    {
        // set up the tunnel between decode and render ports
        err = OMX_SetupTunnel(ilclient_get_handle(decodeComponent),
                            131,
                            ilclient_get_handle(renderComponent),
                            90);
        if (err != OMX_ErrorNone)
        {
            fprintf(stderr, "Error setting up tunnel %X\n", err);
        exit(1);
        }
        else
        {
            printf("Tunnel set up ok\n");
        }
    }
    // Okay to go back to processing data
    // enable the decode output ports

//UNNECESSARY?? PGB    OMX_SendCommand(ilclient_get_handle(decodeComponent),
//UNNECESSARY?? PGB                    OMX_CommandPortEnable, 131, NULL);

    ilclient_enable_port(decodeComponent, 131);

    if (do_deinterlace)
    {
        setup_shared_buffer_format(decodeComponent, 131, fxComponent, 191);
        // enable fx ports
        ilclient_enable_port(fxComponent, 190);
        ilclient_enable_port(fxComponent, 191);

//UNNECESSARY?? PGB    OMX_SendCommand(ilclient_get_handle(renderComponent),
//UNNECESSARY?? PGB                    OMX_CommandPortEnable, 90, NULL);

        // setup_shared_buffer_format(fxComponent, renderComponent);
    }
    // enable the render output ports
    ilclient_enable_port(renderComponent, 90);

    // set all components to executing state
    err = ilclient_change_component_state(decodeComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change decode to Executing\n");
        exit(1);
    }
    if (do_deinterlace)
    {
        err = ilclient_change_component_state(fxComponent,
                                            OMX_StateExecuting);
        if (err < 0)
        {
            fprintf(stderr, "Couldn't change fx to Executing\n");
            exit(1);
        }
    }
    err = ilclient_change_component_state(renderComponent,
                                          OMX_StateExecuting);
    if (err < 0)
    {
        fprintf(stderr, "Couldn't change render to Executing\n");
        exit(1);
    }

    print_port_info(ilclient_get_handle(decodeComponent), 131);
    if (do_deinterlace)
    {
        print_port_info(ilclient_get_handle(fxComponent), 190);
        print_port_info(ilclient_get_handle(fxComponent), 191);
    }
    print_port_info(ilclient_get_handle(renderComponent), 90);

    // now work through the file
    while (toread > 0)
    {
        OMX_ERRORTYPE r;

        // do we have a decode input buffer we can fill and empty?
        buff_header =
            ilclient_get_input_buffer(decodeComponent,
                                      130,
                                      1 /* block */);
        if (buff_header != NULL)
        {
            read_into_buffer_and_empty(fp,
                                       decodeComponent,
                                       buff_header,
                                       &toread);
        }
        usleep(100000);
        // print_port_info(ilclient_get_handle(renderComponent), 90);
    }


    ilclient_wait_for_event(renderComponent,
                            OMX_EventBufferFlag,
                            90, 0, OMX_BUFFERFLAG_EOS, 0,
                            ILCLIENT_BUFFER_FLAG_EOS, 10000);
    printf("EOS on render\n");

    sleep(100);

    exit(0);
}
OMX_ERRORTYPE NonTextureEngine::onCameraEventParamOrConfigChanged()
{

	ofLogVerbose(__func__) << "START";
	
	OMX_ERRORTYPE error = OMX_SendCommand(camera, OMX_CommandStateSet, OMX_StateIdle, NULL);
	if (error != OMX_ErrorNone) 
	{
		ofLog(OF_LOG_ERROR, "camera OMX_SendCommand OMX_StateIdle FAIL error: 0x%08x", error);
	}
	
	//Enable Camera Output Port
	OMX_CONFIG_PORTBOOLEANTYPE cameraport;
	OMX_INIT_STRUCTURE(cameraport);
	cameraport.nPortIndex = CAMERA_OUTPUT_PORT;
	cameraport.bEnabled = OMX_TRUE;
	
	error =OMX_SetParameter(camera, OMX_IndexConfigPortCapturing, &cameraport);	
	if (error != OMX_ErrorNone) 
	{
		ofLog(OF_LOG_ERROR, "camera enable Output Port FAIL error: 0x%08x", error);
	}
	
	
	
	if (omxCameraSettings.doRecording) 
	{		
		if (omxCameraSettings.doRecordingPreview) 
		{
			//Set up renderer
			setupRenderer();
		} 
		
		
		//set up encoder
		OMX_CALLBACKTYPE encoderCallbacks;
		encoderCallbacks.EventHandler		= &BaseEngine::encoderEventHandlerCallback;
		encoderCallbacks.EmptyBufferDone	= &BaseEngine::encoderEmptyBufferDone;
		encoderCallbacks.FillBufferDone		= &NonTextureEngine::encoderFillBufferDone;
		
		
		string encoderComponentName = "OMX.broadcom.video_encode";
		
		error =OMX_GetHandle(&encoder, (OMX_STRING)encoderComponentName.c_str(), this , &encoderCallbacks);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_GetHandle FAIL error: 0x%08x", error);
		}
		
		configureEncoder();
		
		if (omxCameraSettings.doRecordingPreview) 
		{
			//Create camera->video_render Tunnel
			error = OMX_SetupTunnel(camera, CAMERA_PREVIEW_PORT, render, VIDEO_RENDER_INPUT_PORT);
			if (error != OMX_ErrorNone) 
			{
				ofLog(OF_LOG_ERROR, "camera->video_render OMX_SetupTunnel FAIL error: 0x%08x", error);
			}
		}

		// Tunnel camera video output port and encoder input port
		error = OMX_SetupTunnel(camera, CAMERA_OUTPUT_PORT, encoder, VIDEO_ENCODE_INPUT_PORT);
		if(error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "CAMERA_OUTPUT_PORT->VIDEO_ENCODE_INPUT_PORT OMX_SetupTunnel FAIL error: 0x%08x", error);
		}

		
		//Set encoder to Idle
		error = OMX_SendCommand(encoder, OMX_CommandStateSet, OMX_StateIdle, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_SendCommand OMX_StateIdle FAIL error: 0x%08x", error);
		}
		
		//Set camera to Idle
		error = OMX_SendCommand(camera, OMX_CommandStateSet, OMX_StateIdle, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera OMX_SendCommand OMX_StateIdle FAIL error: 0x%08x", error);
		}
		
		if (omxCameraSettings.doRecordingPreview)
		{
			//Enable camera preview port
			error = OMX_SendCommand(camera, OMX_CommandPortEnable, CAMERA_PREVIEW_PORT, NULL);
			if (error != OMX_ErrorNone) 
			{
				ofLog(OF_LOG_ERROR, "camera OMX_CommandPortEnable CAMERA_PREVIEW_PORT FAIL error: 0x%08x", error);
			}
		}
	
		//Enable camera output port
		error = OMX_SendCommand(camera, OMX_CommandPortEnable, CAMERA_OUTPUT_PORT, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera OMX_CommandPortEnable CAMERA_OUTPUT_PORT FAIL error: 0x%08x", error);
		}
		
		//Enable encoder input port
		error = OMX_SendCommand(encoder, OMX_CommandPortEnable, VIDEO_ENCODE_INPUT_PORT, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_CommandPortEnable VIDEO_ENCODE_INPUT_PORT FAIL error: 0x%08x", error);
		}
		
		//Enable encoder output port
		error = OMX_SendCommand(encoder, OMX_CommandPortEnable, VIDEO_ENCODE_OUTPUT_PORT, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_CommandPortEnable VIDEO_ENCODE_OUTPUT_PORT FAIL error: 0x%08x", error);
		}
		
		if (omxCameraSettings.doRecordingPreview) 
		{
			//Enable render input port
			error = OMX_SendCommand(render, OMX_CommandPortEnable, VIDEO_RENDER_INPUT_PORT, NULL);
			if (error != OMX_ErrorNone) 
			{
				ofLog(OF_LOG_ERROR, "render enable output port FAIL error: 0x%08x", error);
			}
		}

		OMX_PARAM_PORTDEFINITIONTYPE encoderOutputPortDefinition;
		OMX_INIT_STRUCTURE(encoderOutputPortDefinition);
		encoderOutputPortDefinition.nPortIndex = VIDEO_ENCODE_OUTPUT_PORT;
		error =OMX_GetParameter(encoder, OMX_IndexParamPortDefinition, &encoderOutputPortDefinition);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_GetParameter OMX_IndexParamPortDefinition FAIL error: 0x%08x", error);
		}else 
		{
			ofLogVerbose(__func__) << "VIDEO_ENCODE_OUTPUT_PORT eColorFormat: " << OMX_Maps::getInstance().colorFormatTypes[encoderOutputPortDefinition.format.video.eColorFormat];
		}

		error =  OMX_AllocateBuffer(encoder, &encoderOutputBuffer, VIDEO_ENCODE_OUTPUT_PORT, NULL, encoderOutputPortDefinition.nBufferSize);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_AllocateBuffer VIDEO_ENCODE_OUTPUT_PORT FAIL error: 0x%08x", error);
			
		}
		

		//Start camera
		error = OMX_SendCommand(camera, OMX_CommandStateSet, OMX_StateExecuting, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera OMX_StateExecuting FAIL error: 0x%08x", error);
		}
		
		//Start encoder
		error = OMX_SendCommand(encoder, OMX_CommandStateSet, OMX_StateExecuting, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_StateExecuting FAIL error: 0x%08x", error);		
		}
		
		if (omxCameraSettings.doRecordingPreview) 
		{
			
			//Start renderer
			error = OMX_SendCommand(render, OMX_CommandStateSet, OMX_StateExecuting, NULL);
			if (error != OMX_ErrorNone) 
			{
				ofLog(OF_LOG_ERROR, "render OMX_StateExecuting FAIL error: 0x%08x", error);		
			}
			
			setupDisplay();
			
		}
		
		
		error = OMX_FillThisBuffer(encoder, encoderOutputBuffer);
		
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "encoder OMX_FillThisBuffer FAIL error: 0x%08x", error);		
		}
		
		bool doThreadBlocking	= true;
		startThread(doThreadBlocking);
		
	}else 
	{
		setupRenderer();
		
		
		//Create camera->video_render Tunnel
		error = OMX_SetupTunnel(camera, CAMERA_OUTPUT_PORT, render, VIDEO_RENDER_INPUT_PORT);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera->video_render OMX_SetupTunnel FAIL error: 0x%08x", error);
		}
		
		//Enable camera output port
		error = OMX_SendCommand(camera, OMX_CommandPortEnable, CAMERA_OUTPUT_PORT, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera enable output port FAIL error: 0x%08x", error);
		}
		
		//Enable render input port
		error = OMX_SendCommand(render, OMX_CommandPortEnable, VIDEO_RENDER_INPUT_PORT, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "render enable output port FAIL error: 0x%08x", error);
		}
		
		
		//Start renderer
		error = OMX_SendCommand(render, OMX_CommandStateSet, OMX_StateExecuting, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "render OMX_StateExecuting FAIL error: 0x%08x", error);		
		}
		
		//Start camera
		error = OMX_SendCommand(camera, OMX_CommandStateSet, OMX_StateExecuting, NULL);
		if (error != OMX_ErrorNone) 
		{
			ofLog(OF_LOG_ERROR, "camera OMX_StateExecuting FAIL error: 0x%08x", error);
		}
		
		setupDisplay();
				
	}

	isOpen = true;
	return error;
}
예제 #25
0
파일: omxtxres.c 프로젝트: arjenv/omxtx
int main(int argc, char *argv[])
{
	AVFormatContext	*ic;
	char		*iname;
	char		*oname;
	char		*size;
	int		err;
	int		vidindex;
	int		i, j;
	OMX_ERRORTYPE	oerr;
	OMX_HANDLETYPE	m2 = NULL, m4 = NULL, resize = NULL;
	OMX_VIDEO_PARAM_PORTFORMATTYPE	*pfmt;
	OMX_PORT_PARAM_TYPE		*porttype;
	OMX_PARAM_PORTDEFINITIONTYPE	*portdef;
	OMX_BUFFERHEADERTYPE		*decbufs;
	OMX_VIDEO_PORTDEFINITIONTYPE	*viddef;
	OMX_VIDEO_PARAM_PROFILELEVELTYPE *level;
	int		decportidx = 200;
	int		resizeportidx = 60;
	int		encportidx = 130;
	int		fd;
	time_t		start, end;
	int		offset;
	AVPacket	*p, *rp;
	int		ish264;
	int		filtertest;
	int		opt;
	ILCLIENT_T	*client;

	if (argc < 3)
		usage(argv[0]);

	ctx.bitrate = 2*1024*1024;
	ctx.verbose = 0;
	ctx.width = 0;
	ctx.height = 0;

	while ((opt = getopt(argc, argv, ":b:vs:")) != -1) {
		switch (opt) {
		case 'b':	//bitrate
			ctx.bitrate = atoi(optarg);
			printf("bitrate = %d\n", ctx.bitrate);
			break;
		case 'v':	//verbose`
			ctx.verbose = 1;
			break;
		case 's':	//WxH
			ctx.width = atoi(optarg);
			if ((atoi(optarg) % 16) != 0) {
				printf("W = %d is not a multiple of 16\n", ctx.width);
				usage(argv[0]);
			}
			if (ctx.width <16 || ctx.width > 1080) {
				printf("W = %d should be between 16 and 1080\n", ctx.width);
				usage(argv[0]);
			}	
			printf("W = %d\n", ctx.width);
			if ((size = strchr(optarg, 'x')) == NULL) {
				printf("wrong size parameter (no 'x') exiting\n");
				usage(argv[0]);
			}
			ctx.height = atoi(size+1);
			if ((atoi(size+1) % 16) != 0) {
				printf("H = %d is not a multiple of 16\n", ctx.height);
				usage(argv[0]);
			}
			if (ctx.height <16 || ctx.height > 1080) {
				printf("H = %d should be between 16 and 1080\n", ctx.height);
				usage(argv[0]);
			}	
			printf("H = %d\n", ctx.height);
			break;
		case '?':
			usage(argv[0]);
		}
	}
	if ((client = ilclient_init()) == NULL)
		return -2;
	iname = argv[optind++];
	oname = argv[optind++];

	MAKEME(porttype, OMX_PORT_PARAM_TYPE);
	MAKEME(portdef, OMX_PARAM_PORTDEFINITIONTYPE);
	MAKEME(pfmt, OMX_VIDEO_PARAM_PORTFORMATTYPE);

	av_register_all();

	ic = NULL;
	ish264 = 0;
	pthread_mutex_init(&ctx.lock, NULL);

#if 0
	fmt = av_oformat_next(fmt);
	while (fmt) {
		printf("Found '%s'\t\t'%s'\n", fmt->name, fmt->long_name);
		fmt = av_oformat_next(fmt);
	}
#endif

	/* Input init: */

	if ((err = avformat_open_input(&ic, iname, NULL, NULL) != 0)) {
		fprintf(stderr, "Failed to open '%s': %s\n", iname,
			strerror(err));
		exit(1);
	}
	ctx.ic = ic;

	if (avformat_find_stream_info(ic, NULL) < 0) {
		fprintf(stderr, "Failed to find streams in '%s'\n", iname);
		exit(1);
	}

	av_dump_format(ic, 0, iname, 0);

	vidindex = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1,
		NULL, 0);
	if (vidindex < 0) {
		fprintf(stderr, "Failed to find a video stream in '%s'\n",
			iname);
		exit(1);
	}
	printf("Found a video at index %d\n", vidindex);

	printf("Frame size: %dx%d\n", ic->streams[vidindex]->codec->width, 
		ic->streams[vidindex]->codec->height);
	ish264 = (ic->streams[vidindex]->codec->codec_id == CODEC_ID_H264);

	/* Output init: */
	ctx.fd = fd = open(oname, O_CREAT | O_LARGEFILE | O_WRONLY | O_TRUNC,
			0666);
	printf("File descriptor %d\n", fd);


#if 0
	avformat_alloc_output_context(&oc, NULL, /*NULL,*/ oname);
	if (!oc) {
		printf("Couldn't determine output from '%s'; using MPEG.\n",
			oname);
		avformat_alloc_output_context(&oc, NULL, /*"matroska",*/ oname);
	}
#endif
//	if (!oc)
//		exit(1);
	
//	fmt = oc->oformat;
	
	for (i = 0; i < ic->nb_streams; i++) {
		printf("Found stream %d, context %p\n",
			ic->streams[i]->index, ic->streams[i]->codec);
	}

	bcm_host_init();
	OERR(OMX_Init(), ctx.verbose);
	OERR(OMX_GetHandle(&m2, DECNAME, &ctx, &decevents), ctx.verbose);
	OERR(OMX_GetHandle(&m4, ENCNAME, &ctx, &encevents), ctx.verbose);
	OERR(OMX_GetHandle(&resize, RESIZENAME, &ctx, &resizeevents), ctx.verbose);
	ctx.m2 = m2;
	ctx.m4 = m4;
	ctx.resize = resize;

	if (ctx.verbose) printf("Obtained handles.  %p decode, %p resize, %p encode\n",
		m2, resize, m4);

	OERR(OMX_GetParameter(m2, OMX_IndexParamVideoInit, porttype), ctx.verbose);
	if (ctx.verbose) printf("Found %d ports, starting at %d (%x) on decoder\n",
		porttype->nPorts, porttype->nStartPortNumber,
		porttype->nStartPortNumber);
	ctx.decportidx = decportidx = porttype->nStartPortNumber;

	OERR(OMX_GetParameter(resize, OMX_IndexParamImageInit, porttype), ctx.verbose);
	if (ctx.verbose) printf("Found %d ports, starting at %d (%x) on resizer\n",
		porttype->nPorts, porttype->nStartPortNumber,
		porttype->nStartPortNumber);
	ctx.resizeportidx = resizeportidx = porttype->nStartPortNumber;

	OERR(OMX_GetParameter(m4, OMX_IndexParamVideoInit, porttype), ctx.verbose);
	if (ctx.verbose) printf("Found %d ports, starting at %d (%x) on encoder\n",
		porttype->nPorts, porttype->nStartPortNumber,
		porttype->nStartPortNumber);
	ctx.encportidx = encportidx = porttype->nStartPortNumber;
	free(porttype);

	OERR(OMX_SendCommand(m2, OMX_CommandPortDisable, decportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m2, OMX_CommandPortDisable, decportidx+1, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortDisable, resizeportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortDisable, resizeportidx+1, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandPortDisable, encportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandPortDisable, encportidx+1, NULL), ctx.verbose);

	portdef->nPortIndex = decportidx;
	OERR(OMX_GetParameter(m2, OMX_IndexParamPortDefinition, portdef), ctx.verbose);
	viddef = &portdef->format.video;
	viddef->nFrameWidth = ic->streams[vidindex]->codec->width;
	viddef->nFrameHeight = ic->streams[vidindex]->codec->height;
	printf("Mapping codec %d to %d\n",
		ic->streams[vidindex]->codec->codec_id,
		mapcodec(ic->streams[vidindex]->codec->codec_id));
	viddef->eCompressionFormat = 
		mapcodec(ic->streams[vidindex]->codec->codec_id);
	viddef->bFlagErrorConcealment = 0;
//	viddef->xFramerate = 25<<16;
	OERR(OMX_SetParameter(m2, OMX_IndexParamPortDefinition, portdef), ctx.verbose);
	free(portdef);

#if 0
/* It appears these have limited effect: */
	dataunit->nPortIndex = decportidx;
	dataunit->eUnitType = OMX_DataUnitCodedPicture;
	dataunit->eEncapsulationType = OMX_DataEncapsulationGenericPayload;
	OERR(OMX_SetParameter(m2, OMX_IndexParamBrcmDataUnit, dataunit), ctx.verbose);

	if (ish264) {
		naltype->nPortIndex = decportidx;
		naltype->eNaluFormat = OMX_NaluFormatStartCodes;
		OERR(OMX_SetParameter(m2, OMX_IndexParamNalStreamFormatSelect, naltype), ctx.verbose);
	}
#endif

	MAKEME(level, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
	level->nPortIndex = encportidx+1;
/* Dump what the encoder is capable of: */
	if (ctx.verbose) print_codecs();
	if (ctx.verbose) {
		for (oerr = OMX_ErrorNone, i = 0; oerr == OMX_ErrorNone; i++) {
			pfmt->nIndex = i;
			oerr = OMX_GetParameter(m4, OMX_IndexParamVideoPortFormat, pfmt);
			if (oerr == OMX_ErrorNoMore)
				break;
			printf("Codecs supported:\n"
				"\tIndex:\t\t%d\n"
				"\tCodec:\t\t%d (%x)\n"
				"\tColour:\t\t%d\n"
				"\tFramerate:\t%x (%f)\n",
				pfmt->nIndex,
				pfmt->eCompressionFormat, pfmt->eCompressionFormat,
				pfmt->eColorFormat,
				pfmt->xFramerate,
				((float)pfmt->xFramerate/(float)65536));
		}

		for (oerr = OMX_ErrorNone, i = 0; oerr == OMX_ErrorNone; i++) {
			level->nProfileIndex = i;
			oerr = OMX_GetParameter(m4,
				OMX_IndexParamVideoProfileLevelQuerySupported,
				level);
			if (oerr == OMX_ErrorNoMore)
				break;
			printf("Levels supported:\n"
				"\tIndex:\t\t%d\n"
				"\tProfile:\t%d\n"
				"\tLevel:\t\t%d\n",
				level->nProfileIndex,
				level->eProfile,
				level->eLevel);
		}
	}
	free(pfmt);
	free(level);

/* Dump current port states: */
	if (ctx.verbose) {
		dumpport(m2, decportidx);
		dumpport(m2, decportidx+1);
		dumpport(resize, resizeportidx);
		dumpport(resize, resizeportidx+1);
		dumpport(m4, encportidx);
		dumpport(m4, encportidx+1);
	}

	OERR(OMX_SendCommand(m2, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx.verbose);

	decbufs = allocbufs(m2, decportidx, 1);

/* Start the initial loop.  Process until we have a state change on port 131 */
	ctx.decstate = DECINIT;
	ctx.encstate = ENCPREINIT;
	OERR(OMX_SendCommand(m2, OMX_CommandStateSet, OMX_StateExecuting, NULL), ctx.verbose);

	rp = calloc(sizeof(AVPacket), 1);
	filtertest = ish264;

	for (offset = i = j = 0; ctx.decstate != DECFAILED; i++, j++) {
		int rc;
		int k;
		int size, nsize;
		OMX_BUFFERHEADERTYPE *spare;

		if (offset == 0 && ctx.decstate != DECFLUSH) {
			rc = av_read_frame(ic, rp);
			if (rc != 0) {
				if (ic->pb->eof_reached)
					ctx.decstate = DECFLUSH;
				break;
			}
			if (rp->stream_index != vidindex) {
				i--;
				av_free_packet(rp);
				continue;
			}
			size = rp->size;
			ctx.fps++;
			ctx.framecount++;

			if (ish264 && filtertest) {
				filtertest = 0;
				ctx.bsfc = dofiltertest(rp);
			}
			if (ctx.bsfc) {
				p = filter(&ctx, rp);
			} else {
				p = rp;
			}
		}

		switch (ctx.decstate) {
		case DECTUNNELSETUP:
			start = time(NULL);
			//printf("NOW to CONFIGURE !!!!!!!!!!!!!!\n\n");
			configure(&ctx);
			ctx.decstate = DECRUNNING;
			break;
		case DECFLUSH:
			size = 0;
			/* Add the flush code here */
			printf("IN FLUSH NOW\n\n");
			break;
		case DECINIT:
			if (i < 120) /* Bail; decoder doesn't like it */
				break;
			ctx.decstate = DECFAILED;
			/* Drop through */
		case DECFAILED:
			fprintf(stderr, "Failed to set the parameters after "
					"%d video frames.  Giving up.\n", i);
			dumpport(m2, decportidx);
			dumpport(m2, decportidx+1);
			dumpport(resize, resizeportidx);
			dumpport(resize, resizeportidx+1);
			dumpport(m4, encportidx);
			dumpport(m4, encportidx+1);
			exit(1);
			break;
		default:
			break;	/* Shuts the compiler up */
		}

		for (spare = NULL; !spare; usleep(10)) {
			pthread_mutex_lock(&ctx.lock);
			spare = ctx.bufhead;
			ctx.bufhead = NULL;
			ctx.flags &= ~FLAGS_DECEMPTIEDBUF;
			pthread_mutex_unlock(&ctx.lock);
			while (spare) {
				write(fd, &spare->pBuffer[spare->nOffset],
					spare->nFilledLen);
				spare->nFilledLen = 0;
				spare->nOffset = 0;
				OERRq(OMX_FillThisBuffer(m4, spare));
				spare = spare->pAppPrivate;
			}

			spare = decbufs;
			for (k = 0; spare && spare->nFilledLen != 0; k++)
				spare = spare->pAppPrivate;
		}

		if (size > spare->nAllocLen) {
			nsize = spare->nAllocLen;
		} else {
			nsize = size;
		}

		if (ctx.decstate != DECFLUSH) {
			memcpy(spare->pBuffer, &(p->data[offset]), nsize);
			spare->nFlags = i == 0 ? OMX_BUFFERFLAG_STARTTIME : 0;
			spare->nFlags |= size == nsize ?
				OMX_BUFFERFLAG_ENDOFFRAME : 0;
		} else {
			spare->nFlags = OMX_BUFFERFLAG_STARTTIME |
					OMX_BUFFERFLAG_EOS;
		}
		spare->nFilledLen = nsize;
		spare->nOffset = 0;
		OERRq(OMX_EmptyThisBuffer(m2, spare));
		size -= nsize;
		if (size) {
			offset += nsize;
		} else {
			offset = 0;
			av_free_packet(p);
		}
	}

	close(fd);

	end = time(NULL);

	printf("Processed %d frames in %d seconds; %df/s\n",
		ctx.framecount, end-start, (ctx.framecount/(end-start)));

	// flush the encoder
//	OERR(OMX_SendCommand(m4, OMX_CommandFlush, encportidx, NULL), ctx.verbose);
//	OERR(OMX_SendCommand(m4, OMX_CommandFlush, encportidx+ctx.verbose, NULL), ctx.verbose);



	// tear down the tunnels
	OERR(OMX_SendCommand(m2, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandStateSet, OMX_StateIdle, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m2, OMX_CommandStateSet, OMX_StateLoaded, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandStateSet, OMX_StateLoaded, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandStateSet, OMX_StateLoaded, NULL), ctx.verbose);
	// free buffers
	vcos_free(decbufs);
	vcos_free(ctx.encbufs);
	// Apparantly the teardwon function is not implemented. Use setup function instead
	//OERR(OMX_TeardownTunnel(m2, decportidx+ctx.verbose, resize, resizeportidx), ctx.verbose);
	//OERR(OMX_TeardownTunnel(resize, resizeportidx+ctx.verbose, m4, encportidx), ctx.verbose);
	OERR(OMX_SendCommand(m2, OMX_CommandPortDisable, decportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m2, OMX_CommandPortDisable, decportidx+ctx.verbose, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortDisable, resizeportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(resize, OMX_CommandPortDisable, resizeportidx+ctx.verbose, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandPortDisable, encportidx, NULL), ctx.verbose);
	OERR(OMX_SendCommand(m4, OMX_CommandPortDisable, encportidx+ctx.verbose, NULL), ctx.verbose);
//	ilclient_disable_port_buffers(m2, decportidx, NULL, NULL, NULL);
//	ilclient_disable_port_buffers(m4, encportidx, NULL, NULL, NULL);
	OERR(OMX_SetupTunnel(m2, decportidx+ctx.verbose, NULL, 0), ctx.verbose);
	OERR(OMX_SetupTunnel(resize, resizeportidx, NULL, 0), ctx.verbose);
	OERR(OMX_SetupTunnel(resize, resizeportidx+ctx.verbose, NULL, 0), ctx.verbose);
	OERR(OMX_SetupTunnel(m4, encportidx, NULL, 0), ctx.verbose);
	OERR(OMX_FreeHandle(m2), ctx.verbose);
	OERR(OMX_FreeHandle(resize), ctx.verbose);
	OERR(OMX_FreeHandle(m4), ctx.verbose);

//	free(porttype);
//	free(portdef);
//	free(pfmt);
//	free(level);
	return 0;
}
예제 #26
0
파일: jpeg.c 프로젝트: 1234sv/firmware
int
portSettingsChanged(OPENMAX_JPEG_DECODER * decoder)
{
    OMX_PARAM_PORTDEFINITIONTYPE portdef;

    // need to setup the input for the resizer with the output of the
    // decoder
    portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    portdef.nVersion.nVersion = OMX_VERSION;
    portdef.nPortIndex = decoder->imageDecoder->outPort;
    OMX_GetParameter(decoder->imageDecoder->handle,
		     OMX_IndexParamPortDefinition, &portdef);

    unsigned int    uWidth =
	(unsigned int) portdef.format.image.nFrameWidth;
    unsigned int    uHeight =
	(unsigned int) portdef.format.image.nFrameHeight;

    // tell resizer input what the decoder output will be providing
    portdef.nPortIndex = decoder->imageResizer->inPort;
    OMX_SetParameter(decoder->imageResizer->handle,
		     OMX_IndexParamPortDefinition, &portdef);

    // establish tunnel between decoder output and resizer input
    OMX_SetupTunnel(decoder->imageDecoder->handle,
		    decoder->imageDecoder->outPort,
		    decoder->imageResizer->handle,
		    decoder->imageResizer->inPort);

    // enable ports
    OMX_SendCommand(decoder->imageDecoder->handle,
		    OMX_CommandPortEnable,
		    decoder->imageDecoder->outPort, NULL);
    OMX_SendCommand(decoder->imageResizer->handle,
		    OMX_CommandPortEnable,
		    decoder->imageResizer->inPort, NULL);

    // put resizer in idle state (this allows the outport of the decoder
    // to become enabled)
    OMX_SendCommand(decoder->imageResizer->handle,
		    OMX_CommandStateSet, OMX_StateIdle, NULL);

    // wait for state change complete
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete,
			    OMX_CommandStateSet, 1,
			    OMX_StateIdle, 1, 0, TIMEOUT_MS);

    // once the state changes, both ports should become enabled and the
    // resizer
    // output should generate a settings changed event
    ilclient_wait_for_event(decoder->imageDecoder->component,
			    OMX_EventCmdComplete,
			    OMX_CommandPortEnable, 1,
			    decoder->imageDecoder->outPort, 1, 0,
			    TIMEOUT_MS);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete, OMX_CommandPortEnable, 1,
			    decoder->imageResizer->inPort, 1, 0,
			    TIMEOUT_MS);
    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventPortSettingsChanged,
			    decoder->imageResizer->outPort, 1, 0, 1, 0,
			    TIMEOUT_MS);

    ilclient_disable_port(decoder->imageResizer->component,
			  decoder->imageResizer->outPort);

    // query output buffer requirements for resizer
    portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    portdef.nVersion.nVersion = OMX_VERSION;
    portdef.nPortIndex = decoder->imageResizer->outPort;
    OMX_GetParameter(decoder->imageResizer->handle,
		     OMX_IndexParamPortDefinition, &portdef);

    // change output color format and dimensions to match input
    portdef.format.image.eCompressionFormat = OMX_IMAGE_CodingUnused;
    portdef.format.image.eColorFormat = OMX_COLOR_Format32bitABGR8888;
    portdef.format.image.nFrameWidth = uWidth;
    portdef.format.image.nFrameHeight = uHeight;
    portdef.format.image.nStride = 0;
    portdef.format.image.nSliceHeight = 0;
    portdef.format.image.bFlagErrorConcealment = OMX_FALSE;

    OMX_SetParameter(decoder->imageResizer->handle,
		     OMX_IndexParamPortDefinition, &portdef);

    // grab output requirements again to get actual buffer size
    // requirement (and buffer count requirement!)
    OMX_GetParameter(decoder->imageResizer->handle,
		     OMX_IndexParamPortDefinition, &portdef);

    // move resizer into executing state
    ilclient_change_component_state(decoder->imageResizer->component,
				    OMX_StateExecuting);

    // show some logging so user knows it's working
    printf
	("Width: %u Height: %u Output Color Format: 0x%x Buffer Size: %u\n",
	 (unsigned int) portdef.format.image.nFrameWidth,
	 (unsigned int) portdef.format.image.nFrameHeight,
	 (unsigned int) portdef.format.image.eColorFormat,
	 (unsigned int) portdef.nBufferSize);
    fflush(stdout);

    // enable output port of resizer
    OMX_SendCommand(decoder->imageResizer->handle,
		    OMX_CommandPortEnable,
		    decoder->imageResizer->outPort, NULL);

    // allocate the buffer
    // void* outputBuffer = 0; 
    // if (posix_memalign(&outputBuffer, portdef.nBufferAlignment,
    // portdef.nBufferSize) != 0)
    // {
    // perror("Allocating output buffer");
    // return OMXJPEG_ERROR_MEMORY;
    // }

    // set the buffer
    // int ret = OMX_UseBuffer(decoder->imageResizer->handle,
    // &decoder->pOutputBufferHeader,
    // decoder->imageResizer->outPort, NULL,
    // portdef.nBufferSize,
    // (OMX_U8 *) outputBuffer);
    int             ret = OMX_AllocateBuffer(decoder->imageResizer->handle,
					     &decoder->pOutputBufferHeader,
					     decoder->imageResizer->
					     outPort,
					     NULL,
					     portdef.nBufferSize);
    if (ret != OMX_ErrorNone) {
	perror("Eror allocating buffer");
	fprintf(stderr, "OMX_AllocateBuffer returned 0x%x allocating buffer size 0x%x\n", ret, portdef.nBufferSize);
	return OMXJPEG_ERROR_MEMORY;
    }

    ilclient_wait_for_event(decoder->imageResizer->component,
			    OMX_EventCmdComplete,
			    OMX_CommandPortEnable, 1,
			    decoder->imageResizer->outPort, 1, 0,
			    TIMEOUT_MS);

    return OMXJPEG_OK;
}
int main(int argc, char** argv) {
  int argn_dec;
  OMX_ERRORTYPE err;
  OMX_INDEXTYPE eIndexParamFilename;
  int gain=-1;
  OMX_AUDIO_CONFIG_VOLUMETYPE sVolume;
  OMX_TIME_CONFIG_TIMESTAMPTYPE sTimeStamp;
  OMX_PARAM_COMPONENTROLETYPE sComponentRole;
  
  char *stream_dir=NULL;
  DIR *dirp;
	struct dirent *dp;
  int seek=1;

  flagSetupTunnel = 1;
  flagPlaybackOn = 1;
  flagUsingFFMpeg = 1;
  flagIsGain = 0;

  if(argc <= 3) {
    argn_dec = 1;
    while (argn_dec<argc) {
      if (*(argv[argn_dec]) =='-') {
        switch (*(argv[argn_dec]+1)) {
        case 's':
          seek = 0;
          break;
        //case 't':
        //  flagSetupTunnel = 0;
        //  break;
        default:
          display_help();
        }
      } else {
        stream_dir = malloc(strlen(argv[argn_dec]) * sizeof(char) + 1);
        strcpy(stream_dir,argv[argn_dec]);
      }
      argn_dec++;
    }
  } else if(argc > 3) {
    display_help();
  }

  if(stream_dir==NULL) {

    stream_dir = malloc(strlen(getenv("HOME")) * sizeof(char) + 20);
    memset(stream_dir, 0, sizeof(stream_dir));
	  strcat(stream_dir, getenv("HOME"));
	  strcat(stream_dir, "/stream/audio/");
  }

  DEBUG(DEFAULT_MESSAGES, "Directory Name=%s\n",stream_dir);

  /* Populate the registry file */
	dirp = opendir(stream_dir);
	if(dirp == NULL){
    int err = errno;
		DEBUG(DEB_LEV_ERR, "Cannot open directory %s\n", stream_dir);
		return err;
	}

  
  /** initializing appPriv structure */
  appPriv = malloc(sizeof(appPrivateType));
  appPriv->filereaderEventSem = malloc(sizeof(tsem_t));
  appPriv->decoderEventSem = malloc(sizeof(tsem_t));
  appPriv->eofSem = malloc(sizeof(tsem_t));
  if (flagPlaybackOn) {
    appPriv->sinkEventSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->sinkEventSem, 0);
    appPriv->volumeEventSem = malloc(sizeof(tsem_t));
    tsem_init(appPriv->volumeEventSem, 0);
  }
  tsem_init(appPriv->filereaderEventSem, 0);
  tsem_init(appPriv->decoderEventSem, 0);
  tsem_init(appPriv->eofSem, 0);

  /** initialising openmax */
  err = OMX_Init();
  if (err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
    exit(1);
  } 

  

  if(flagUsingFFMpeg) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Using File Reader\n");
    /** file reader component name -- gethandle*/
    err = OMX_GetHandle(&appPriv->filereaderhandle, FILE_READER, NULL , &filereadercallbacks);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "FileReader Component Not Found\n");
      exit(1);
    }  
    err = OMX_GetExtensionIndex(appPriv->filereaderhandle,"OMX.ST.index.param.inputfilename",&eIndexParamFilename);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"\n error in get extension index\n");
			exit(1);
    } 
  }

  /** getting the handle of audio decoder */
  err = OMX_GetHandle(&appPriv->audiodechandle, COMPONENT_NAME_BASE, NULL , &audiodeccallbacks);
  if(err != OMX_ErrorNone) {
    DEBUG(DEB_LEV_ERR, "Audio Decoder Component Not Found\n");
		exit(1);
  } 
  DEBUG(DEFAULT_MESSAGES, "Component %s opened\n", COMPONENT_NAME_BASE);

  if (flagPlaybackOn) {
    err = OMX_GetHandle(&appPriv->audiosinkhandle, SINK_NAME, NULL , &audiosinkcallbacks);
    if(err != OMX_ErrorNone){
      DEBUG(DEB_LEV_ERR, "No sink found. Exiting...\n");
      exit(1);
    }

    DEBUG(DEFAULT_MESSAGES, "Getting Handle for Component %s\n", AUDIO_EFFECT);
    err = OMX_GetHandle(&appPriv->volumehandle, AUDIO_EFFECT, NULL , &volumecallbacks);
    if(err != OMX_ErrorNone){
      DEBUG(DEB_LEV_ERR, "No sink found. Exiting...\n");
      exit(1);
    }

    if((gain >= 0) && (gain <100)) {
      err = OMX_GetConfig(appPriv->volumehandle, OMX_IndexConfigAudioVolume, &sVolume);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
      }
      sVolume.sVolume.nValue = gain;
      DEBUG(DEFAULT_MESSAGES, "Setting Gain %d \n", gain);
      err = OMX_SetConfig(appPriv->volumehandle, OMX_IndexConfigAudioVolume, &sVolume);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
      }
    }
  }

  if (flagSetupTunnel) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Setting up Tunnel\n");
    if(flagUsingFFMpeg) {
      err = OMX_SetupTunnel(appPriv->filereaderhandle, 0, appPriv->audiodechandle, 0);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
        exit(1);
      }
    }
    err = OMX_SetupTunnel(appPriv->audiodechandle, 1, appPriv->volumehandle, 0);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
      exit(1);
    }
    err = OMX_SetupTunnel(appPriv->volumehandle, 1, appPriv->audiosinkhandle, 0);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
      exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Set up Tunnel Completed\n");
  }

  if(flagUsingFFMpeg) {
    /** now set the filereader component to idle and executing state */
    OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  /*Send State Change Idle command to Audio Decoder*/
  DEBUG(DEB_LEV_SIMPLE_SEQ, "Send Command Idle to Audio Dec\n");
  err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  if (flagPlaybackOn) {
    DEBUG(DEB_LEV_SIMPLE_SEQ, "Send Command Idle to Audio Sink\n");
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  if(flagUsingFFMpeg) {
      /*Wait for File reader state change to */
    tsem_down(appPriv->filereaderEventSem);
    DEBUG(DEFAULT_MESSAGES,"File reader idle state \n");
  }

  tsem_down(appPriv->decoderEventSem);
  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    DEBUG(DEFAULT_MESSAGES,"volume state idle\n");
    tsem_down(appPriv->sinkEventSem);
    DEBUG(DEFAULT_MESSAGES,"audio sink state idle\n");
  }

  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"volume state executing failed\n");
			exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for  volume state executing\n");
    tsem_down(appPriv->volumeEventSem);

    DEBUG(DEB_LEV_SIMPLE_SEQ,"sending audio sink state executing\n");
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"audio sink state executing failed\n");
			exit(1);
    }
    DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for  audio sink state executing\n");
    tsem_down(appPriv->sinkEventSem);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink state executing successful\n");
  } 
  
  setHeader(&sComponentRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
  strcpy((char*)&sComponentRole.cRole[0], MP3_ROLE);

  while((dp = readdir(dirp)) != NULL) {
    int len = strlen(dp->d_name);

		if(len >= 3){
      
      if(strncmp(dp->d_name+len-4, ".mp3", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input Mp3 File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], MP3_ROLE);

      } else if(strncmp(dp->d_name+len-4, ".ogg", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input Vorbis File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], VORBIS_ROLE);
                
      } else if(strncmp(dp->d_name+len-4, ".aac", 4) == 0){
        
        if(input_file!=NULL) {
          free(input_file);
          input_file=NULL;
        }

        input_file = malloc(strlen(stream_dir) * sizeof(char) + sizeof(dp->d_name) +1);
        strcpy(input_file,stream_dir);
				strcat(input_file, dp->d_name);

        DEBUG(DEFAULT_MESSAGES, "Input AAC File Name=%s\n",input_file);

        flagUsingFFMpeg = 1;

        strcpy((char*)&sComponentRole.cRole[0], AAC_ROLE);
                
      } else {
        continue;
      }
    } else {
      continue;
    }

    
    /*Reset Global Variables*/
    tsem_reset(appPriv->eofSem);
    bEOS=OMX_FALSE;

    if (flagUsingFFMpeg) {
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Disable Command State Idle\n");
      /*Port Disable for filereader is sent from Port Settings Changed event of FileReader*/
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandPortDisable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader port disable failed\n");
			  exit(1);
      }
      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandPortDisable, OMX_ALL, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio decoder port disable failed\n");
			  exit(1);
      }

      err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortDisable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio sink port disable failed\n");
			  exit(1);
      }
      
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting File reader Port Disable event \n");
      /*Wait for File Reader Ports Disable Event*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"File reader Port Disable State Idle\n");
      /*Wait for Audio Decoder Ports Disable Event*/
      tsem_down(appPriv->decoderEventSem);
      tsem_down(appPriv->decoderEventSem);

      tsem_down(appPriv->volumeEventSem);

      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
      tsem_down(appPriv->decoderEventSem);
    }


    DEBUG(DEB_LEV_SIMPLE_SEQ,"Setting Role\n");

    err = OMX_SetParameter(appPriv->audiodechandle,OMX_IndexParamStandardComponentRole,&sComponentRole);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"\n error in input audio format - exiting\n");
      exit(1);
    }

    if(flagUsingFFMpeg) {
      /** setting the input audio format in file reader */
      DEBUG(DEB_LEV_SIMPLE_SEQ,"FileName Param index : %x \n",eIndexParamFilename);
      err = OMX_SetParameter(appPriv->filereaderhandle,eIndexParamFilename,input_file);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"\n error in input audio format - exiting\n");
        exit(1);
      }
    }
    
    if (flagUsingFFMpeg) {
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Enable Command State Idle\n");

      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
      tsem_down(appPriv->decoderEventSem);

      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandPortEnable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader port enable failed\n");
			  exit(1);
      }
      err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandPortEnable, OMX_ALL, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio decoder port enable failed\n");
			  exit(1);
      }

      err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandPortEnable, 0, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"audio sink port enable failed\n");
			  exit(1);
      }
      
      DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting File reader Port Disable event \n");
      /*Wait for File Reader Ports Disable Event*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEB_LEV_SIMPLE_SEQ,"File reader Port Disable State Idle\n");
      /*Wait for Audio Decoder Ports Disable Event*/
      tsem_down(appPriv->decoderEventSem);
      tsem_down(appPriv->decoderEventSem);
      
      tsem_down(appPriv->volumeEventSem);

      
    }

    if(flagUsingFFMpeg) {
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to executing*/
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEFAULT_MESSAGES,"File reader executing state \n");
    }

    err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
    if(err != OMX_ErrorNone) {
      DEBUG(DEB_LEV_ERR,"audio decoder state executing failed\n");
      exit(1);
    }
    
    DEBUG(DEB_LEV_SIMPLE_SEQ,"Waiting for audio dec state exec\n");
    /*Wait for decoder state change to executing*/
    tsem_down(appPriv->decoderEventSem);

    DEBUG(DEB_LEV_SIMPLE_SEQ,"All Component state changed to Executing\n");
    
    DEBUG(DEFAULT_MESSAGES,"Waiting for  EOS = %d\n",appPriv->eofSem->semval);

    if (seek==1) {

      DEBUG(DEFAULT_MESSAGES,"Sleeping for 5 Secs \n");
      /* Play for 5 Secs */
      sleep(5);
      DEBUG(DEFAULT_MESSAGES,"Sleep for 5 Secs is over\n");

      /*Then Pause the filereader component*/
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StatePause, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to Pause*/
      tsem_down(appPriv->filereaderEventSem);

      setHeader(&sTimeStamp, sizeof(OMX_TIME_CONFIG_TIMESTAMPTYPE));
      sTimeStamp.nPortIndex=0;
      /*Seek to 30 secs and play for 10 secs*/
      sTimeStamp.nTimestamp = 2351*38*30; // 23.51ms*38fps*30secs
      //sTimeStamp.nTimestamp = 2351*38*60*3; // 23.51ms*38fps*60secs*4mins
      DEBUG(DEFAULT_MESSAGES, "nTimestamp %llx \n", sTimeStamp.nTimestamp);
      err = OMX_SetConfig(appPriv->filereaderhandle, OMX_IndexConfigTimePosition, &sTimeStamp);
      if(err!=OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
      }

      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
      if(err != OMX_ErrorNone) {
        DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			  exit(1);
      }
      /*Wait for File reader state change to Pause*/
      tsem_down(appPriv->filereaderEventSem);

      DEBUG(DEFAULT_MESSAGES,"Sleeping for 10 Secs \n");
      /*Play for 10 secs*/
      sleep(10);
      DEBUG(DEFAULT_MESSAGES,"Sleep for 10 Secs is over\n");

      if(!bEOS) {
        /*Then Pause the filereader component*/
        err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StatePause, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			    exit(1);
        }
        /*Wait for File reader state change to Pause*/
        tsem_down(appPriv->filereaderEventSem);

        /*Seek to 5 mins or EOF*/
        sTimeStamp.nTimestamp = 2351*38*60*5; // 23.51ms*38fps*30secs
        //sTimeStamp.nTimestamp = 2351*38*60*3; // 23.51ms*38fps*60secs*4mins
        DEBUG(DEFAULT_MESSAGES, "nTimestamp %llx \n", sTimeStamp.nTimestamp);
        err = OMX_SetConfig(appPriv->filereaderhandle, OMX_IndexConfigTimePosition, &sTimeStamp);
        if(err!=OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
        }

        err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
        if(err != OMX_ErrorNone) {
          DEBUG(DEB_LEV_ERR,"file reader state executing failed\n");
			    exit(1);
        }
        /*Wait for File reader state change to Pause*/
        tsem_down(appPriv->filereaderEventSem);
      }
    }

    tsem_down(appPriv->eofSem);

    DEBUG(DEFAULT_MESSAGES,"Received EOS \n");
    /*Send Idle Command to all components*/
    DEBUG(DEFAULT_MESSAGES, "The execution of the decoding process is terminated\n");
    if(flagUsingFFMpeg) {
      err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    }
    err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    
    if(flagUsingFFMpeg) {
      tsem_down(appPriv->filereaderEventSem);
      DEBUG(DEFAULT_MESSAGES,"File reader idle state \n");
    }
    tsem_down(appPriv->decoderEventSem);
    
    DEBUG(DEFAULT_MESSAGES, "All component Transitioned to Idle\n");

  } /*Loop While Play List*/

  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
  }

  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    tsem_down(appPriv->sinkEventSem);
  }
  /*Send Loaded Command to all components*/
  if(flagUsingFFMpeg) {
    err = OMX_SendCommand(appPriv->filereaderhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  }
  err = OMX_SendCommand(appPriv->audiodechandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  if (flagPlaybackOn) {
    err = OMX_SendCommand(appPriv->volumehandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
    err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
  }

  DEBUG(DEFAULT_MESSAGES, "Audio dec to loaded\n");

  if(flagUsingFFMpeg) {
    tsem_down(appPriv->filereaderEventSem);
    DEBUG(DEFAULT_MESSAGES,"File reader loaded state \n");
  }
  tsem_down(appPriv->decoderEventSem);
  if (flagPlaybackOn) {
    tsem_down(appPriv->volumeEventSem);
    tsem_down(appPriv->sinkEventSem);
  }

  if(input_file!=NULL) {
    free(input_file);
    input_file=NULL;
  }

  closedir(dirp);

  DEBUG(DEFAULT_MESSAGES, "All components released\n");

  /** freeing all handles and deinit omx */
  OMX_FreeHandle(appPriv->audiodechandle);

  DEBUG(DEB_LEV_SIMPLE_SEQ, "audiodec dec freed\n");
  
  if(flagUsingFFMpeg) {
    OMX_FreeHandle(appPriv->filereaderhandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "filereader freed\n");
  }

  if (flagPlaybackOn) {
    OMX_FreeHandle(appPriv->volumehandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "volume component freed\n");
    OMX_FreeHandle(appPriv->audiosinkhandle);
    DEBUG(DEB_LEV_SIMPLE_SEQ, "audiosink freed\n");
  }

  OMX_Deinit();

  DEBUG(DEB_LEV_SIMPLE_SEQ, "All components freed. Closing...\n");

  free(appPriv->filereaderEventSem);
  appPriv->filereaderEventSem = NULL;

  free(appPriv->decoderEventSem);
  appPriv->decoderEventSem = NULL;
  if (flagPlaybackOn) {
    free(appPriv->volumeEventSem);
    appPriv->volumeEventSem = NULL;

    free(appPriv->sinkEventSem);
    appPriv->sinkEventSem = NULL;
  }

  free(appPriv->eofSem);
  appPriv->eofSem = NULL;
  free(appPriv);
  appPriv = NULL;

  if(input_file) {
    free(input_file);
  }

  return 0;
}	
예제 #28
0
OMX_ERRORTYPE omx_setup_camera_pipeline(struct omx_pipeline_t* pipe)
{

  // Create component.
  omx_init_component(pipe, &pipe->camera, "OMX.broadcom.camera");

  // Use OMX_IndexConfigRequestCallback to request callbacks on OMX_IndexParamCameraDeviceNumber.
  OMX_CONFIG_REQUESTCALLBACKTYPE cbtype;
  OMX_INIT_STRUCTURE(cbtype);
  cbtype.nPortIndex=OMX_ALL;
  cbtype.nIndex=OMX_IndexParamCameraDeviceNumber;
  cbtype.bEnable = OMX_TRUE;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigRequestCallback, &cbtype));

  // Set OMX_IndexParamISPTunerName.

  // Set OMX_IndexParamCameraFlashType.

  // Set OMX_IndexParamCameraDeviceNumber.
  OMX_PARAM_U32TYPE device;
  OMX_INIT_STRUCTURE(device);
  device.nPortIndex = OMX_ALL;
  device.nU32 = 0;
  OERR(OMX_SetParameter(pipe->camera.h, OMX_IndexParamCameraDeviceNumber, &device));

  dumpport(pipe->camera.h, 71);

  /* Set the resolution */
  OMX_PARAM_PORTDEFINITIONTYPE portdef;
  OMX_INIT_STRUCTURE(portdef);
  portdef.nPortIndex = 71;
  OERR(OMX_GetParameter(pipe->camera.h, OMX_IndexParamPortDefinition, &portdef));
  portdef.format.image.nFrameWidth = 640;
  portdef.format.image.nFrameHeight = 360;
  portdef.format.image.nStride = 640;
  OERR(OMX_SetParameter(pipe->camera.h, OMX_IndexParamPortDefinition, &portdef));

  /* Set the framerate */
  OMX_CONFIG_FRAMERATETYPE framerate;
  OMX_INIT_STRUCTURE(framerate);
  framerate.nPortIndex = 71;
  framerate.xEncodeFramerate = 25 << 16; // Q16 format - 25fps
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigVideoFramerate, &framerate));

  /* Set the sharpness */
  OMX_CONFIG_SHARPNESSTYPE sharpness;
  OMX_INIT_STRUCTURE(sharpness);
  sharpness.nPortIndex = OMX_ALL;
  sharpness.nSharpness = -50; /* -100 to 100 */
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonSharpness, &sharpness));

  /* Set the contrast */
  OMX_CONFIG_CONTRASTTYPE contrast;
  OMX_INIT_STRUCTURE(contrast);
  contrast.nPortIndex = OMX_ALL;
  contrast.nContrast = -10; /* -100 to 100 */
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonContrast, &contrast));

  /* Set the brightness */
  OMX_CONFIG_BRIGHTNESSTYPE brightness;
  OMX_INIT_STRUCTURE(brightness);
  brightness.nPortIndex = OMX_ALL;
  brightness.nBrightness = 50; /* 0 to 100 */
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonBrightness, &brightness));

  /* Set the saturation */
  OMX_CONFIG_SATURATIONTYPE saturation;
  OMX_INIT_STRUCTURE(saturation);
  saturation.nPortIndex = OMX_ALL;
  saturation.nSaturation = 0; /* -100 to 100 */
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonSaturation, &saturation));

  /* Video stabilisation */
  OMX_CONFIG_FRAMESTABTYPE framestab;
  OMX_INIT_STRUCTURE(framestab);
  framestab.nPortIndex = OMX_ALL;
  framestab.bStab = OMX_FALSE;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonFrameStabilisation, &framestab));

  /* Set EV compensation, ISO and metering mode */
  OMX_CONFIG_EXPOSUREVALUETYPE exposurevalue;
  OMX_INIT_STRUCTURE(exposurevalue);
  exposurevalue.nPortIndex = OMX_ALL;
  OERR(OMX_GetConfig(pipe->camera.h, OMX_IndexConfigCommonExposureValue, &exposurevalue));
  fprintf(stderr,"nSensitivity=%d\n",exposurevalue.nSensitivity);
  exposurevalue.xEVCompensation = 0;  /* Fixed point value stored as Q16 */
  exposurevalue.nSensitivity = 100;         /**< e.g. nSensitivity = 100 implies "ISO 100" */
  exposurevalue.bAutoSensitivity = OMX_FALSE;
  exposurevalue.eMetering = OMX_MeteringModeAverage; 
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonExposureValue, &exposurevalue));

  /* Set exposure mode */
  OMX_CONFIG_EXPOSURECONTROLTYPE exposure;
  OMX_INIT_STRUCTURE(exposure);
  exposure.nPortIndex = OMX_ALL;
  exposure.eExposureControl = OMX_ExposureControlAuto;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonExposure, &exposure));

  /* Set AWB mode */
  OMX_CONFIG_WHITEBALCONTROLTYPE awb;
  OMX_INIT_STRUCTURE(awb);
  awb.nPortIndex = OMX_ALL;
  awb.eWhiteBalControl = OMX_WhiteBalControlAuto;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonWhiteBalance, &awb));
  
  /* Set image effect */
  OMX_CONFIG_IMAGEFILTERTYPE imagefilter;
  OMX_INIT_STRUCTURE(imagefilter);
  imagefilter.nPortIndex = OMX_ALL;
  imagefilter.eImageFilter = OMX_ImageFilterNone;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonImageFilter, &imagefilter));

  /* 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;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigCommonColorEnhancement, &colour));

  /* Turn off the LED - doesn't work! */
  OMX_CONFIG_PRIVACYINDICATORTYPE privacy;
  OMX_INIT_STRUCTURE(privacy);
  privacy.ePrivacyIndicatorMode = OMX_PrivacyIndicatorOff;
  OERR(OMX_SetConfig(pipe->camera.h, OMX_IndexConfigPrivacyIndicator, &privacy));

  // Wait for the callback that OMX_IndexParamCameraDeviceNumber has
  // changed. At this point, all the drivers have been loaded. Other
  // settings can be applied whilst waiting for this event.
  fprintf(stderr,"Waiting for camera config to change\n");
  while (!pipe->camera.config_changed);  /* TODO: Use a condition variable */
  fprintf(stderr,"Config changed\n");

  // Query for OMX_IndexConfigCameraSensorModes as required.

  // Change state to IDLE, and proceed as required. 
  omx_send_command_and_wait(&pipe->camera, OMX_CommandStateSet, OMX_StateIdle, NULL);

  OMX_CONFIG_PORTBOOLEANTYPE cameraport;
  OMX_INIT_STRUCTURE(cameraport);
  cameraport.nPortIndex = 71;
  cameraport.bEnabled = OMX_TRUE;
  OERR(OMX_SetParameter(pipe->camera.h, OMX_IndexConfigPortCapturing, &cameraport));

  omx_init_component(pipe, &pipe->video_render, "OMX.broadcom.video_render");
  omx_send_command_and_wait(&pipe->video_render, OMX_CommandStateSet, OMX_StateIdle, NULL);

  OERR(OMX_SetupTunnel(pipe->camera.h, 71, pipe->video_render.h, 90));  /* Camera capture port to video render */

  omx_send_command_and_wait(&pipe->camera, OMX_CommandPortEnable, 71, NULL);
  omx_send_command_and_wait(&pipe->video_render, OMX_CommandPortEnable, 90, NULL);

  omx_send_command_and_wait(&pipe->video_render, OMX_CommandStateSet, OMX_StateExecuting, NULL);
  omx_send_command_and_wait(&pipe->camera, OMX_CommandStateSet, OMX_StateExecuting, NULL);

  omx_set_display_region(pipe, 1200, 180, 640, 360);

  OMX_CONFIG_DISPLAYREGIONTYPE region;
  OMX_INIT_STRUCTURE(region);
  region.nPortIndex = 90; /* Video render input port */
  region.set = OMX_DISPLAY_SET_LAYER;
  region.layer = 10;
  OERR(OMX_SetParameter(pipe->video_render.h, OMX_IndexConfigDisplayRegion, &region));

  fprintf(stderr,"Camera pipeline configured\n");

  dumpport(pipe->camera.h, 71);
}