平台是RK3066(福州瑞芯微公司),android 4.2.0,其实时VP8硬编码,与软件编码是ffpmeg,x264,xvid等软编码是有区别的。硬编码主要是依赖于
硬件。

  硬编码:通过调用Android系统自带的Camera录制视频,实际上是调用了底层的高清编码硬件模块,也即显卡,不使用CPU,速度快
  软编码:使用CPU进行编码,如常见C/C++代码,一般编译生成的二进制都是的,速度相对较慢。例如使用Android NDK编译H264生成so库,编写jni接口,再使用java调用so库
VPUCoder.h

  1. /*
  2. * VPUCoder.h
  3. *
  4. * Current, Only Support YUV420sp encoder and decoder
  5. *
  6. * Created on: Dec 16, 2013
  7. * Author: henry
  8. *
  9. * Example:
  10. *
  11. * int main()
  12. * {
  13. * int ret = InitCodec();
  14. * //===========encode video
  15. * ret = StartEnc("/sdcard/test.mkv", 1280, 720, 30);
  16. *
  17. * while(1)
  18. * {
  19. * //get data and length, //unsigned char* data; int length
  20. * ret = ProcessEnc(data, length);
  21. * }
  22. * ret = StopEnc();
  23. *
  24. * //===========decode video
  25. * ret = ProcessDec("/sdcard/test.mkv", 1280, 720);
  26. * return 0;
  27. * }
  28. */
  29.  
  30. #ifndef VPUCODER_H_
  31. #define VPUCODER_H_
  32.  
  33. /**
  34. * Init encoder and decoder handle, only call once, must first call
  35. *
  36. * @return 0 is successful, another fail
  37. */
  38. int InitCodec();
  39.  
  40. /**
  41. * setup encoder configure
  42. * @param filePath : save file path
  43. * @param enc_width : video width
  44. * @param enc_height : video height
  45. * @param enc_fps : video fps
  46. *
  47. * @return 0 is successful, another fail
  48. */
  49. int StartEnc(const char* filePath, uint32_t enc_width, uint32_t enc_height, uint32_t enc_fps);
  50.  
  51. /**
  52. * stop encode video
  53. */
  54. void StopEnc();
  55.  
  56. /**
  57. * @params data : frame data
  58. * @params length : frame length
  59. *
  60. * @return 0 is successful, another fail
  61. */
  62. int ProcessEnc(const unsigned char* data, uint32_t length);
  63.  
  64. /**
  65. * setup decoder configure
  66. * @param filePath : source file path
  67. * @param enc_width : video width
  68. * @param enc_height : video height
  69. *
  70. * @return 0 is successful, another fail
  71. */
  72. int ProcessDec(const char* filePath, uint32_t dec_width, uint32_t dec_height);
  73.  
  74. #endif /* VPUCODER_H_ */

  VPUCoder.cpp

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4.  
  5. #include <vpu_global.h>
  6. #include <SoftwareRenderer.h>
  7. #include <vpu_api_interface.h>
  8.  
  9. #include <utils/Log.h>
  10. #include <ui/DisplayInfo.h>
  11. #include <gui/ISurfaceTexture.h>
  12. #include <gui/ISurfaceComposer.h>
  13. #include <gui/SurfaceTextureClient.h>
  14. #include <gui/SurfaceComposerClient.h>
  15. #include <media/stagefright/MetaData.h>
  16.  
  17. using namespace android;
  18.  
  19. #ifdef LOGI
  20. #undef LOGI
  21. #undef LOGW
  22. #undef LOGE
  23. #undef LOGD
  24. #endif
  25.  
  26. #define LOG_TAG_SERVICE "TeliDHVPU8Codec"
  27. #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG_SERVICE, __VA_ARGS__)
  28. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG_SERVICE, __VA_ARGS__)
  29. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG_SERVICE, __VA_ARGS__)
  30. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG_SERVICE, __VA_ARGS__)
  31.  
  32. #define MAX_STREM_LENGTH (1280 * 400)
  33.  
  34. static uint32_t g_lenght_enc = MAX_STREM_LENGTH;
  35. static FILE* g_file_enc = NULL;
  36. static FILE* g_file_dec = NULL;
  37. static VPU_API g_vpu_api;
  38. static void* g_vp8encHandle = NULL;
  39. static void* g_vp8decHandle = NULL;
  40. static unsigned int g_bufferLen = 0;
  41. static unsigned char* g_frameBuffer = NULL;
  42.  
  43. static EncParams1 g_encParams;
  44. static int g_SyncFlag = 0;
  45. static unsigned int g_dataSize;
  46. static unsigned int g_InputTimestamp;
  47. static int g_nal = 0;
  48. static int g_ret = 0;
  49.  
  50. int InitCodec()
  51. {
  52. vpu_api_init(&g_vpu_api, OMX_ON2_VIDEO_CodingVPX);
  53. return 0;
  54. }
  55.  
  56. int StartEnc(const char* filePath, uint32_t enc_width, uint32_t enc_height, uint32_t enc_fps)
  57. {
  58. LOGI("StartEnc Begin ====================");
  59. if(!filePath)
  60. {
  61. LOGD("Please make sure file path not null!");
  62. return -1;
  63. }
  64.  
  65. if(g_file_enc)
  66. {
  67. LOGD("Another file is being encoded!");
  68. return -1;
  69. }
  70.  
  71. g_file_enc = fopen(filePath, "wb+");
  72. if(!g_file_enc)
  73. {
  74. LOGD("file open fail!");
  75. return -1;
  76. }
  77.  
  78. g_lenght_enc = enc_width * enc_height * 3 >> 1;
  79.  
  80. memset(&g_encParams, 0, sizeof(EncParams1));
  81. g_encParams.width = enc_width;
  82. g_encParams.height = enc_height;
  83. g_encParams.framerate = 25;
  84. g_encParams.bitRate = 10000;
  85.  
  86. g_frameBuffer = (unsigned char*)malloc(MAX_STREM_LENGTH);
  87.  
  88. g_vp8encHandle = g_vpu_api.get_class_On2Encoder();
  89. g_vpu_api.init_class_On2Encoder(g_vp8encHandle, &g_encParams, g_frameBuffer, &g_bufferLen);
  90.  
  91. g_nal = g_bufferLen;
  92. fwrite(&g_nal, 1, sizeof(g_nal), g_file_enc);
  93. fwrite(g_frameBuffer, 1, g_bufferLen, g_file_enc);
  94.  
  95. LOGI("StartEnc End g_bufferLen = %d ====================", g_bufferLen);
  96.  
  97. return 0;
  98. }
  99.  
  100. void StopEnc()
  101. {
  102. LOGI("StartEnc Begin ====================");
  103. g_lenght_enc = 0;
  104. if(g_frameBuffer)
  105. {
  106. free(g_frameBuffer);
  107. g_frameBuffer = NULL;
  108. }
  109.  
  110. if(g_file_enc)
  111. {
  112. fclose(g_file_enc);
  113. g_file_enc = NULL;
  114. }
  115.  
  116. if(g_vp8encHandle)
  117. {
  118. g_vpu_api.deinit_class_On2Encoder(g_vp8encHandle);
  119. g_vpu_api.destroy_class_On2Encoder(g_vp8encHandle);
  120. g_vp8encHandle = NULL;
  121. }
  122. LOGI("StartEnc End ====================");
  123. }
  124.  
  125. int ProcessEnc(const unsigned char* data, uint32_t length)
  126. {
  127. if(length != g_lenght_enc)
  128. {
  129. LOGD("encode frame length is error!");
  130. StopEnc();
  131. return -1;
  132. }
  133.  
  134. if(!g_file_enc)
  135. {
  136. LOGD("file not open!");
  137. return -1;
  138. }
  139.  
  140. LOGD("enc_oneframe_class_On2AvcEncoder");
  141.  
  142. g_SyncFlag = 0;
  143. g_ret = g_vpu_api.enc_oneframe_class_On2Encoder(g_vp8encHandle, g_frameBuffer, &g_bufferLen
  144. , (unsigned char*)data, 0, &g_dataSize, &g_InputTimestamp, &g_SyncFlag);
  145.  
  146. if(g_bufferLen > 0 && g_ret >=0)
  147. {
  148. LOGI("ProcessEnc encode one frame ====================");
  149. g_nal = g_bufferLen;
  150. fwrite(&g_nal, 1, sizeof(g_nal), g_file_enc);
  151. fwrite(g_frameBuffer, 1, g_bufferLen, g_file_enc);
  152. fflush(g_file_enc);
  153. }
  154. else
  155. {
  156. LOGD("ProcessEnc encode frame fail!");
  157. return -1;
  158. }
  159. g_bufferLen = 0;
  160.  
  161. return 0;
  162. }
  163.  
  164. int32_t FillFrameHead(unsigned char* dst, unsigned char* src, uint32_t size
  165. , uint32_t bitsreamLen, int64_t time, uint32_t type, uint32_t num)
  166. {
  167. VPU_BITSTREAM h;
  168. uint32_t TimeLow = (uint32_t)(time/1000);
  169. h.StartCode = BSWAP(VPU_BITSTREAM_START_CODE);
  170. h.SliceLength= BSWAP(size);
  171. h.SliceTime.TimeLow = BSWAP(TimeLow);
  172. h.SliceTime.TimeHigh= 0;
  173. h.SliceType= BSWAP(type);
  174. h.SliceNum= BSWAP(num);
  175. h.Res[0] = 0;
  176. h.Res[1] = 0;
  177. memcpy(dst, &h, bitsreamLen);
  178.  
  179. return 0;
  180. }
  181.  
  182. int ProcessDec(const char* filePath, uint32_t dec_width, uint32_t dec_height)
  183. {
  184. LOGI("ProcessDec Begin dec_width = %d dec_height = %d====================", dec_width, dec_height);
  185. if(!filePath)
  186. {
  187. LOGD("src file path is null");
  188. return -1;
  189. }
  190.  
  191. FILE *fp_in = fopen(filePath, "rb");
  192. if(!fp_in)
  193. {
  194. LOGD("File not exist!");
  195. return -1;
  196. }
  197.  
  198. char filePathOut[64];
  199. memset(filePathOut, 0, 64);
  200. sprintf(filePathOut, "%s.yuv", filePath);
  201. g_file_dec = fopen(filePathOut, "wb+");
  202.  
  203. if(!g_file_dec)
  204. {
  205. LOGD("file open fail!");
  206. fclose(fp_in);
  207. return -1;
  208. }
  209.  
  210. unsigned char* aOutBuffer;
  211. unsigned char* aInputBuf = NULL;
  212. unsigned char* aInputData = NULL;
  213. unsigned int aOutputLength;
  214. unsigned int aInBufSize = MAX_STREM_LENGTH;
  215.  
  216. g_vp8decHandle = g_vpu_api.get_class_On2Decoder();
  217. g_vpu_api.init_class_On2Decoder(g_vp8decHandle);
  218.  
  219. int tmp_length = (dec_width * dec_height * 3) >> 1;
  220.  
  221. LOGI(" init_class_On2AvcDecoder OK! tmp_length=%d", tmp_length);
  222.  
  223. aOutBuffer = (unsigned char*)malloc(tmp_length);
  224. aInputBuf = (unsigned char*)malloc(MAX_STREM_LENGTH);
  225.  
  226. fread(&g_nal, 1, sizeof(g_nal), fp_in);
  227.  
  228. if(g_nal > 0)
  229. {
  230. fread(aInputBuf, 1, g_nal, fp_in);
  231. }
  232. else
  233. {
  234. LOGD("Can't decoder the video!");
  235. goto fail;
  236. }
  237.  
  238. int ret;
  239. uint32_t bitsLen;
  240. uint32_t vpu_stream_lenc;
  241.  
  242. vpu_stream_lenc = sizeof(VPU_BITSTREAM);
  243. aInputData = aInputBuf + vpu_stream_lenc;
  244.  
  245. while(1)
  246. {
  247. ret = fread(&g_nal, 1, sizeof(g_nal), fp_in);
  248. if(ret <= 0)
  249. break;
  250.  
  251. fread(aInputData, 1, g_nal, fp_in);
  252. aInBufSize = g_nal;
  253. bitsLen = vpu_stream_lenc + aInBufSize;
  254. FillFrameHead(aInputBuf, aInputData, aInBufSize, vpu_stream_lenc, 0, 0, 0);
  255.  
  256. ret = g_vpu_api.dec_oneframe_class_On2Decoder(g_vp8decHandle, aOutBuffer, &aOutputLength, aInputBuf, &bitsLen);
  257. LOGI("out_length=%d in_length=%d ret=%d", aOutputLength, bitsLen, ret);
  258.  
  259. if(aOutputLength > 0)
  260. {
  261. VPU_FRAME *frame = (VPU_FRAME *)aOutBuffer;
  262.  
  263. if(frame->vpumem.phy_addr)
  264. {
  265. VPUMemLink(&frame->vpumem);
  266.  
  267. if(frame->vpumem.vir_addr)
  268. {
  269. LOGI("VPUMemLinear_t size=%d", frame->vpumem.size);
  270. fwrite(frame->vpumem.vir_addr, 1, tmp_length, g_file_dec);
  271. fflush(g_file_dec);
  272. }
  273. else
  274. {
  275. LOGI("vir_addr is null");
  276. }
  277. VPUFreeLinear(&frame->vpumem);
  278. }
  279. else
  280. {
  281. LOGI("phy_addr is null");
  282. }
  283. }
  284. fflush(fp_in);
  285. }
  286.  
  287. fail:
  288. if(aOutBuffer)
  289. {
  290. free(aOutBuffer);
  291. aOutBuffer = NULL;
  292. }
  293.  
  294. if(aInputBuf)
  295. {
  296. free(aInputBuf);
  297. aInputBuf = NULL;
  298. }
  299.  
  300. if(g_file_dec)
  301. {
  302. fclose(g_file_dec);
  303. g_file_dec = NULL;
  304. }
  305.  
  306. if(fp_in)
  307. {
  308. fclose(fp_in);
  309. fp_in = NULL;
  310. }
  311.  
  312. if(g_vp8decHandle)
  313. {
  314. g_vpu_api.deinit_class_On2Decoder(g_vp8decHandle);
  315. g_vpu_api.destroy_class_On2Decoder(g_vp8decHandle);
  316.  
  317. g_vp8decHandle = NULL;
  318. }
  319. LOGI("ProcessDec End ====================");
  320.  
  321. return 0;
  322. }

  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硬编码的更多相关文章

  1. Android安全开发之浅谈密钥硬编码

    Android安全开发之浅谈密钥硬编码 作者:伊樵.呆狐@阿里聚安全 1 简介 在阿里聚安全的漏洞扫描器中和人工APP安全审计中,经常发现有开发者将密钥硬编码在Java代码.文件中,这样做会引起很大风 ...

  2. 使用VideoToolbox硬编码H.264<转>

    文/落影loyinglin(简书作者)原文链接:http://www.jianshu.com/p/37784e363b8a著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. ======= ...

  3. 【Android】Android Camera实时数据采集及通过MediaCodec硬编码编码数据的流程

    吐槽: 其实常用流程都差不多,但是有时候还是会忘记某一步的详细用法,但是各位朋友请注意,官方已经不推荐Camera类的使用(现在是android.hardware.camera2),但无奈公司项目之前 ...

  4. android studio 中查找代码中的硬编码

    在Android Studio中同时按下Ctrl + Shift+ F  或者其他自定义的快捷键,打开全局搜索,在全局搜索中输入 ^((?!(\*|//)).)+[\u4e00-\u9fa5] 并打勾 ...

  5. 【GPU编解码】GPU硬编码

    一.OpenCV中的硬编码 OpenCV2.4.6中,已实现利用GPU进行写视频,编码过程由cv::gpu::VideoWriter_GPU完成,其示例程序如下. int main(int argc, ...

  6. 告别硬编码-发个获取未导出函数地址的Dll及源码

    还在为找内核未导出函数地址而苦恼嘛? 还在为硬编码通用性差而不爽吗? 还在为暴搜内核老蓝屏而痛苦吗? 请看这里: 最近老要用到内核未导出的函数及一些结构,不想再找特征码了,准备到网上找点符号文件解析的 ...

  7. 【流媒体】 Android 实时视频编码—H.264硬编码

    [流媒體] Android 实时视频编码—H.264硬编码 SkySeraph Apr 4th 2012 Email:skyseraph00@163.com 1  硬编码 & 软编码 硬编码: ...

  8. ExpressionTree——让反射性能向硬编码看齐

    缘起 最近又换了工作.然后开心是以后又能比较频繁的关注博客园了.办离职手续的这一个月梳理了下近一年自己写的东西,然后就有了此文以及附带的代码. 反射 关于反射,窃以为,他只是比较慢.在这个前提下,个人 ...

  9. 硬编码写RadioGroup的时候要注意设置RadioButton的Id

    硬编码写RadioGroup的时候要注意RadioButton的id重复问题,导致选择的时候出现能够多选的情况发生,如下代码,注意Id的设置,这样避免Radiobutton的id重复. /** * 生 ...

随机推荐

  1. 09--c++ 类的继承与派生

    c++ 类的继承与派生   一.基本概念 1.类的继承,是新的类从已有类那里得到已有的特性.或从已有类产生新类的过程就是类的派生.原有的类称为基类或父类,产生的新类称为派生类或子类.   2.派生类的 ...

  2. mac 上执行 rm -rf /

    # 很可怕的指令,清空磁盘所有资料,千万不要用 sudo 尝试,吓的小心肝差掉跳出来 rm -rf / 无聊,想执行rm -rf /会怎样,想起没加sudo时对~/download执行提示权限不足,被 ...

  3. jsTree checkbox plugin使用笔记

    引入css文件 <link rel="stylesheet" type="text/css" href="js/assets/global/pl ...

  4. BZOJ 4278: [ONTAK2015]Tasowanie 后缀数组 + 贪心 + 细节

    Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin ...

  5. vfs:open.c 源码学习

    nameidata路径查找辅助结构 open.c @do_sys_open @get_unused_fd_flags @do_filp_open 1.开始填充nameidata 2.开始填充file ...

  6. vue-router 懒加载

    懒加载:也叫延迟加载,即在需要的时候进行加载,按需加载. 那vue 为什么需要懒加载呢? 使用 vue-cli构建的项目,在默认情况下,执行 npm run build  会将所有的 js代码打包为一 ...

  7. Windows Server 2008 R2x64 IIS7+PHP5.6 错误 500.0

    这两天准备升级一个网站项目,新项目基于PHP并进行了ZendGuard加密,需要在PHP5.6版本中运行 而客户之前的运行环境是php5.2~5.4,那好,再新建一个PHP版本不就完事了吗!!! 于是 ...

  8. D2007从win7升级到win10下的莫名其妙问题。

    在win7下听说win10被推荐,于是升级到win10.结果使用d2007不能打开,出现莫名其妙的错误.把bin\bds.exe改名bds1.exe后居然可以启动了.一番折腾后,这把bds1.exe改 ...

  9. 解决ExpressSpreadSheet 中文乱码问题[备查]

    cxSpreadSheet和F1Book等都提供了类似Excel的操作, 但是相比F1Book, cxSpreadSheet的中文支持还不是很完善.在设置了wordbreak为true的时候,里面的中 ...

  10. mongodb--reduce并行处理框架

    reduce 命令 db.runCommand( { mapReduce: <collection>, map: <function>, reduce: <functio ...