static gboolean gst_fsl_vpu_base_enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state) { VpuEncRetCode ret; GstVideoCodecState *output_state; GstFslVpuBaseEncClass *klass; GstFslVpuBaseEnc *vpu_base_enc; vpu_base_enc = GST_FSL_VPU_BASE_ENC(encoder); klass = GST_FSL_VPU_BASE_ENC_CLASS(G_OBJECT_GET_CLASS(vpu_base_enc)); g_assert(klass->set_open_params != NULL); g_assert(klass->get_output_caps != NULL); /* Close old encoder instance */ gst_fsl_vpu_base_enc_close_encoder(vpu_base_enc); /* Clean up existing framebuffers structure; * if some previous and still existing buffer pools depend on this framebuffers * structure, they will extend its lifetime, since they ref'd it */ if (vpu_base_enc->framebuffers != NULL) { gst_object_unref(vpu_base_enc->framebuffers); vpu_base_enc->framebuffers = NULL; } if (vpu_base_enc->output_phys_buffer != NULL) { gst_allocator_free(gst_fsl_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer)); vpu_base_enc->output_phys_buffer = NULL; } memset(&(vpu_base_enc->open_param), 0, sizeof(VpuEncOpenParam)); /* These params are usually not set by derived classes */ vpu_base_enc->open_param.nPicWidth = GST_VIDEO_INFO_WIDTH(&(state->info)); vpu_base_enc->open_param.nPicHeight = GST_VIDEO_INFO_HEIGHT(&(state->info)); vpu_base_enc->open_param.nFrameRate = (GST_VIDEO_INFO_FPS_N(&(state->info)) & 0xffffUL) | (((GST_VIDEO_INFO_FPS_D(&(state->info)) - 1) & 0xffffUL) << 16); vpu_base_enc->open_param.sMirror = VPU_ENC_MIRDIR_NONE; /* don't use VPU rotation (IPU has better performance) */ vpu_base_enc->open_param.nBitRate = vpu_base_enc->bitrate; vpu_base_enc->open_param.nGOPSize = vpu_base_enc->gop_size; vpu_base_enc->open_param.nUserGamma = (int)(32768 * vpu_base_enc->qp_smoothing); vpu_base_enc->open_param.nAvcIntra16x16OnlyModeEnable = vpu_base_enc->intra_16x16_only ? 1 : 0; vpu_base_enc->open_param.nRcIntervalMode = 1; /* These params are defaults, and are often overwritten by derived classes */ vpu_base_enc->open_param.nUserQpMax = -1; vpu_base_enc->open_param.nUserQpMin = -1; vpu_base_enc->open_param.nRcIntraQp = -1; GST_DEBUG_OBJECT(vpu_base_enc, "setting bitrate to %u kbps and GOP size to %u", vpu_base_enc->open_param.nBitRate, vpu_base_enc->open_param.nGOPSize); /* Give the derived class a chance to set params */ if (!klass->set_open_params(vpu_base_enc, &(vpu_base_enc->open_param))) { GST_ERROR_OBJECT(vpu_base_enc, "derived class could not set open params"); return FALSE; } /* The actual initialization; requires bitstream information (such as the codec type), which * is determined by the fill_param_set call before */ ret = VPU_EncOpen(&(vpu_base_enc->handle), &(vpu_base_enc->mem_info), &(vpu_base_enc->open_param)); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "opening new VPU handle failed: %s", gst_fsl_vpu_strerror(ret)); return FALSE; } vpu_base_enc->vpu_inst_opened = TRUE; /* configure AFTER setting vpu_inst_opened to TRUE, to make sure that in case of config failure the VPU handle is closed in the finalizer */ ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_NONE, NULL); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "could not apply default configuration: %s", gst_fsl_vpu_strerror(ret)); return FALSE; } ret = VPU_EncGetInitialInfo(vpu_base_enc->handle, &(vpu_base_enc->init_info)); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "retrieving init info failed: %s", gst_fsl_vpu_strerror(ret)); return FALSE; } /* Framebuffers are created in handle_frame(), to make sure the actual stride is used */ /* Set the output state, using caps defined by the derived class */ output_state = gst_video_encoder_set_output_state( encoder, klass->get_output_caps(vpu_base_enc), state ); gst_video_codec_state_unref(output_state); vpu_base_enc->video_info = state->info; return TRUE; }
static gboolean gst_imx_vpu_base_enc_set_format(GstVideoEncoder *encoder, GstVideoCodecState *state) { VpuEncRetCode ret; GstVideoCodecState *output_state; GstImxVpuBaseEncClass *klass; GstImxVpuBaseEnc *vpu_base_enc; int param; vpu_base_enc = GST_IMX_VPU_BASE_ENC(encoder); klass = GST_IMX_VPU_BASE_ENC_CLASS(G_OBJECT_GET_CLASS(vpu_base_enc)); g_assert(klass->set_open_params != NULL); g_assert(klass->get_output_caps != NULL); /* Close old encoder instance */ gst_imx_vpu_base_enc_close_encoder(vpu_base_enc); /* Clean up existing framebuffers structure; * if some previous and still existing buffer pools depend on this framebuffers * structure, they will extend its lifetime, since they ref'd it */ if (vpu_base_enc->framebuffers != NULL) { gst_object_unref(vpu_base_enc->framebuffers); vpu_base_enc->framebuffers = NULL; } if (vpu_base_enc->output_phys_buffer != NULL) { gst_allocator_free(gst_imx_vpu_enc_allocator_obtain(), (GstMemory *)(vpu_base_enc->output_phys_buffer)); vpu_base_enc->output_phys_buffer = NULL; } memset(&(vpu_base_enc->open_param), 0, sizeof(VpuEncOpenParam)); /* These params are usually not set by derived classes */ vpu_base_enc->open_param.nPicWidth = GST_VIDEO_INFO_WIDTH(&(state->info)); vpu_base_enc->open_param.nPicHeight = GST_VIDEO_INFO_HEIGHT(&(state->info)); vpu_base_enc->open_param.nFrameRate = (GST_VIDEO_INFO_FPS_N(&(state->info)) & 0xffffUL) | (((GST_VIDEO_INFO_FPS_D(&(state->info)) - 1) & 0xffffUL) << 16); vpu_base_enc->open_param.sMirror = VPU_ENC_MIRDIR_NONE; /* don't use VPU mirroring (IPU has better performance) */ vpu_base_enc->open_param.nBitRate = vpu_base_enc->bitrate; vpu_base_enc->open_param.nGOPSize = vpu_base_enc->gop_size; GST_INFO_OBJECT(vpu_base_enc, "setting bitrate to %u kbps and GOP size to %u", vpu_base_enc->open_param.nBitRate, vpu_base_enc->open_param.nGOPSize); /* These are default settings from VPU_EncOpenSimp */ vpu_base_enc->open_param.sliceMode.sliceMode = 0; /* 1 slice per picture */ vpu_base_enc->open_param.sliceMode.sliceSizeMode = 0; /* sliceSize is bits */ vpu_base_enc->open_param.sliceMode.sliceSize = 4000; vpu_base_enc->open_param.nRcIntraQp = -1; vpu_base_enc->open_param.nUserGamma = 0.75 * 32768; if (vpu_base_enc->slice_size) { vpu_base_enc->open_param.sliceMode.sliceMode = 1; /* 0: 1 slice per picture; 1: Multiple slices per picture */ if (vpu_base_enc->slice_size < 0) { vpu_base_enc->open_param.sliceMode.sliceSizeMode = 1; /* 1: sliceSize defined by MB number*/ vpu_base_enc->open_param.sliceMode.sliceSize = -vpu_base_enc->slice_size; /* Size of a slice in MB numbers */ } else { vpu_base_enc->open_param.sliceMode.sliceSizeMode = 0; /* 1: sliceSize defined by bits */ vpu_base_enc->open_param.sliceMode.sliceSize = vpu_base_enc->slice_size; /* Size of a slice in bits */ } } vpu_base_enc->open_param.nIntraRefresh = vpu_base_enc->intra_refresh; /* Give the derived class a chance to set params */ if (!klass->set_open_params(vpu_base_enc, state, &(vpu_base_enc->open_param))) { GST_ERROR_OBJECT(vpu_base_enc, "derived class could not set open params"); return FALSE; } /* The actual initialization; requires bitstream information (such as the codec type), which * is determined by the fill_param_set call before */ ret = VPU_EncOpen(&(vpu_base_enc->handle), &(vpu_base_enc->mem_info), &(vpu_base_enc->open_param)); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "opening new VPU handle failed: %s", gst_imx_vpu_strerror(ret)); return FALSE; } vpu_base_enc->vpu_inst_opened = TRUE; /* configure AFTER setting vpu_inst_opened to TRUE, to make sure that in case of config failure the VPU handle is closed in the finalizer */ if (vpu_base_enc->bitrate != 0) { param = vpu_base_enc->bitrate; ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_BIT_RATE, ¶m); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "could not configure bitrate: %s", gst_imx_vpu_strerror(ret)); return FALSE; } } if (vpu_base_enc->intra_refresh != 0) { param = vpu_base_enc->intra_refresh; ret = VPU_EncConfig(vpu_base_enc->handle, VPU_ENC_CONF_INTRA_REFRESH, ¶m); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "could not configure intra refresh period: %s", gst_imx_vpu_strerror(ret)); return FALSE; } } ret = VPU_EncGetInitialInfo(vpu_base_enc->handle, &(vpu_base_enc->init_info)); if (ret != VPU_ENC_RET_SUCCESS) { GST_ERROR_OBJECT(vpu_base_enc, "retrieving init info failed: %s", gst_imx_vpu_strerror(ret)); return FALSE; } /* Framebuffers are created in handle_frame(), to make sure the actual stride is used */ /* Set the output state, using caps defined by the derived class */ output_state = gst_video_encoder_set_output_state( encoder, klass->get_output_caps(vpu_base_enc), state ); gst_video_codec_state_unref(output_state); vpu_base_enc->video_info = state->info; return TRUE; }
int32_t encoder_open(struct encode *enc) { EncHandle handle = { 0 }; EncOpenParam encop = { 0 }; RetCode ret; /* Fill up parameters for encoding */ encop.bitstreamBuffer = enc->phy_bsbuf_addr; encop.bitstreamBufferSize = STREAM_BUF_SIZE; encop.bitstreamFormat = enc->codecctrl->format; encop.mapType = enc->codecctrl->mapType; encop.linear2TiledEnable = enc->linear2TiledEnable; /* width and height in command line means source image size */ if (enc->codecctrl->width && enc->codecctrl->height) { enc->src_picwidth = enc->codecctrl->width; enc->src_picheight = enc->codecctrl->height; } /* enc_width and enc_height in command line means encoder output size */ if (enc->codecctrl->enc_width && enc->codecctrl->enc_height) { enc->enc_picwidth = enc->codecctrl->enc_width; enc->enc_picheight = enc->codecctrl->enc_height; } else { enc->enc_picwidth = enc->src_picwidth; enc->enc_picheight = enc->src_picheight; } /* If rotation angle is 90 or 270, pic width and height are swapped */ if (enc->codecctrl->rot_angle == 90 || enc->codecctrl->rot_angle == 270) { encop.picWidth = enc->enc_picheight; encop.picHeight = enc->enc_picwidth; } else { encop.picWidth = enc->enc_picwidth; encop.picHeight = enc->enc_picheight; } /*Note: Frame rate cannot be less than 15fps per H.263 spec */ encop.frameRateInfo = frameRateInfo = 30; encop.bitRate = enc->codecctrl->bitrate; encop.gopSize = enc->codecctrl->gop; encop.slicemode.sliceMode = 0; /* 0: 1 slice per picture; 1: Multiple slices per picture */ encop.slicemode.sliceSizeMode = 0; /* 0: silceSize defined by bits; 1: sliceSize defined by MB number */ encop.slicemode.sliceSize = 4000; /* Size of a slice in bits or MB numbers */ encop.initialDelay = 0; encop.vbvBufferSize = 0; /* 0 = ignore 8 */ encop.intraRefresh = 0; encop.sliceReport = 0; encop.mbReport = 0; encop.mbQpReport = 0; encop.rcIntraQp = -1; encop.userQpMax = 0; encop.userQpMin = 0; encop.userQpMinEnable = 0; encop.userQpMaxEnable = 0; encop.IntraCostWeight = 0; encop.MEUseZeroPmv = 0; /* (3: 16x16, 2:32x16, 1:64x32, 0:128x64, H.263(Short Header : always 3) */ encop.MESearchRange = 3; encop.userGamma = (uint32_t) (0.75 * 32768); /* (0*32768 <= gamma <= 1*32768) */ encop.RcIntervalMode = 1; /* 0:normal, 1:frame_level, 2:slice_level, 3: user defined Mb_level */ encop.MbInterval = 0; encop.avcIntra16x16OnlyModeEnable = 0; encop.ringBufferEnable = enc->ringBufferEnable = 0; encop.dynamicAllocEnable = 0; encop.chromaInterleave = enc->codecctrl->chromaInterleave; if (enc->codecctrl->format == STD_MPEG4) { encop.EncStdParam.mp4Param.mp4_dataPartitionEnable = 0; enc->mp4_dataPartitionEnable = encop.EncStdParam.mp4Param.mp4_dataPartitionEnable; encop.EncStdParam.mp4Param.mp4_reversibleVlcEnable = 0; encop.EncStdParam.mp4Param.mp4_intraDcVlcThr = 0; encop.EncStdParam.mp4Param.mp4_hecEnable = 0; encop.EncStdParam.mp4Param.mp4_verid = 2; } else if (enc->codecctrl->format == STD_H263) { encop.EncStdParam.h263Param.h263_annexIEnable = 0; encop.EncStdParam.h263Param.h263_annexJEnable = 1; encop.EncStdParam.h263Param.h263_annexKEnable = 0; encop.EncStdParam.h263Param.h263_annexTEnable = 0; } else if (enc->codecctrl->format == STD_AVC) { encop.EncStdParam.avcParam.avc_constrainedIntraPredFlag = 0; encop.EncStdParam.avcParam.avc_disableDeblk = 1; encop.EncStdParam.avcParam.avc_deblkFilterOffsetAlpha = 6; encop.EncStdParam.avcParam.avc_deblkFilterOffsetBeta = 0; encop.EncStdParam.avcParam.avc_chromaQpOffset = 10; encop.EncStdParam.avcParam.avc_audEnable = 0; if (cpu_is_mx6()) { encop.EncStdParam.avcParam.interview_en = 0; encop.EncStdParam.avcParam.paraset_refresh_en = enc->mvc_paraset_refresh_en = 0; encop.EncStdParam.avcParam.prefix_nal_en = 0; encop.EncStdParam.avcParam.mvc_extension = enc->codecctrl->mp4_h264Class; enc->mvc_extension = enc->codecctrl->mp4_h264Class; encop.EncStdParam.avcParam.avc_frameCroppingFlag = 0; encop.EncStdParam.avcParam.avc_frameCropLeft = 0; encop.EncStdParam.avcParam.avc_frameCropRight = 0; encop.EncStdParam.avcParam.avc_frameCropTop = 0; encop.EncStdParam.avcParam.avc_frameCropBottom = 0; if (enc->codecctrl->rot_angle != 90 && enc->codecctrl->rot_angle != 270 && enc->enc_picheight == 1080) { /* * In case of AVC encoder, when we want to use * unaligned display width frameCroppingFlag * parameters should be adjusted to displayable * rectangle */ encop.EncStdParam.avcParam.avc_frameCroppingFlag = 1; encop.EncStdParam.avcParam.avc_frameCropBottom = 8; } } else { encop.EncStdParam.avcParam.avc_fmoEnable = 0; encop.EncStdParam.avcParam.avc_fmoType = 0; encop.EncStdParam.avcParam.avc_fmoSliceNum = 1; encop.EncStdParam.avcParam.avc_fmoSliceSaveBufSize = 32; /* FMO_SLICE_SAVE_BUF_SIZE */ } } ret = VPU_EncOpen(&handle, &encop); if (ret != RETCODE_SUCCESS) { err_msg("Encoder open failed %d\n", ret); return -1; } enc->handle = handle; return 0; }
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; }