ipu_lib_handle_t* ipu_init(int in_w, int in_h, int in_fmt, int out_w, int out_h, int out_fmt, int show) { ipu_lib_handle_t* ipu_handle = NULL; ipu_lib_input_param_t input; ipu_lib_output_param_t output; ipu_handle = calloc(1, sizeof(ipu_lib_handle_t)); memset(&input, 0, sizeof(ipu_lib_input_param_t)); memset(&output, 0, sizeof(ipu_lib_output_param_t)); input.width = in_w; input.height = in_h; input.fmt = in_fmt; output.width = out_w; output.height = out_h; output.fmt = out_fmt; output.show_to_fb = show; output.output_win.pos.x = 0; output.output_win.pos.y = 0; output.output_win.win_w = out_w; output.output_win.win_h = out_h; mxc_ipu_lib_task_init(&input, NULL, &output, OP_NORMAL_MODE|TASK_VF_MODE, ipu_handle); return ipu_handle; }
void ipu_disp_loop_thread(void *arg) { struct decode *dec = (struct decode *)arg; DecHandle handle = dec->handle; struct vpu_display *disp = dec->disp; int index = -1, disp_clr_index, tmp_idx[3] = {0,0,0}, err, mode; pthread_attr_t attr; ipu_running = 1; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_RR); while(1) { disp_clr_index = index; index = dequeue_buf(&(disp->ipu_q)); if (index < 0) { wait_queue(); ipu_waiting = 0; index = dequeue_buf(&(disp->ipu_q)); if (index < 0) { info_msg("thread is going to finish\n"); break; } } if (disp->ncount == 0) { disp->input.user_def_paddr[0] = disp->ipu_bufs[index].ipu_paddr; /* For video de-interlace, Low/Medium motion */ tmp_idx[0] = index; } else if ((disp->deinterlaced == 1) && (disp->input.motion_sel != HIGH_MOTION) && (disp->ncount == 1)) { disp->input.user_def_paddr[1] = disp->ipu_bufs[index].ipu_paddr; /* For video de-interlace, Low/Medium motion */ tmp_idx[1] = index; } else if ((disp->ncount == 1) || ((disp->deinterlaced == 1) && (disp->input.motion_sel != HIGH_MOTION) && (disp->ncount == 2))) { disp->input.user_def_paddr[disp->ncount] = disp->ipu_bufs[index].ipu_paddr; mode = (disp->deinterlaced == 1) ? (OP_STREAM_MODE | TASK_VDI_VF_MODE) : (OP_STREAM_MODE | TASK_PP_MODE); err = mxc_ipu_lib_task_init(&(disp->input), NULL, &(disp->output), mode, &(disp->ipu_handle)); if (err < 0) { err_msg("mxc_ipu_lib_task_init failed, err %d\n", err); quitflag = 1; return; } /* it only enable ipu task and finish first frame */ err = mxc_ipu_lib_task_buf_update(&(disp->ipu_handle), 0, 0, 0, NULL, NULL); if (err < 0) { err_msg("mxc_ipu_lib_task_buf_update failed, err %d\n", err); quitflag = 1; break; } /* For video de-interlace, Low/Medium motion */ tmp_idx[2] = index; if ((disp->deinterlaced == 1) && (disp->input.motion_sel != HIGH_MOTION)) disp_clr_index = tmp_idx[0]; } else { err = mxc_ipu_lib_task_buf_update(&(disp->ipu_handle), disp->ipu_bufs[index].ipu_paddr, 0, 0, NULL, NULL); if (err < 0) { err_msg("mxc_ipu_lib_task_buf_update failed, err %d\n", err); quitflag = 1; break; } /* For video de-interlace, Low/Medium motion */ if ((disp->deinterlaced == 1) && (disp->input.motion_sel != HIGH_MOTION)) { tmp_idx[0] = tmp_idx[1]; tmp_idx[1] = tmp_idx[2]; tmp_idx[2] = index; disp_clr_index = tmp_idx[0]; } } if ((dec->cmdl->format != STD_MJPG) && (disp_clr_index >= 0) && (!disp->stopping) && !((disp->deinterlaced == 1) && (disp->input.motion_sel != HIGH_MOTION) && (disp->ncount < 2))) { err = vpu_DecClrDispFlag(handle, disp_clr_index); if (err) { err_msg("vpu_DecClrDispFlag failed Error code %d\n", err); quitflag = 1; break; } } disp->ncount++; } mxc_ipu_lib_task_uninit(&(disp->ipu_handle)); pthread_attr_destroy(&attr); info_msg("Disp loop thread exit\n"); ipu_running = 0; return; }
OMX_ERRORTYPE VideoProcessorComponent::VideoProcessor_init( ) { OMX_ERRORTYPE eRetVal = OMX_ErrorNone; OMX_PARAM_PORTDEFINITIONTYPE sPortDef; OMX_BUFFERHEADERTYPE *pBufHdr; OMX_U32 nEGLImageWidth, nEGLImageHeight; int mode, ret; VP_DEBUG(" Begin Init\n"); /* Get In/Out port format */ omxSetHeader(&sPortDef,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); sPortDef.nPortIndex = VP_IN_PORT; ports[VP_IN_PORT]->GetPortDefinition( &sPortDef); nInWidth = sPortDef.format.video.nFrameWidth; nInHeight = sPortDef.format.video.nFrameHeight; eInColorFmt = sPortDef.format.video.eColorFormat; sPortDef.nPortIndex = VP_OUT_PORT; ports[VP_OUT_PORT]->GetPortDefinition(&sPortDef); nOutWidth = sPortDef.format.video.nFrameWidth; nOutHeight = sPortDef.format.video.nFrameHeight; eOutColorFmt = sPortDef.format.video.eColorFormat; if(sInRect.nWidth==0 && sInRect.nHeight==0) { sInRect.nWidth = nInWidth; sInRect.nHeight = nInHeight; } if( nOutWidth == 0 ||nOutHeight ==0 ) { nOutWidth = 1024; sPortDef.format.video.nFrameWidth = nOutWidth; nOutHeight = 768; sPortDef.format.video.nFrameHeight = nOutHeight; eOutColorFmt = OMX_COLOR_Format16bitRGB565; sPortDef.format.video.eColorFormat = eOutColorFmt; ports[VP_OUT_PORT]->SetPortDefinition(&sPortDef); } /* set ipu task in parameter */ sInParam.width = nInWidth; sInParam.height = nInHeight; sInParam.fmt = omx2ipu_pxlfmt(eInColorFmt); sInParam.input_crop_win.pos.x = (sInRect.nLeft + 7)/8*8; sInParam.input_crop_win.pos.y = sInRect.nTop; sInParam.input_crop_win.win_w = (sInRect.nWidth - (sInParam.input_crop_win.pos.x - sInRect.nLeft))/8*8; sInParam.input_crop_win.win_h = sInRect.nHeight; OMX_PTR pPhyAddr; ports[VP_IN_PORT]->GetBuffer( &pBufHdr); GetHwBuffer(pBufHdr->pBuffer, &pPhyAddr); sInParam.user_def_paddr[0] = (int)pPhyAddr; pInBufHdr[0] = pBufHdr; VP_DEBUG("VP Inbuffer 0 %p, offset %p\n",pBufHdr,pPhyAddr); ports[VP_IN_PORT]->GetBuffer( &pBufHdr); GetHwBuffer(pBufHdr->pBuffer, &pPhyAddr); sInParam.user_def_paddr[1] = (int)pPhyAddr; pInBufHdr[1] = pBufHdr; VP_DEBUG("VP Inbuffer 1 %p, offset %p\n",pBufHdr,pPhyAddr); VP_DEBUG("VP sInParam width %d, height %d,crop x %d, y %d, w %d, h %d, color %d\n", sInParam.width,sInParam.height , sInParam.input_crop_win.pos.x,sInParam.input_crop_win.pos.y, sInParam.input_crop_win.win_w,sInParam.input_crop_win.win_h, sInParam.fmt ); if(bUseEGLImage == OMX_TRUE) { ports[VP_OUT_PORT]->GetBuffer( &pBufHdr); EGLImageKHRInternal * eglImage = (EGLImageKHRInternal *)pBufHdr->pPlatformPrivate; sOutParam.user_def_paddr[0] = (int)eglImage->phyAddr; pOutBufHdr[0] = pBufHdr; nEGLImageWidth = eglImage->width; nEGLImageHeight = eglImage->height; OMX_S32 nImageSize = nEGLImageWidth * nEGLImageHeight * eglImage->bitsPerPixel / 8; fsl_osal_memset(eglImage->virtAddr, 0, nImageSize); ports[VP_OUT_PORT]->GetBuffer( &pBufHdr); eglImage = (EGLImageKHRInternal *)pBufHdr->pPlatformPrivate; sOutParam.user_def_paddr[1] = (int)eglImage->phyAddr; pOutBufHdr[1] = pBufHdr; fsl_osal_memset(eglImage->virtAddr,0,nImageSize); } /* set ipu task out parameter */ sOutParam.width = nOutWidth; sOutParam.height = nOutHeight; sOutParam.fmt = omx2ipu_pxlfmt(eOutColorFmt); if(sOutRect.nWidth==0 && sOutRect.nHeight==0) { sOutRect.nWidth = nOutWidth; sOutRect.nHeight = nOutHeight; } /* calc out pos according to in fmt*/ if(sInParam.input_crop_win.win_w * sOutRect.nHeight >= sInParam.input_crop_win.win_h * sOutRect.nWidth) { /* keep target width*/ OMX_U32 height = sOutRect.nWidth * sInParam.input_crop_win.win_h / sInParam.input_crop_win.win_w; sOutParam.output_win.win_w = sOutRect.nWidth; sOutParam.output_win.win_h = height; sOutParam.output_win.pos.x = 0; sOutParam.output_win.pos.y = (sOutRect.nHeight - height)/2; } else { /* keep target height*/ OMX_U32 width = sOutRect.nHeight * sInParam.input_crop_win.win_w / sInParam.input_crop_win.win_h; sOutParam.output_win.win_w = width; sOutParam.output_win.win_h = sOutRect.nHeight; sOutParam.output_win.pos.x = (( sOutRect.nWidth - width)/2 + 7)/8*8; sOutParam.output_win.pos.y = 0; } if(bUseEGLImage == OMX_TRUE) { sOutParam.width = nEGLImageWidth; sOutParam.height = nEGLImageHeight; } VP_DEBUG("VP sOutParam width %d, height %d,crop x %d, y %d, w %d, h %d,color %d\n", sOutParam.width,sOutParam.height , sOutParam.output_win.pos.x,sOutParam.output_win.pos.y, sOutParam.output_win.win_w,sOutParam.output_win.win_h, sOutParam.fmt ); /* ipu lib task init */ mode = OP_STREAM_MODE; ret = mxc_ipu_lib_task_init(&sInParam, NULL, &sOutParam, mode, &ipu_handle); if(ret < 0) { VP_ERROR("mxc_ipu_lib_task_init failed!\n"); return OMX_ErrorHardware; } nInFrames = 0; nOutFrames = 0; VP_DEBUG(" Exit Init\n"); return eRetVal; }
OMX_ERRORTYPE IpulibRender::IpulibInit(OMX_PTR pFrame) { OMX_PARAM_PORTDEFINITIONTYPE sPortDef; int mode, ret; /* set ipu task in parameter */ fsl_osal_memset(&sInParam, 0, sizeof(ipu_lib_input_param_t)); sInParam.width = sVideoFmt.nFrameWidth; sInParam.height = sVideoFmt.nFrameHeight; sInParam.input_crop_win.pos.x = (sRectIn.nLeft + 7)/8*8; sInParam.input_crop_win.pos.y = sRectIn.nTop; sInParam.input_crop_win.win_w = sRectIn.nWidth/8*8; sInParam.input_crop_win.win_h = sRectIn.nHeight; if(sVideoFmt.eColorFormat == OMX_COLOR_FormatYUV420Planar) { sInParam.fmt = ipu_fourcc('I', '4', '2', '0'); LOG_DEBUG("Set IPU in format to YUVI420.\n"); } else if(sVideoFmt.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { sInParam.fmt = ipu_fourcc('N', 'V', '1', '2'); LOG_DEBUG("Set IPU in format to NV12.\n"); } else if(sVideoFmt.eColorFormat == OMX_COLOR_FormatYUV422Planar) { sInParam.fmt = ipu_fourcc('4', '2', '2','P'); LOG_DEBUG("Set IPU in format to YUV422P.\n"); } /* FIXME: 422 interleave is not supported by IPU else if(sVideoFmt.eColorFormat == OMX_COLOR_FormatYUV422SemiPlanar) { sInParam.fmt = ipu_fourcc('N', 'V', '1', '6'); LOG_DEBUG("Set IPU in format to NV16.\n"); }*/ else { LOG_ERROR("Unsupported IPU color format : %d \n",sVideoFmt.eColorFormat); return OMX_ErrorHardware; } sInParam.user_def_paddr[0] = (int)pFrame; printf("IpulibRender sInParam width %d, height %d,crop x %d, y %d, w %d, h %d, color %d\n", sInParam.width,sInParam.height , sInParam.input_crop_win.pos.x,sInParam.input_crop_win.pos.y, sInParam.input_crop_win.win_w,sInParam.input_crop_win.win_h, sInParam.fmt ); /* set ipu task out parameter */ fsl_osal_memset(&sOutParam, 0, sizeof(ipu_lib_output_param_t)); sOutParam.width = sRectOut.nWidth; sOutParam.height = sRectOut.nHeight; sOutParam.fmt = ipu_fourcc('U', 'Y', 'V', 'Y'); sOutParam.rot = eRotation; sOutParam.show_to_fb = true; sOutParam.fb_disp.pos.x = sRectOut.nLeft; sOutParam.fb_disp.pos.y = sRectOut.nTop; if(sOutputMode.bTv != OMX_TRUE) sOutParam.fb_disp.fb_num = 2; else sOutParam.fb_disp.fb_num = 1; printf("IpulibRender sOutParam width %d, height %d,crop x %d, y %d, rot: %d, color %d\n", sOutParam.width, sOutParam.height , sOutParam.fb_disp.pos.x, sOutParam.fb_disp.pos.y, sOutParam.rot, sOutParam.fmt ); /* ipu lib task init */ mode = OP_NORMAL_MODE | TASK_PP_MODE; fsl_osal_memset(&ipu_handle, 0, sizeof(ipu_lib_handle_t)); ret = mxc_ipu_lib_task_init(&sInParam, NULL, &sOutParam, mode, &ipu_handle); if(ret < 0) { LOG_ERROR("mxc_ipu_lib_task_init failed!\n"); return OMX_ErrorHardware; } RegistSignalHandler(); return OMX_ErrorNone; }
void ipu_disp_loop_thread(void *arg) { struct DecodingInstance *dec = (struct DecodingInstance *)arg; struct vpu_display *disp = dec->disp; int index = -1, disp_clr_index, tmp_idx[3] = {0,0,0}, err, mode; pthread_attr_t attr; ipu_running = 1; pthread_attr_init(&attr); pthread_attr_setschedpolicy(&attr, SCHED_RR); while(1) { disp_clr_index = index; index = dequeue_buf(&(disp->ipu_q)); if (index < 0) { wait_queue(); ipu_waiting = 0; index = dequeue_buf(&(disp->ipu_q)); if (index < 0) { fputs("thread is going to finish\n", stderr); break; } } if (disp->ncount == 0) { disp->input.user_def_paddr[0] = disp->ipu_bufs[index].ipu_paddr; /* For video de-interlace, Low/Medium motion */ tmp_idx[0] = index; }else if ((disp->ncount == 1)) { disp->input.user_def_paddr[disp->ncount] = disp->ipu_bufs[index].ipu_paddr; mode = (OP_STREAM_MODE | TASK_PP_MODE); err = mxc_ipu_lib_task_init(&(disp->input), NULL, &(disp->output), mode, &(disp->ipu_handle)); if (err < 0) { fprintf(stderr, "mxc_ipu_lib_task_init failed, err %d\n", err); quitflag = 1; return; } /* it only enable ipu task and finish first frame */ err = mxc_ipu_lib_task_buf_update(&(disp->ipu_handle), 0, 0, 0, NULL, NULL); if (err < 0) { fprintf(stderr, "mxc_ipu_lib_task_buf_update failed, err %d\n", err); quitflag = 1; break; } } else { err = mxc_ipu_lib_task_buf_update(&(disp->ipu_handle), disp->ipu_bufs[index].ipu_paddr, 0, 0, NULL, NULL); if (err < 0) { fprintf(stderr, "mxc_ipu_lib_task_buf_update failed, err %d\n", err); quitflag = 1; break; } } disp->ncount++; } mxc_ipu_lib_task_uninit(&(disp->ipu_handle)); pthread_attr_destroy(&attr); fputs("Disp loop thread exit\n", stderr); ipu_running = 0; return; }