android 使用X264編碼視頻

android 使用X264編碼視頻

源碼剛上傳可能審核
源碼下載地址

X264對應部分API介紹

初始化x264_param_t

    _x264_param = new x264_param_t;/***  preset是編碼速度*  可選項"ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow",*  "slower", "veryslow", "placebo",從最快到最慢。無特殊要求選fast即可。** tune是編碼質量和畫面細節相關的參數。*可選項"film"電影, "animation"動畫, "grain"顆粒, "stillimage"靜態圖像,* "psnr"PSNR測試, "ssim"SSIM測試, "fastdecode"快速解碼, "zerolatency"零延遲這幾種。**/x264_param_default_preset(_x264_param, "fast" , "zerolatency");//設置preset和tune

碼率的控制

    if (bite == 0) {bite = 1;}if (bite > 0 && bite <= 64) {bitratelevel = BIT_LOW_LEVEL;} else if (bite > 64 && bite <= 128) {bitratelevel = BIT_MEDIUM_LEVEL;} else if (bite > 128 && bite <= 256) {bitratelevel = BIT_STANDARD_LEVEL;} else if (bite > 256 && bite <= 384) {bitratelevel = BIT_HIGH_LEVEL;} else if (bite > 384 && bite <= 512) {bitratelevel = BIT_HIGH_LEVEL;} else {bitratelevel = BIT_STANDARD_LEVEL;}/*** f_rf_constant圖像質量控制是實際質量,越大圖像越花,越小越清晰。*/if (bitratelevel == BIT_LOW_LEVEL) {_x264_param->rc.f_rf_constant = 32;} else if (bitratelevel == BIT_MEDIUM_LEVEL) {_x264_param->rc.f_rf_constant = 29;} else if (bitratelevel == BIT_STANDARD_LEVEL) {_x264_param->rc.f_rf_constant = 26;} else if (bitratelevel == BIT_HIGH_LEVEL) {_x264_param->rc.f_rf_constant = 24;} else {_x264_param->rc.f_rf_constant = 24;}

碼率控制模式、寬高、IDR幀間隔、幀率(X264_CSP_BGRA是RGBA編碼)

   // 重復SPS/PPS 放到關鍵幀前面  該參數設置是讓每個I幀都附帶sps/pps。_x264_param->b_repeat_headers = 1;//參數i_rc_method表示碼率控制,CQP(恒定質量),CRF(恒定碼率),ABR(平均碼率)_x264_param->rc.i_rc_method = X264_RC_CRF;_x264_param->i_width  = width;_x264_param->i_height = height;_x264_param->i_frame_total = 0;  /* 編碼幀的總數, 默認 0 */_x264_param->i_keyint_max = 3; /* 在此間隔設置IDR關鍵幀 */_x264_param->i_fps_den = 1; //* 幀率分母_x264_param->i_fps_num = fps; //* 幀率分子_x264_param->i_timebase_den = _x264_param->i_fps_num;_x264_param->i_timebase_num = _x264_param->i_fps_den;_x264_param->i_cqm_preset = X264_CQM_FLAT; /*自定義量化矩陣(CQM),初始化量化模式為flat*/

參考幀和B幀設置、編碼線程設置、采用什么格式編碼

    xfps= fps;xheight = height;xwidth = width;_x264_param->analyse.i_me_method = X264_ME_HEX; /* 運動估計算法 (X264_ME_*) */_x264_param->analyse.i_subpel_refine = 2; /* 亞像素運動估計質量 */_x264_param->i_frame_reference = 1; /* 參考幀最大數目 */_x264_param->analyse.b_mixed_references = 0;/*允許每個宏塊的分區在P幀有它自己的參考號*//* Trellis量化,對每個8x8的塊尋找合適的量化值,需要CABAC,默認0 0:關閉1:只在最后編碼時使用2:一直使用*/_x264_param->analyse.i_trellis = 0;_x264_param->b_sliced_threads = 0;_x264_param->i_threads = 4;/* 并行編碼多幀 *///i_threads = N并行編碼的時候如果b_sliced_threads=1那么是并行slice編碼,//如果b_sliced_threads=0,那么是并行frame編碼。并行slice無延時,并行frame有延時_x264_param->analyse.b_transform_8x8 = 0;/* 幀間分區*/_x264_param->b_cabac = 0;_x264_param->b_deblocking_filter =1;/*去塊濾波器需要的參數*/_x264_param->psz_cqm_file = NULL;_x264_param->analyse.i_weighted_pred = X264_WEIGHTP_NONE;_x264_param->rc.i_lookahead = 10;_x264_param->i_bframe = 0;/*兩個相關圖像間P幀的數目 */#if CODEC_X264_BGRA_x264_param->i_csp = X264_CSP_BGRA; /* 編碼比特流的CSP,僅支持i420,色彩空間設置 */#else#endif

