gboolean gst_fsl_vpu_framebuffers_register_with_encoder(GstFslVpuFramebuffers *framebuffers, VpuEncHandle handle, guint src_stride) { VpuEncRetCode vpu_ret; if (framebuffers->registration_state != GST_FSL_VPU_FRAMEBUFFERS_UNREGISTERED) { GST_ERROR_OBJECT(framebuffers, "framebuffers already registered"); return FALSE; } framebuffers->decenc_states.enc.handle = handle; vpu_ret = VPU_EncRegisterFrameBuffer(handle, framebuffers->framebuffers, framebuffers->num_framebuffers, src_stride); if (vpu_ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(framebuffers, "registering framebuffers failed: %s", gst_fsl_vpu_strerror(vpu_ret)); return FALSE; } framebuffers->registration_state = GST_FSL_VPU_FRAMEBUFFERS_ENCODER_REGISTERED; framebuffers->decenc_states.enc.encoder_open = TRUE; return TRUE; }
int32_t encoder_allocate_framebuffer(struct encode *enc) { EncHandle handle = enc->handle; int32_t i, enc_stride, src_stride, src_fbid; int32_t totalfb, minfbcount, srcfbcount, extrafbcount; RetCode ret; FrameBuffer *fb; PhysicalAddress subSampBaseA = 0, subSampBaseB = 0; struct frame_buf **pfbpool; EncExtBufInfo extbufinfo = { 0 }; int32_t enc_fbwidth, enc_fbheight, src_fbwidth, src_fbheight; minfbcount = enc->minFrameBufferCount; srcfbcount = 1; enc_fbwidth = (enc->enc_picwidth + 15) & ~15; enc_fbheight = (enc->enc_picheight + 15) & ~15; src_fbwidth = (enc->src_picwidth + 15) & ~15; src_fbheight = (enc->src_picheight + 15) & ~15; if (cpu_is_mx6()) { if (enc->codecctrl->format == STD_AVC && enc->mvc_extension) /* MVC */ extrafbcount = 2 + 2; /* Subsamp [2] + Subsamp MVC [2] */ else if (enc->codecctrl->format == STD_MJPG) extrafbcount = 0; else extrafbcount = 2; /* Subsamp buffer [2] */ } else extrafbcount = 0; enc->totalfb = totalfb = minfbcount + extrafbcount + srcfbcount; /* last framebuffer is used as src frame in the test */ enc->src_fbid = src_fbid = totalfb - 1; fb = enc->fb = calloc(totalfb, sizeof(FrameBuffer)); if (fb == NULL) { err_msg("Failed to allocate enc->fb\n"); return -1; } pfbpool = enc->pfbpool = calloc(totalfb, sizeof(struct frame_buf *)); if (pfbpool == NULL) { err_msg("Failed to allocate enc->pfbpool\n"); free(fb); return -1; } if (enc->codecctrl->mapType == LINEAR_FRAME_MAP) { /* All buffers are linear */ for (i = 0; i < minfbcount + extrafbcount; i++) { pfbpool[i] = framebuf_alloc(enc->codecctrl->format, enc->mjpg_fmt, enc_fbwidth, enc_fbheight, 0); if (pfbpool[i] == NULL) { goto err1; } } } else { /* Encoded buffers are tiled */ for (i = 0; i < minfbcount; i++) { pfbpool[i] = tiled_framebuf_alloc(enc->codecctrl->format, enc->mjpg_fmt, enc_fbwidth, enc_fbheight, 0, enc->codecctrl->mapType); if (pfbpool[i] == NULL) goto err1; } /* sub frames are linear */ for (i = minfbcount; i < minfbcount + extrafbcount; i++) { pfbpool[i] = framebuf_alloc(enc->codecctrl->format, enc->mjpg_fmt, enc_fbwidth, enc_fbheight, 0); if (pfbpool[i] == NULL) goto err1; } } for (i = 0; i < minfbcount + extrafbcount; i++) { fb[i].myIndex = i; fb[i].bufY = pfbpool[i]->addrY; fb[i].bufCb = pfbpool[i]->addrCb; fb[i].bufCr = pfbpool[i]->addrCr; fb[i].strideY = pfbpool[i]->strideY; fb[i].strideC = pfbpool[i]->strideC; } if (cpu_is_mx6() && (enc->codecctrl->format != STD_MJPG)) { subSampBaseA = fb[minfbcount].bufY; subSampBaseB = fb[minfbcount + 1].bufY; if (enc->codecctrl->format == STD_AVC && enc->mvc_extension) { /* MVC */ extbufinfo.subSampBaseAMvc = fb[minfbcount + 2].bufY; extbufinfo.subSampBaseBMvc = fb[minfbcount + 3].bufY; } } /* Must be a multiple of 16 */ if (enc->codecctrl->rot_angle == 90 || enc->codecctrl->rot_angle == 270) enc_stride = (enc->enc_picheight + 15) & ~15; else enc_stride = (enc->enc_picwidth + 15) & ~15; src_stride = (enc->src_picwidth + 15) & ~15; extbufinfo.scratchBuf = enc->scratchBuf; ret = VPU_EncRegisterFrameBuffer(handle, fb, minfbcount, enc_stride, src_stride, subSampBaseA, subSampBaseB, &extbufinfo); if (ret != RETCODE_SUCCESS) { err_msg("Register frame buffer failed\n"); goto err1; } { /* Allocate a single frame buffer for source frame */ pfbpool[src_fbid] = framebuf_alloc(enc->codecctrl->format, enc->mjpg_fmt, src_fbwidth, src_fbheight, 0); if (pfbpool[src_fbid] == NULL) { err_msg("failed to allocate single framebuf\n"); goto err1; } fb[src_fbid].myIndex = enc->src_fbid; fb[src_fbid].bufY = pfbpool[src_fbid]->addrY; fb[src_fbid].bufCb = pfbpool[src_fbid]->addrCb; fb[src_fbid].bufCr = pfbpool[src_fbid]->addrCr; fb[src_fbid].strideY = pfbpool[src_fbid]->strideY; fb[src_fbid].strideC = pfbpool[src_fbid]->strideC; } return 0; err1: for (i = 0; i < totalfb; i++) { framebuf_free(pfbpool[i]); } free(fb); free(pfbpool); return -1; }
int enc_init(int w, int h, int fps, VpuCodStd std) { int tmp, nBufNum, nAlign, nSize; VpuEncRetCode res; VpuVersionInfo ver; VpuWrapperVersionInfo vver; VpuMemInfo sMemInfo; VpuEncOpenParam sEncOpenParam; VpuEncInitInfo sEncInitInfo; VpuFrameBuffer sFrameBuf[MAX_FRAME_NUM]; res = VPU_EncLoad(); if(res != VPU_ENC_RET_SUCCESS) { printf("VPU_ENC load error : %d\n", res); return -1; } res = VPU_EncGetVersionInfo(&ver); if (res != VPU_ENC_RET_SUCCESS) { printf("VPU_ENC get version error : %d\n", res); goto err; } res = VPU_EncGetWrapperVersionInfo(&vver); if (res != VPU_ENC_RET_SUCCESS) { printf("VPU_ENC get wrapper version error : %d\n", res); goto err; } printf("======= VPU ENC =======\n"); printf(" LIB : %d.%d.%d\n", ver.nLibMajor, ver.nLibMinor, ver.nLibRelease); printf(" FW : %d.%d.%d.%d\n", ver.nFwMajor, ver.nFwMinor, ver.nFwRelease, ver.nFwCode); printf(" WLIB: %d.%d.%d\n", vver.nMajor, vver.nMinor, vver.nRelease); printf("=======================\n"); res = VPU_EncQueryMem(&sMemInfo); if (res != VPU_ENC_RET_SUCCESS) { printf("VPU_ENC query memory error : %d\n", res); goto err; } tmp = enc_mem_alloc(&sMemInfo, &gMemInfo); if(tmp) { printf("enc_mem_alloc error\n"); goto err; } bzero(&sEncOpenParam, sizeof(VpuEncOpenParam)); sEncOpenParam.eFormat = std; sEncOpenParam.sMirror = VPU_ENC_MIRDIR_NONE; sEncOpenParam.nPicWidth = w; sEncOpenParam.nPicHeight = h; sEncOpenParam.nRotAngle = 0; sEncOpenParam.nFrameRate = fps; sEncOpenParam.nBitRate = 5000; sEncOpenParam.nGOPSize = 100; sEncOpenParam.nChromaInterleave = 0; sEncOpenParam.nMapType = 0; sEncOpenParam.nLinear2TiledEnable = 0; sEncOpenParam.eColorFormat = VPU_COLOR_420; sEncOpenParam.nInitialDelay = 0; sEncOpenParam.nVbvBufferSize = 0; sEncOpenParam.sliceMode.sliceMode = 0; /* 0: 1 slice per picture; 1: Multiple slices per picture */ sEncOpenParam.sliceMode.sliceSizeMode = 0; /* 0: silceSize defined by bits; 1: sliceSize defined by MB number*/ sEncOpenParam.sliceMode.sliceSize = 4000;//4000; /* Size of a slice in bits or MB numbers */ //sEncOpenParam.enableAutoSkip = 1; sEncOpenParam.nUserGamma = 0.75*32768; /* (0*32768 <= gamma <= 1*32768) */ sEncOpenParam.nRcIntervalMode = 0; //1; /* 0:normal, 1:frame_level, 2:slice_level, 3: user defined Mb_level */ sEncOpenParam.nMbInterval = 0; // sEncOpenParam.nAvcIntra16x16OnlyModeEnable = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_constrainedIntraPredFlag = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_disableDeblk = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_deblkFilterOffsetAlpha = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_deblkFilterOffsetBeta = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_chromaQpOffset = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_audEnable = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_fmoEnable = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_fmoType = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_fmoSliceNum = 0; // sEncOpenParam.VpuEncStdParam.avcParam.avc_fmoSliceSaveBufSize = 32; /* FMO_SLICE_SAVE_BUF_SIZE */ res = VPU_EncOpen(&gHandle, &sMemInfo, &sEncOpenParam); if (res != VPU_ENC_RET_SUCCESS) { printf("VPU_ENC open error : %d\n", res); goto err1; } res = VPU_EncConfig(gHandle, VPU_ENC_CONF_NONE, NULL); if(VPU_ENC_RET_SUCCESS != res) { printf("VPU_ENC config error : %d\n", res); goto err2; } //get initinfo res = VPU_EncGetInitialInfo(gHandle, &sEncInitInfo); if(VPU_ENC_RET_SUCCESS != res) { printf("VPU_ENC get Init Info error : %d\n", res); goto err2; } nBufNum = sEncInitInfo.nMinFrameBufferCount; nAlign = sEncInitInfo.nAddressAlignment; printf("Init OK: min buffer cnt: %d, alignment: %d\n", nBufNum, nAlign); tmp = enc_mem_frame(sEncOpenParam.eFormat, sFrameBuf, nBufNum, w, h, &gMemInfo, nAlign); if(tmp) { printf("enc_mem_frame error\n"); goto err2; } res = VPU_EncRegisterFrameBuffer(gHandle, sFrameBuf, nBufNum, w); if(VPU_ENC_RET_SUCCESS != res) { printf("VPU_ENC register frame buffer error : %d\n", res); goto err2; } nSize = w * h * 3 / 2; nSize += nAlign * 2; bzero(&sMemInfo, sizeof(VpuMemInfo)); sMemInfo.nSubBlockNum = 2; sMemInfo.MemSubBlock[0].MemType = VPU_MEM_PHY; sMemInfo.MemSubBlock[0].nAlignment = nAlign; sMemInfo.MemSubBlock[0].nSize = nSize; sMemInfo.MemSubBlock[1].MemType = VPU_MEM_PHY; sMemInfo.MemSubBlock[1].nAlignment = nAlign; sMemInfo.MemSubBlock[1].nSize = nSize; nSize = enc_mem_alloc(&sMemInfo, &gMemInfo); if(nSize) { printf("enc_mem_alloc error\n"); goto err2; } bzero(&gEncParam, sizeof(VpuEncEncParam)); gEncParam.eFormat = VPU_V_AVC; gEncParam.nPicWidth = w; gEncParam.nPicHeight = h; gEncParam.nFrameRate = sEncOpenParam.nFrameRate; gEncParam.nQuantParam = 0; gEncParam.nInPhyInput = (unsigned int)sMemInfo.MemSubBlock[0].pPhyAddr; gEncParam.nInVirtInput = (unsigned int)sMemInfo.MemSubBlock[0].pVirtAddr; gEncParam.nInInputSize = nSize; gEncParam.nInPhyOutput = (unsigned int)sMemInfo.MemSubBlock[1].pPhyAddr; gEncParam.nInVirtOutput=(unsigned int)sMemInfo.MemSubBlock[1].pVirtAddr; gEncParam.nInOutputBufLen = nSize; gEncParam.nForceIPicture = 0; gEncParam.nSkipPicture = 0; gEncParam.nEnableAutoSkip = 0; gEncParam.pInFrame = NULL; return 0; err2: VPU_EncClose(gHandle); err1: enc_mem_free(&gMemInfo); err: VPU_EncUnLoad(); return -1; }