VPU硬编码
平台是RK3066(福州瑞芯微公司),android 4.2.0,其实时VP8硬编码,与软件编码是ffpmeg,x264,xvid等软编码是有区别的。硬编码主要是依赖于
硬件。
硬编码:通过调用Android系统自带的Camera录制视频,实际上是调用了底层的高清编码硬件模块,也即显卡,不使用CPU,速度快
软编码:使用CPU进行编码,如常见C/C++代码,一般编译生成的二进制都是的,速度相对较慢。例如使用Android NDK编译H264生成so库,编写jni接口,再使用java调用so库
VPUCoder.h
- /*
- * VPUCoder.h
- *
- * Current, Only Support YUV420sp encoder and decoder
- *
- * Created on: Dec 16, 2013
- * Author: henry
- *
- * Example:
- *
- * int main()
- * {
- * int ret = InitCodec();
- * //===========encode video
- * ret = StartEnc("/sdcard/test.mkv", 1280, 720, 30);
- *
- * while(1)
- * {
- * //get data and length, //unsigned char* data; int length
- * ret = ProcessEnc(data, length);
- * }
- * ret = StopEnc();
- *
- * //===========decode video
- * ret = ProcessDec("/sdcard/test.mkv", 1280, 720);
- * return 0;
- * }
- */
- #ifndef VPUCODER_H_
- #define VPUCODER_H_
- /**
- * Init encoder and decoder handle, only call once, must first call
- *
- * @return 0 is successful, another fail
- */
- int InitCodec();
- /**
- * setup encoder configure
- * @param filePath : save file path
- * @param enc_width : video width
- * @param enc_height : video height
- * @param enc_fps : video fps
- *
- * @return 0 is successful, another fail
- */
- int StartEnc(const char* filePath, uint32_t enc_width, uint32_t enc_height, uint32_t enc_fps);
- /**
- * stop encode video
- */
- void StopEnc();
- /**
- * @params data : frame data
- * @params length : frame length
- *
- * @return 0 is successful, another fail
- */
- int ProcessEnc(const unsigned char* data, uint32_t length);
- /**
- * setup decoder configure
- * @param filePath : source file path
- * @param enc_width : video width
- * @param enc_height : video height
- *
- * @return 0 is successful, another fail
- */
- int ProcessDec(const char* filePath, uint32_t dec_width, uint32_t dec_height);
- #endif /* VPUCODER_H_ */
VPUCoder.cpp
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <vpu_global.h>
- #include <SoftwareRenderer.h>
- #include <vpu_api_interface.h>
- #include <utils/Log.h>
- #include <ui/DisplayInfo.h>
- #include <gui/ISurfaceTexture.h>
- #include <gui/ISurfaceComposer.h>
- #include <gui/SurfaceTextureClient.h>
- #include <gui/SurfaceComposerClient.h>
- #include <media/stagefright/MetaData.h>
- using namespace android;
- #ifdef LOGI
- #undef LOGI
- #undef LOGW
- #undef LOGE
- #undef LOGD
- #endif
- #define LOG_TAG_SERVICE "TeliDHVPU8Codec"
- #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG_SERVICE, __VA_ARGS__)
- #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_SERVICE, __VA_ARGS__)
- #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG_SERVICE, __VA_ARGS__)
- #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG_SERVICE, __VA_ARGS__)
- #define MAX_STREM_LENGTH (1280 * 400)
- static uint32_t g_lenght_enc = MAX_STREM_LENGTH;
- static FILE* g_file_enc = NULL;
- static FILE* g_file_dec = NULL;
- static VPU_API g_vpu_api;
- static void* g_vp8encHandle = NULL;
- static void* g_vp8decHandle = NULL;
- static unsigned int g_bufferLen = 0;
- static unsigned char* g_frameBuffer = NULL;
- static EncParams1 g_encParams;
- static int g_SyncFlag = 0;
- static unsigned int g_dataSize;
- static unsigned int g_InputTimestamp;
- static int g_nal = 0;
- static int g_ret = 0;
- int InitCodec()
- {
- vpu_api_init(&g_vpu_api, OMX_ON2_VIDEO_CodingVPX);
- return 0;
- }
- int StartEnc(const char* filePath, uint32_t enc_width, uint32_t enc_height, uint32_t enc_fps)
- {
- LOGI("StartEnc Begin ====================");
- if(!filePath)
- {
- LOGD("Please make sure file path not null!");
- return -1;
- }
- if(g_file_enc)
- {
- LOGD("Another file is being encoded!");
- return -1;
- }
- g_file_enc = fopen(filePath, "wb+");
- if(!g_file_enc)
- {
- LOGD("file open fail!");
- return -1;
- }
- g_lenght_enc = enc_width * enc_height * 3 >> 1;
- memset(&g_encParams, 0, sizeof(EncParams1));
- g_encParams.width = enc_width;
- g_encParams.height = enc_height;
- g_encParams.framerate = 25;
- g_encParams.bitRate = 10000;
- g_frameBuffer = (unsigned char*)malloc(MAX_STREM_LENGTH);
- g_vp8encHandle = g_vpu_api.get_class_On2Encoder();
- g_vpu_api.init_class_On2Encoder(g_vp8encHandle, &g_encParams, g_frameBuffer, &g_bufferLen);
- g_nal = g_bufferLen;
- fwrite(&g_nal, 1, sizeof(g_nal), g_file_enc);
- fwrite(g_frameBuffer, 1, g_bufferLen, g_file_enc);
- LOGI("StartEnc End g_bufferLen = %d ====================", g_bufferLen);
- return 0;
- }
- void StopEnc()
- {
- LOGI("StartEnc Begin ====================");
- g_lenght_enc = 0;
- if(g_frameBuffer)
- {
- free(g_frameBuffer);
- g_frameBuffer = NULL;
- }
- if(g_file_enc)
- {
- fclose(g_file_enc);
- g_file_enc = NULL;
- }
- if(g_vp8encHandle)
- {
- g_vpu_api.deinit_class_On2Encoder(g_vp8encHandle);
- g_vpu_api.destroy_class_On2Encoder(g_vp8encHandle);
- g_vp8encHandle = NULL;
- }
- LOGI("StartEnc End ====================");
- }
- int ProcessEnc(const unsigned char* data, uint32_t length)
- {
- if(length != g_lenght_enc)
- {
- LOGD("encode frame length is error!");
- StopEnc();
- return -1;
- }
- if(!g_file_enc)
- {
- LOGD("file not open!");
- return -1;
- }
- LOGD("enc_oneframe_class_On2AvcEncoder");
- g_SyncFlag = 0;
- g_ret = g_vpu_api.enc_oneframe_class_On2Encoder(g_vp8encHandle, g_frameBuffer, &g_bufferLen
- , (unsigned char*)data, 0, &g_dataSize, &g_InputTimestamp, &g_SyncFlag);
- if(g_bufferLen > 0 && g_ret >=0)
- {
- LOGI("ProcessEnc encode one frame ====================");
- g_nal = g_bufferLen;
- fwrite(&g_nal, 1, sizeof(g_nal), g_file_enc);
- fwrite(g_frameBuffer, 1, g_bufferLen, g_file_enc);
- fflush(g_file_enc);
- }
- else
- {
- LOGD("ProcessEnc encode frame fail!");
- return -1;
- }
- g_bufferLen = 0;
- return 0;
- }
- int32_t FillFrameHead(unsigned char* dst, unsigned char* src, uint32_t size
- , uint32_t bitsreamLen, int64_t time, uint32_t type, uint32_t num)
- {
- VPU_BITSTREAM h;
- uint32_t TimeLow = (uint32_t)(time/1000);
- h.StartCode = BSWAP(VPU_BITSTREAM_START_CODE);
- h.SliceLength= BSWAP(size);
- h.SliceTime.TimeLow = BSWAP(TimeLow);
- h.SliceTime.TimeHigh= 0;
- h.SliceType= BSWAP(type);
- h.SliceNum= BSWAP(num);
- h.Res[0] = 0;
- h.Res[1] = 0;
- memcpy(dst, &h, bitsreamLen);
- return 0;
- }
- int ProcessDec(const char* filePath, uint32_t dec_width, uint32_t dec_height)
- {
- LOGI("ProcessDec Begin dec_width = %d dec_height = %d====================", dec_width, dec_height);
- if(!filePath)
- {
- LOGD("src file path is null");
- return -1;
- }
- FILE *fp_in = fopen(filePath, "rb");
- if(!fp_in)
- {
- LOGD("File not exist!");
- return -1;
- }
- char filePathOut[64];
- memset(filePathOut, 0, 64);
- sprintf(filePathOut, "%s.yuv", filePath);
- g_file_dec = fopen(filePathOut, "wb+");
- if(!g_file_dec)
- {
- LOGD("file open fail!");
- fclose(fp_in);
- return -1;
- }
- unsigned char* aOutBuffer;
- unsigned char* aInputBuf = NULL;
- unsigned char* aInputData = NULL;
- unsigned int aOutputLength;
- unsigned int aInBufSize = MAX_STREM_LENGTH;
- g_vp8decHandle = g_vpu_api.get_class_On2Decoder();
- g_vpu_api.init_class_On2Decoder(g_vp8decHandle);
- int tmp_length = (dec_width * dec_height * 3) >> 1;
- LOGI(" init_class_On2AvcDecoder OK! tmp_length=%d", tmp_length);
- aOutBuffer = (unsigned char*)malloc(tmp_length);
- aInputBuf = (unsigned char*)malloc(MAX_STREM_LENGTH);
- fread(&g_nal, 1, sizeof(g_nal), fp_in);
- if(g_nal > 0)
- {
- fread(aInputBuf, 1, g_nal, fp_in);
- }
- else
- {
- LOGD("Can't decoder the video!");
- goto fail;
- }
- int ret;
- uint32_t bitsLen;
- uint32_t vpu_stream_lenc;
- vpu_stream_lenc = sizeof(VPU_BITSTREAM);
- aInputData = aInputBuf + vpu_stream_lenc;
- while(1)
- {
- ret = fread(&g_nal, 1, sizeof(g_nal), fp_in);
- if(ret <= 0)
- break;
- fread(aInputData, 1, g_nal, fp_in);
- aInBufSize = g_nal;
- bitsLen = vpu_stream_lenc + aInBufSize;
- FillFrameHead(aInputBuf, aInputData, aInBufSize, vpu_stream_lenc, 0, 0, 0);
- ret = g_vpu_api.dec_oneframe_class_On2Decoder(g_vp8decHandle, aOutBuffer, &aOutputLength, aInputBuf, &bitsLen);
- LOGI("out_length=%d in_length=%d ret=%d", aOutputLength, bitsLen, ret);
- if(aOutputLength > 0)
- {
- VPU_FRAME *frame = (VPU_FRAME *)aOutBuffer;
- if(frame->vpumem.phy_addr)
- {
- VPUMemLink(&frame->vpumem);
- if(frame->vpumem.vir_addr)
- {
- LOGI("VPUMemLinear_t size=%d", frame->vpumem.size);
- fwrite(frame->vpumem.vir_addr, 1, tmp_length, g_file_dec);
- fflush(g_file_dec);
- }
- else
- {
- LOGI("vir_addr is null");
- }
- VPUFreeLinear(&frame->vpumem);
- }
- else
- {
- LOGI("phy_addr is null");
- }
- }
- fflush(fp_in);
- }
- fail:
- if(aOutBuffer)
- {
- free(aOutBuffer);
- aOutBuffer = NULL;
- }
- if(aInputBuf)
- {
- free(aInputBuf);
- aInputBuf = NULL;
- }
- if(g_file_dec)
- {
- fclose(g_file_dec);
- g_file_dec = NULL;
- }
- if(fp_in)
- {
- fclose(fp_in);
- fp_in = NULL;
- }
- if(g_vp8decHandle)
- {
- g_vpu_api.deinit_class_On2Decoder(g_vp8decHandle);
- g_vpu_api.destroy_class_On2Decoder(g_vp8decHandle);
- g_vp8decHandle = NULL;
- }
- LOGI("ProcessDec End ====================");
- return 0;
- }
android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
VISION=1.0.1
LOCAL_MODULE := VPU8Coder_${VISION}
LOCAL_SRC_FILES := VPUCoder.cpp
LOCAL_LDLIBS := -L$(LOCAL_PATH)/libs \
-lvpu \
-lcutils \
-lutils \
-lgui \
-lrk_on2 \
-lstagefright
LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE) \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/include/media/openmax
LOCAL_CFLAGS := -DOSCL_IMPORT_REF= -DOSCL_UNUSED_ARG= -DOSCL_EXPORT_REF=
include $(BUILD_SHARED_LIBRARY)
VPU硬编码的更多相关文章
- Android安全开发之浅谈密钥硬编码
Android安全开发之浅谈密钥硬编码 作者:伊樵.呆狐@阿里聚安全 1 简介 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码.文件中,这样做会引起很大风 ...
- 使用VideoToolbox硬编码H.264<转>
文/落影loyinglin(简书作者)原文链接:http://www.jianshu.com/p/37784e363b8a著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. ======= ...
- 【Android】Android Camera实时数据采集及通过MediaCodec硬编码编码数据的流程
吐槽: 其实常用流程都差不多,但是有时候还是会忘记某一步的详细用法,但是各位朋友请注意,官方已经不推荐Camera类的使用(现在是android.hardware.camera2),但无奈公司项目之前 ...
- android studio 中查找代码中的硬编码
在Android Studio中同时按下Ctrl + Shift+ F 或者其他自定义的快捷键,打开全局搜索,在全局搜索中输入 ^((?!(\*|//)).)+[\u4e00-\u9fa5] 并打勾 ...
- 【GPU编解码】GPU硬编码
一.OpenCV中的硬编码 OpenCV2.4.6中,已实现利用GPU进行写视频,编码过程由cv::gpu::VideoWriter_GPU完成,其示例程序如下. int main(int argc, ...
- 告别硬编码-发个获取未导出函数地址的Dll及源码
还在为找内核未导出函数地址而苦恼嘛? 还在为硬编码通用性差而不爽吗? 还在为暴搜内核老蓝屏而痛苦吗? 请看这里: 最近老要用到内核未导出的函数及一些结构,不想再找特征码了,准备到网上找点符号文件解析的 ...
- 【流媒体】 Android 实时视频编码—H.264硬编码
[流媒體] Android 实时视频编码—H.264硬编码 SkySeraph Apr 4th 2012 Email:skyseraph00@163.com 1 硬编码 & 软编码 硬编码: ...
- ExpressionTree——让反射性能向硬编码看齐
缘起 最近又换了工作.然后开心是以后又能比较频繁的关注博客园了.办离职手续的这一个月梳理了下近一年自己写的东西,然后就有了此文以及附带的代码. 反射 关于反射,窃以为,他只是比较慢.在这个前提下,个人 ...
- 硬编码写RadioGroup的时候要注意设置RadioButton的Id
硬编码写RadioGroup的时候要注意RadioButton的id重复问题,导致选择的时候出现能够多选的情况发生,如下代码,注意Id的设置,这样避免Radiobutton的id重复. /** * 生 ...
随机推荐
- 09--c++ 类的继承与派生
c++ 类的继承与派生 一.基本概念 1.类的继承,是新的类从已有类那里得到已有的特性.或从已有类产生新类的过程就是类的派生.原有的类称为基类或父类,产生的新类称为派生类或子类. 2.派生类的 ...
- mac 上执行 rm -rf /
# 很可怕的指令,清空磁盘所有资料,千万不要用 sudo 尝试,吓的小心肝差掉跳出来 rm -rf / 无聊,想执行rm -rf /会怎样,想起没加sudo时对~/download执行提示权限不足,被 ...
- jsTree checkbox plugin使用笔记
引入css文件 <link rel="stylesheet" type="text/css" href="js/assets/global/pl ...
- BZOJ 4278: [ONTAK2015]Tasowanie 后缀数组 + 贪心 + 细节
Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin ...
- vfs:open.c 源码学习
nameidata路径查找辅助结构 open.c @do_sys_open @get_unused_fd_flags @do_filp_open 1.开始填充nameidata 2.开始填充file ...
- vue-router 懒加载
懒加载:也叫延迟加载,即在需要的时候进行加载,按需加载. 那vue 为什么需要懒加载呢? 使用 vue-cli构建的项目,在默认情况下,执行 npm run build 会将所有的 js代码打包为一 ...
- Windows Server 2008 R2x64 IIS7+PHP5.6 错误 500.0
这两天准备升级一个网站项目,新项目基于PHP并进行了ZendGuard加密,需要在PHP5.6版本中运行 而客户之前的运行环境是php5.2~5.4,那好,再新建一个PHP版本不就完事了吗!!! 于是 ...
- D2007从win7升级到win10下的莫名其妙问题。
在win7下听说win10被推荐,于是升级到win10.结果使用d2007不能打开,出现莫名其妙的错误.把bin\bds.exe改名bds1.exe后居然可以启动了.一番折腾后,这把bds1.exe改 ...
- 解决ExpressSpreadSheet 中文乱码问题[备查]
cxSpreadSheet和F1Book等都提供了类似Excel的操作, 但是相比F1Book, cxSpreadSheet的中文支持还不是很完善.在设置了wordbreak为true的时候,里面的中 ...
- mongodb--reduce并行处理框架
reduce 命令 db.runCommand( { mapReduce: <collection>, map: <function>, reduce: <functio ...