_x264_param參數初始化結束后直接打開編碼器

    _x264_encoder = x264_encoder_open( _x264_param );

創建相關的編碼結構和編碼后輸出結構體(RGBA和YUV420p兩種格式)

    _in_pic = new x264_picture_t;_out_pic = new x264_picture_t;x264_picture_init(_out_pic);#if CODEC_X264_BGRAx264_picture_alloc(_in_pic, X264_CSP_BGRA, _x264_param->i_width, _x264_param->i_height);_in_pic->img.i_csp = X264_CSP_BGRA;_in_pic->img.i_plane = 1;_in_pic->img.i_stride[0] = 4 * _x264_param->i_width;#elsex264_picture_alloc(_in_pic, X264_CSP_I420, _x264_param->i_width, _x264_param->i_height);_in_pic->img.i_csp = X264_CSP_I420;_in_pic->img.i_plane = 3;
#endif

把獲取到數據進去相關格式拷貝到編碼結構體x264_picture_t,然后進行編碼輸出相關編碼數據

void x264Encode::startEncoder(uint8_t * dataptr, char *&bufdata,int &buflen, int &isKeyFrame)
{int width = xheight;int height =xwidth;#if CODEC_X264_BGRAif(src_data_y == NULL){src_data_y = (uint8_t *)malloc(width*height);}if(src_data_u == NULL){src_data_u = (uint8_t *)malloc(width/2*height/2);}if(src_data_v == NULL){src_data_v = (uint8_t *)malloc(width/2*height/2);}if(dst_data == NULL){dst_data =(uint8_t *) malloc(width*height*4);}//拷貝y分量memcpy(src_data_y, dataptr, width * height);//拷貝u分量memcpy(src_data_u, dataptr+width*height, width*height/4);//拷貝v分量memcpy(src_data_v, dataptr+width*height*5/4, width*height/4);libyuv::I420ToARGB(src_data_y,width,src_data_u,width/2,src_data_v,width/2,dst_data,width*4,width,height);memcpy(_in_pic->img.plane[0], dst_data,width*height*4);#elsememcpy(_in_pic->img.plane[0], dataptr, width * height);memcpy(_in_pic->img.plane[1], dataptr+width*height, width*height/4);memcpy(_in_pic->img.plane[2], dataptr+width*height*5/4, width*height/4);
#endif_in_pic->i_type = X264_TYPE_AUTO;_in_pic->i_qpplus1 = 0;_in_pic->param = _x264_param;_in_pic->i_pts = 0;x264_nal_t *nal;int        i_nal = 0;int Result;if (_x264_encoder != NULL) {Result = x264_encoder_encode(_x264_encoder, &nal, &i_nal, _in_pic, _out_pic);isKeyFrame = _out_pic->b_keyframe;_in_pic->i_pts++;} else{}if (Result < 0) {LOGE("=======encoder faild=========");}else if (Result == 0){//LOGI("/**********************編碼成功,但被緩存了************************");}else{LOGE("=======encoder succees=========");int bufsize = 0;for (int i=0; i<i_nal; i++) {bufsize += nal[i].i_payload;}char * tempdata = new char[bufsize];memset(tempdata, 0, bufsize);bufdata = tempdata;for (int i=0; i<i_nal; i++) {if (nal[i].p_payload != NULL) {memcpy(tempdata, nal[i].p_payload, nal[i].i_payload);tempdata+=nal[i].i_payload;}}buflen = bufsize;}
}

編碼結束后退出進行刷新把編碼器所以數據編碼出來

void x264Encode::Flush()
{x264_picture_t pic_out;x264_nal_t * nal;int i_nal;if (x264_encoder_encode(_x264_encoder, &nal, &i_nal, NULL, &pic_out)<0) {}
}

ndk接口

public class x264Tool {public interface listener{void h264data(byte[] buffer, int length);}private listener _listener;public x264Tool(listener l){_listener = l;}static {System.loadLibrary("x264encoder");}public void PushOriStream(byte[] buffer, int length, long time){encoderH264(buffer,length, time);}public native void initX264Encode(int width, int height, int fps, int bite);public native int encoderH264(byte[] buffer,int length, long time);public native void CloseX264Encode();private void H264DataCallBackFunc(byte[] buffer, int length){_listener.h264data(buffer, length);}}

Android Camera的調用獲取相關的照相機數據

package com.test.x264encoderdemo;import android.Manifest;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;import example.mg.x264.x264Tool;public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback,Camera.PreviewCallback {private SurfaceView surfaceview;private SurfaceHolder surfaceHolder;private Camera camera;private Parameters parameters;private int width = 640;private int height = 480;private int fps = 20;private int bitrate = 90000;private x264Tool x264;private int timespan = 90000 / fps;private long time;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO)!= PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(this,Manifest.permission.INTERNET)!= PackageManager.PERMISSION_GRANTED||ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_CONTACTS,Manifest.permission.INTERNET,Manifest.permission.CAMERA}, 100);}surfaceview = (SurfaceView)findViewById(R.id.surfaceview);surfaceHolder = surfaceview.getHolder();surfaceHolder.addCallback(this);x264 = new x264Tool(l);createfile();}private x264Tool.listener l = new x264Tool.listener(){@Overridepublic void h264data(byte[] buffer, int length) {// TODO Auto-generated method stubtry {//Log.e("========","=======length==="+length);outputStream.write(buffer, 0, buffer.length);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};private static String path ="/storage/emulated/0/DCIM/aa/test.h264";private BufferedOutputStream outputStream;FileOutputStream outStream;private void createfile(){File file = new File(path);if(file.exists()){file.delete();}try {outputStream = new BufferedOutputStream(new FileOutputStream(file));} catch (Exception e){e.printStackTrace();}}@Overridepublic void onPreviewFrame(byte[] data, Camera camera) {// TODO Auto-generated method stubtime += timespan;byte[] yuv420 = new byte[width*height*3/2];YUV420SP2YUV420(data,yuv420,width,height);x264.PushOriStream(yuv420, yuv420.length, time);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {// TODO Auto-generated method stubx264.initX264Encode(width, height, fps, bitrate);camera = getBackCamera();startcamera(camera);}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// TODO Auto-generated method stub}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {// TODO Auto-generated method stubif (null != camera) {camera.setPreviewCallback(null);camera.stopPreview();camera.release();camera = null;}x264.CloseX264Encode();try {outputStream.flush();outputStream.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}private void startcamera(Camera mCamera){if(mCamera != null){try {mCamera.setPreviewCallback(this);mCamera.setDisplayOrientation(90);if(parameters == null){parameters = mCamera.getParameters();}parameters = mCamera.getParameters();parameters.setPreviewFormat(ImageFormat.NV21);parameters.setPreviewSize(width, height);mCamera.setParameters(parameters);mCamera.setPreviewDisplay(surfaceHolder);mCamera.startPreview();} catch (IOException e) {e.printStackTrace();}}}Bitmap getBitmap(byte[] data,int height,int width){Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);ByteBuffer bufffer = ByteBuffer.wrap(data);//bufffer.position(0);bufffer.rewind();bufffer.position(0);bitmap.copyPixelsFromBuffer(bufffer);return bitmap;}@TargetApi(9)private Camera getBackCamera() {Camera c = null;try {c = Camera.open(0); // attempt to get a Camera instance} catch (Exception e) {e.printStackTrace();}return c; // returns null if camera is unavailable}private void YUV420SP2YUV420(byte[] yuv420sp, byte[] yuv420, int width, int height){if (yuv420sp == null ||yuv420 == null)return;int framesize = width*height;int i = 0, j = 0;//copy yfor (i = 0; i < framesize; i++){yuv420[i] = yuv420sp[i];}i = 0;for (j = 0; j < framesize/2; j+=2){yuv420[i + framesize*5/4] = yuv420sp[j+framesize];i++;}i = 0;for(j = 1; j < framesize/2;j+=2){yuv420[i+framesize] = yuv420sp[j+framesize];i++;}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697783.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697783.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697783.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用 package.json 配置代理解決 React 項目中的跨域請求問題

使用 package.json 配置代理解決 React 項目中的跨域請求問題 當我們在開發前端應用時&#xff0c;經常會遇到跨域請求的問題。為了解決這個問題&#xff0c;我們可以通過配置代理來實現在開發環境中向后端服務器發送請求。 在 React 項目中&#xff0c;我們可以使用 package…

MES系統中的手動排產和自動排產-助力生產效率

企業在排產管理中面臨的問題&#xff1a; 大多數的企業在調度排產過程中&#xff0c;都會遇到以下問題。首先是插單非常的多&#xff0c;計劃調整困難&#xff0c;會經常性的發生原材料、零部件的備貨不足。計劃按MRP或庫存展示計算出需求后將產生大量工單&#xff0c;這些工單…

《劍指Offer》筆記題解思路技巧優化_Part_6

《劍指Offer》筆記&題解&思路&技巧&優化_Part_6 &#x1f60d;&#x1f60d;&#x1f60d; 相知&#x1f64c;&#x1f64c;&#x1f64c; 相識&#x1f622;&#x1f622;&#x1f622; 開始刷題&#x1f7e1;1.LCR 168. 丑數—— 丑數&#x1f7e2;2. LCR 16…

Kubernetes服務網絡Ingress網絡模型分析、安裝和高級用法

文章目錄 1、Ingres簡介2、Ingres網絡模型分析3、安裝Ingress4、使用4.1、搭建測試環境4.2、域名訪問4.3、路徑重寫&#xff08;高級用法&#xff09;4.4、流量限制&#xff08;高級用法&#xff09; 5、總結 1、Ingres簡介 Ingress翻譯過來是“入口”的意思&#xff0c;也就是…

切換分支時候IDEA提示:workspace associated with branch feature has been restored

切換分支時候IDEA提示&#xff1a;workspace associated with branch feature has been restored 這個消息是指與"feature"分支關聯的工作區已經恢復。在Git中&#xff0c;工作區是指你當前正在進行修改和編輯的文件和目錄。當你切換分支時&#xff0c;Git會自動將工…

配置docker 支持GPU方法(Nvidia GPU)

參考官方文檔&#xff1a; https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 系統版本&#xff1a;ubuntu 23.04 執行腳本如下&#xff1a; 1.Configure the production repository: curl -fsSL https://nvidia.github.io/lib…

怎么把試卷圖片轉換成word?這4種方法一看就會

怎么把試卷圖片轉換成word&#xff1f;在數字化日益盛行的今天&#xff0c;我們常常會面臨將紙質試卷或圖片中的試卷內容轉化為Word文檔的需求。無論是為了對試卷內容進行編輯、修改&#xff0c;還是為了在線共享、遠程教學&#xff0c;將圖片轉換為Word文檔都成為了至關重要的…

集成TinyMCE富文本編輯器

若依的基礎上集成TinyMCE富文本編輯器 前端bootstrap TinyMCE官網鏈接 TinyMCE所需靜態資源下載鏈接 開源項目-若依鏈接 將TinyMCE靜態資源包放入項目中&#xff1b; 代碼引入css&#xff1a; <!-- 引入TinyMCE CSS --><link th:href"{/ajax/libs/tinymce/j…

金田金業: 美聯儲泡沫正在破裂! 崩潰對黃金非常有利

The Great Recession Blog作者大衛哈吉斯表示&#xff0c;美聯儲一直以來都將繼續收緊貨幣政策&#xff0c;直到出現問題&#xff0c;但市場現在已經陷入泡沫。 他指出&#xff0c;泡沫正在破裂&#xff0c;崩潰最終將對黃金非常有利。 正當投資者聚焦美聯儲何時會降息&#xf…

Springboot 使用升級小記-循環依賴

springboot 使用已經非常廣泛了&#xff0c;它的版本迭代速度也比較快&#xff0c;過一段時間版本差異就會比較大。 由于低版本依賴的 spring 版本有漏洞問題&#xff0c;這次我們是從 2.2.6 版本直接升級到 2.7.16&#xff0c;升級 3.0 的話擔心差異更大。 這時直接修改依賴…

Jmeter 學習目錄(0)

Jmeter 所有內容均以學習為主輸出內容&#xff0c;按照最小單位和基礎進行輸出。 如果有看不懂&#xff0c;或者有不明確的內容&#xff0c;歡迎大家留言說明。 Mac Jmeter下載安裝啟動(1) Jmeter 目錄介紹(2) Jmeter基礎發起一次請求(3)

代碼隨想錄三刷day07

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、力扣206. 反轉鏈表二、力扣24. 兩兩交換鏈表中的節點 前言 遞歸寫法和雙指針法實質上都是從前往后翻轉指針指向&#xff0c;其實還有另外一種與雙指針法不同…

SD-WAN:快速改造升級企業原有網絡架構

隨著企業信息化的推進&#xff0c;傳統網絡架構已難以滿足企業日益復雜和多樣化的組網互聯需求。企業在不斷提高對網絡的要求&#xff0c;包括各辦公點的互聯數據傳輸、資源共享、視頻會議、ERP、OA、郵箱系統、云服務等應用需求&#xff0c;以及對網絡運維工作的簡化和降低難度…

Spring Event 快速入門

請直接看原文 : Spring Event&#xff0c;賊好用的業務解耦神器&#xff01; (qq.com) -------------------------------------------------------------------------------------------------------------------------------- 前言 Spring Event 同步使用 Spring Event 異…

架構篇35:微服務架構最佳實踐 - 方法篇

文章目錄 服務粒度拆分方法基礎設施小結上一篇我們談了實施微服務需要避免踩的陷阱,簡單提煉為: 微服務拆分過細,過分強調“small”。微服務基礎設施不健全,忽略了“automated”。微服務并不輕量級,規模大了后,“lightweight”不再適應。針對這些問題,我們看看微服務最佳…

ADAS智能駕駛測試知多少?

當涉及ADAS&#xff08;Advanced Driver Assistance Systems&#xff09;智能駕駛的測試時&#xff0c;有一個完整的測試體系可以用來評估系統的性能和功能。 1. 傳感器測試 1.1 傳感器校準測試 描述&#xff1a;確保傳感器&#xff08;如雷達、攝像頭、激光雷達等&#xff09;…

【stm32】hal庫學習筆記-UART/USART串口通信(超詳細!)

【stm32】hal庫學習筆記-UART/USART串口通信 hal庫驅動函數 CubeMX圖形化配置 導入LCD.ioc RTC設置 時鐘樹配置 設置LSE為RTC時鐘源 USART設置 中斷設置 程序編寫 編寫主函數 /* USER CODE BEGIN 2 */lcd_init();lcd_show_str(10, 10, 16, "Demo12_1:USART1-CH340&q…

【PythonGIS】Python線矢量等距離取點/線等分取點點創建矢量面

不多說&#xff0c;這是之前項目需求的代碼&#xff0c;已經是去年的了一直沒來的及發&#xff0c;今天抽出來一丟丟的空擋發一下。主要就是利用線矢量等距離生成點矢量&#xff0c;或者直接將線矢量等分生成點矢量&#xff0c;這個需求其實極限一下就是線轉點了&#xff08;將…

Java中各種O(PO,BO,DTO,VO等) 是不是人為增加系統復雜度?

Java中各種O(PO,BO,DTO,VO等) 是不是人為增加系統復雜度&#xff1f; 在Java和其他編程語言的開發過程中&#xff0c;經常會用到幾個以"O"結尾的縮寫&#xff0c;比如PO,BO,DTO,VO等等&#xff0c;O在這里是Object的縮寫&#xff0c;不同的O代表了不同的數據類型&am…

onlyoffice7.5.1 實現填寫表單 word+html form雙向綁定功能

說明&#xff1a;目前官方已經更新wordhtml為8.0以前的&#xff0c;目前官方新版本8.0增加了pdf綁定&#xff0c;這個我考慮在以后研究努力實現。 onlyoffice雙向綁定form表單數據