娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年02月13日(星期四)

正在發生

2018年02月13日 | 基于FFmpeg的H.264視頻硬件編解碼在S3C6410處理器上的實現

發布者:SparklingDreams 來源: eefocus關鍵字:FFmpeg  264視頻  硬件編解碼  S3C6410 手機看文章 掃描二維碼
隨時隨地手機看文章

  目前,智能手機、PDA和平板電腦等越來越多的嵌入式設備支持高清視頻采集和播放功能,高清視頻的采集或播放功能正廣泛用于游戲設備、監控設備、視頻會議設備和數字網絡電視等嵌入式系統中。這些功能的實現建立在高性能視頻硬件編解碼技術基礎之上。本文闡述了基于FFMpeg的H.264視頻硬件編解碼在S3C6410處理器上的實現方法,為數字娛樂、視頻監控和視頻通信系統開發過程中的高清視頻硬件編解碼的實現提供參考。


  FFmpeg[1]是一個開源免費跨平臺的視頻和音頻流方案,屬于自由軟件。它包含非常先進的音頻/視頻編解碼庫libavcodec,提供了錄制、轉換以及流化音視頻的完整解決方案。FFmpeg支持MPEG4、FLV等40多種編碼,以及AVI、ASF等90多種解碼。目前國內較為流行的播放器暴風影音和國外較為流行的Mplayer在音頻/視頻編解碼方面都用到了FFmpeg。

  S3C6410[2]是三星公司推出的應用處理器芯片,基于ARM11架構,主頻最高可達800 MHz。它具有多媒體硬件加速功能,其中包括大于30 FPs的MPEG4 SP、H.264/263 BP和VC1(WMV9)多種視頻硬件編解碼,可用于手機、平板電腦和游戲機等手持移動設備和其他高性能嵌入式設備。國產手機魅族M8的處理器使用的就是S3C6410。

  雖然FFmpeg提供了簡單的應用程序編程接口(API),可以很方便地實現多種格式的視頻軟件編解碼[3],但是軟件編解碼在處理復雜視頻編解碼(如H.264)時無法運用到處理速度不快、內存空間不多的嵌入式環境中。為了在資源有限的嵌入式環境下使用FFmpeg實現復雜視頻編解碼,下面在分析FFmpeg視頻編碼流程和S3C6410處理器視頻編解碼方法的基礎上,闡述嵌入式Linux操作系統下基于FFmpeg的H.264硬件編解碼在S3C6410處理器上的實現方法。

  1 FFmpeg視頻編解碼流程

  FFmpeg主要有encode/decode、muxer/demuxer和內存操作3個模塊。encode/decode模塊用于音視頻的編碼和解碼,存放在libavcodec子目錄中;muxer/demuxer模塊用于音頻和視頻的合并與分離(也稱混合器模塊),存放在libavformat目錄中;內存等常用模塊存放于libavutil目錄中。下面以解碼過程為例分析FFmpeg視頻編解碼流程。

  解碼基本流程共分4步:

  ① 注冊所有可能用到的編解碼器和混合器。av_register_all(void)函數中通過執行 REGISTER_MUXDEMUX(X,x)和REGISTER_ENCDEC(X,x),把所有FFmpeg支持的混合器和編解碼器相關信息以鏈式的結構存放在內存中。

  ② 打開視頻文件。av_open_input_file(AVFormatContext **IC_ptr,const char *filename,AVInputFormat *fmt,int buf_size,AVFormatParameters *ap)函數中偵測文件的格式,根據文件格式從鏈式的混合器中找到相對應的混合器(demuxer)并分離出視頻信息。

  ③ 獲取視頻信息。通過av_find_stream_info(AVFormatContext *ic)函數獲取視頻格式。根據視頻格式,在鏈式的視頻解碼器中找到相應的視頻解碼器,并通過avcodec_open(AVCodeCContext *avctx,AVCodec *codec)函數將解碼器打開用于下一步視頻的解碼。

  ④ 解碼一幀視頻,通過 avcodec_decode_video(AVCodecContext *avctx,AVFrame *picture,int *got_picture_ptr,const uint8_t *buf,int buf_size)函數解碼一幀視頻。

  FFmpeg的編碼過程與解碼過程類似,不同的是第3步根據要求編碼的格式在鏈式的視頻編碼器中找到相應的視頻編碼器,并執行編碼過程。

  通過以上對FFmpeg視頻編解碼流程分析可以知道,為了在FFmpeg中添加自定義的視頻編解碼器,并在程序運行時使用這個編解碼器,關鍵在于如下兩點:

  ① 根據FFmpeg對編解碼器的描述,實現自定義編解碼器。

  ② 通過REGISTER_ENCDEC(X,x)函數將自定義的視頻編解碼器添加到視頻編解碼器鏈中。在獲取視頻信息時,保證需要編碼或解碼的視頻能找到視頻編解碼器鏈中自定義的視頻編解碼器。

  2 S3C6410處理器視頻編解碼方法

  S3C6410視頻編解碼軟件架構[4]如圖1所示。底層為操作系統空間,上層為用戶空間,視頻編解碼器通過驅動和操作系統以設備文件的形式使用,使用的方法和普通文件一樣,包括文件打開和關閉、文件讀寫和輸入/輸出控制(ioctl,input/output control)。

圖1 S3C6410視頻編解碼軟件架構

  具體操作方法如下:

  ① 通過open函數打開編解碼器設備文件;

  ② 使用mmap方法在用戶空間和驅動空間之間映射輸入/輸出緩存空間,這樣做的好處是可以快速進行數據輸入/輸出;

  ③ 通過ioctl設備編解碼參數,初始化編解碼器;

  ④ 輸入數據,通過ioctl執行編解碼過程,輸出數據;

  ⑤ 通過close方法關閉編解碼器設備文件。

  值得注意的是,無論編碼還是解碼,處理的數據都是以一幀幀的形式操作的,所以第4步是一個不斷循環的過程,直到所有數據處理完成。另外,雖然編解碼器以設備文件的形式使用,但是它不能使用標準的文件讀寫操作,查看編解碼的設備驅動可以發現,其文件讀寫函數是空的,這一點三星公司的開發文檔并沒有說明。

  3 H.264硬件編解碼實現

  FFmpeg的H.264硬件編解碼[5]實現就是自定義一個視頻編解碼器,加入到FFmpeg庫中。這個視頻編解碼器使用S3C6410處理視頻硬件編解碼功能來實現H.264的視頻編碼和解碼過程,這樣使用FFmpeg庫的多媒體程序可以用訪問FFmpeg其他編解碼器一樣的方法使用這個自定義的編解碼器。添加自定義編解碼器的關鍵是根據FFmpeg中對編解碼的描述定義編解碼器,并實現定義中的相關函數。

  在libavcodec/avcodec.h中的AVCodec結構體是定義FFmpeg編解碼器的關鍵結構體,包括編解碼器的名字、類型(聲音/視頻)、編解碼器的識別號(CodecID)、支持格式和一些用于初始化、編碼、解碼和關閉的函數指針。

  typedef struct AVCodec {

  const char *name;

  enum CodecType type;

  enum CodecID id;

  int priv_data_size;

  int (*init)(AVCodecContext *);

  int (*encode)(AVCodecContext *,uint8_t *buf,int buf_size,void *data);

  int (*close)(AVCodecContext *);

  int (*decode)(AVCodecContext *,void *outdata,int *outdata_size,

  uint8_t *buf,int buf_size);

  int capabilities;

  struct AVCodec *next;

  void (*flush)(AVCodecContext *);

  const AVRational *supported_framerates;

  const enum PixelFormat *pix_fmts;

  } AVCodec;

  H.264硬件編解碼器定義如下:

  AVCodec s3cx264_encoder = {

  .name="s3cx264",

  .type=AVMEDIA_TYPE_VIDEO,

  .id=CODEC_ID_H264,

  .init=X264_init,

  .encode=X264_frame,

  .decode=X264_decode,

  .close=X264_close,

  …

  };

  解碼器的名字為s3cx264,類型為視頻。CodecID為H264,表示這個解碼器用于H.264視頻編解碼。初始化、編碼、解碼和關閉函數指針分別指向X264_init、X264_frame、X264_decodec和X264_close函數。

  添加s3cx264編解碼器到編解器鏈中,關鍵是通過修改libavcodec/allcodecs.c文件實現,修改如下:

  REGISTER_ENCDEC (ASV1,asv1);

  REGISTER_ENCDEC (S3CX264,s3cx264);

  //添加s3cx264編解碼器

  REGISTER_ENCDEC (ASV2,asv2);

  這樣,在程序運行時調用av_register_all(void)函數后,就可以把自定義的編解碼器s3cx264添加到FFmpeg存放在內存中的解編碼器鏈中。值得提出的是,對同一個視頻格式FFmpeg有多個編解碼器與之相對應。如H.264格式的視頻,FFmpeg本身就帶有對應的軟解碼器,現在添加了硬解碼器,為了避免不確定是哪一個解碼器在執行,可以把自定義的硬件編解碼器在注冊時放在注冊過程的最前面,這樣編解碼器在添加到解編器鏈中時就會放在靠前的位置,查找時就可以優于軟件解碼器找到硬解碼器。

  把硬件編解碼器s3cx264注冊到編解碼器鏈后,還要完成X264_init、X264_frame、X264_decodec和X264_close函數,編解碼器才能正常工作。以下結合前面對S3C6410視頻編解碼過程的分析,以編碼為例詳細闡述實現過程。

  定義X264Context結構體,保存設備文件描述符、編碼參數和輸入/輸出地址等信息,用于FFmpeg模塊間數據的傳遞:

  typedef struct X264Context {

  int dev_fd;

  uint8_t *addr;

  s3c_mfc_enc_init_arg_t enc_init;

  s3c_mfc_enc_exe_arg_t enc_exe;

  s3c_mfc_get_buf_addr_arg_t get_buf_addr;

  uint8_t *in_buf,*out_buf;

  AVFrame out_pic;

  } X264Context;

  X264_init實現的是編碼器初始化過程, 用于編碼器設備文件的打開、內存空間的映射、編碼參數設置和獲取編解碼數據輸入/輸出地址。

  static av_cold int X264_init(AVCodecContext *avctx){

  X264Context *x4 = avctx>priv_data;

  //打開編碼器設備文件

  x4>dev_fd = open(MFC_DEV_NAME,O_RDWR|O_NDELAY);

  //內存空間映射

  x4>addr = (uint8_t *) mmap(0,BUF_SIZE,PROT_READ |PROT_WRITE,MAP_SHARED,x4>dev_fd,0);

  //編碼參數設置

  ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_H264_ENC_INIT,&x4>enc_init);

  //獲取輸入/輸出地址

  x4>get_buf_addr.in_usr_data = (int)x4>addr;

  ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_GET_YUV_BUF_ADDR,&x4>get_buf_addr);

  x4>in_buf = (uint8_t *)x4>get_buf_addr.out_buf_addr;

  x4>get_buf_addr.in_usr_data = (int)x4>addr;

  ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_GET_LINE_BUF_ADDR,&x4>get_buf_addr);

  x4>out_buf = (uint8_t *)x4>get_buf_addr.out_buf_addr;

  return 0;

  }

  ioctl的參數為S3C_MFC_IOCTL_MFC_H264_ENC_INIT,表示使用H.264編碼。

  X264_frame函數執行編碼過程。需要注意的是data參數保存了需要編碼的數據,是一個四維的數組,要把它轉換成一維數組用于S3C6410編碼器輸入。另外,編碼數據存在空的情況,也就是空幀。這是需要處理的,方法是返回“0”,表示沒有輸出數據,否則程序運行時會出現段錯誤。

  static int X264_frame(AVCodecContext *ctx,uint8_t *buf,int bUFSize,void *data){

  ……

  //空間轉換

  if(frame){

  mEMCpy(x4>in_buf,frame>data[0],ctx>width*ctx>height);

  mEMCpy(x4>in_buf+ctx>width*ctx>height,frame>data[1],ctx>width*ctx>height/4);

  memcpy(x4>in_buf+ctx>width*ctx>height+ctx>width*ctx>height/4,frame>data[2],

  ctx>width*ctx>height/4);

  }

  else

  return 0;//空幀,返回

  //執行編碼過程

  ioctl(x4>dev_fd,S3C_MFC_IOCTL_MFC_H264_ENC_EXE,&x4>enc_exe);

  //編碼數據輸出

  bufsize = x4>enc_exe.out_encoded_size;

  memcpy(buf,x4>out_buf,bufsize);

  ……

  return bufsize;

  }

  X264_close關閉函數用于編碼結束后的資源釋放,包括取消空間映射和關閉設備文件。

  static av_cold int X264_close(AVCodecContext *avctx){

  …

  //取消空間映射

  munmap(x4>addr,BUF_SIZE);

  //關閉設備文件

  close(x4>dev_fd);

  return 0;

  }

  解碼函數的實現過程類似于編碼函數,包括空間轉換、執行解碼和解碼數據輸出。初始化時使用S3C_MFC_IOCTL_MFC_H264_DEC_INIT參數,執行時使用S3C_MFC_IOCTL_MFC_H264_ENC_EXE參數。

  4 運行測試

  s3cx264編解碼器添加到FFmpeg后,可以通過以下方式測試:

  ① 用如下命令編譯FFmpeg。

  ./configure enablecrosscompile

  arch=armv6 cpu=armv6

  targetos=linux crossprefix

  =/usr/LOCal/arm/4.3.2/bin/

  armlinux

  ② 運行 ./ffmpeg codecs查看可以找到s3cx264編解碼器,如圖2所示。

  圖2 FFmpeg顯示s3cx264編解碼器信息

  ③ 結合USB攝像頭測試s3cx264編碼。運行 ./ffmpeg s 320x240 r 50 f video4linux2 i /dev/video2 vcodec s3cx264 test.mp4 可以看到FFmpegg正使用s3cx264編碼器將USB攝像頭采集的數據編碼壓縮成test.mp4文件。test.mp4能夠正常播放顯示。

  以上測試說明已經成功地將s3cx264硬件視頻編碼器添加到了FFmpeg中,能夠編碼視頻數據,可以運用到其他使用FFmpeg庫的多媒體程序中。

  結語

  對于多媒體開發來說,編解碼時使用FFmpeg多媒體庫是一個不錯的選擇,支持較多的音視頻編解碼,編程接口簡單易用。了解FFmpeg編解碼過程,熟悉FFmpeg硬件編解碼器添加方法,對多媒體開發,尤其是資源有限的嵌入式多媒體開發有很大幫助。本文通過分析FFmpeg視頻編解碼過程和三星S3C6410處理器視頻硬件編解碼方法,在FFmpeg庫中成功添加S3C6410硬件編解碼器,使FFmpeg庫具有H.264視頻格式的硬件編解碼能力,可運用于游戲設備、監控設備、視頻會議設備和數字網絡電視等嵌入式系統中,同時也為其他嵌入式設備添加別的視頻格式的編解碼器到FFmpeg多媒體庫提供了參考。

  參考文獻

  [1] http://www.ffmpeg.org/.

  [2] Samsung.S3C6410 Datasheet,2010.

  [3] 李少春.基于FFMPEG的嵌入式視頻監控系統[J].電子技術,2007(3):3437.

  [4] API Document S3C6400/6410 MultiFormat Codec,2008.

  [5] FFmpeg codec HOWTO[EB/OL].2010[201101].http://wiki.multimedia.cx/index.php?title=FFmpeg_codec_HOWTO/.

  劉建敏(碩士生)、楊斌(教授),主要研究方向為單片機與嵌入式系統及應用。


關鍵字:FFmpeg  264視頻  硬件編解碼  S3C6410 引用地址:基于FFmpeg的H.264視頻硬件編解碼在S3C6410處理器上的實現

上一篇:嵌入式控制系統中I2C串行EEPROM器件應用
下一篇:關于嵌入式Linux的機房遠程監測系統研究

推薦閱讀

  為了推動技術更加協調統一有序地發展與應用,一些領域內的特定技術事項都被予以標準化。同時,技術與專利又有著密不可分的關系,由此衍生了為符合某一技術標準要求而必須使用的專利,即“標準必要專利(SEP)”。下面就隨嵌入式小編一起來了解一下相關內容吧。? ? 標準必要專利對技術實現的重要性為專利持有人帶來了優勢,令這班持有人能夠拒絕給予...
在寫入SPI數據數,必須調用SPI_I2S_ReceiveData(SPI1);讀取一次,不然會對數據的讀取不正確u8 SPI_Flash_GetChar(void){ u8 Data = 0;Data = SPI_I2S_ReceiveData(SPI1);//必須讀取一次,應該是讀后清空寄存器while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);//SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_FLAG_TXE);SPI_I2S_Sen...
一、準備工作1、準備文件binutils-2.22.tar.bz2gcc-4.6.3.tar.bz2glibc-2.14.1.tar.xzglibc-ports-2.14.1.tar.gzglibc-linuxthreads-2.5.tar.bz2gdb-7.4.1.tar.bz2linux-2.6.38.8.tar.bz2mpfr-3.1.1.tar.bz2mpc-1.0.1.tar.gzgmp-5.1.0.tar.bz2 2、建立以下變量,方便稍候的輸入#vim ~/.bashrcexport TARGET=arm-linux-gnueabiexport PREFIX=/usr/local/ar...
據外媒報道,荷蘭設備制造商ASML表示,芯片短缺導致汽車生產放緩是給半導體行業供應商帶來壓力的需求更廣泛增長的一個征兆。ASML的一位高管表示,對大多數類型的電腦芯片的更高需求看起來比包括ASML在內的大多數行業參與者在新冠大流行開始時所預期的更強勁、更持久。 在過去十年時間里,ASML已經發展成為歐洲最大的工業科技公司,市值近2000億歐元。該公...

史海拾趣

問答坊 | AI 解惑

怎樣看電路原理圖

電器維修、電路設計都是要通過分析電路原理圖,了解電器的功能和工作原理,才能得心應手開展工作的。要維修或設計,首先要有過硬的基本功,要能對有技術參數的電路原理圖進行總體了解,能進行劃分功能模塊,找出信號流向,確定元件作用。若不知電路 ...…

查看全部問答∨

中南國際實業有限公司招聘電子工程師

中南集團成立于1935年,是一家大型港資集團,總部在香港,至今已有近70年歷史,員工一萬多名.生產線遍布于深圳﹑廣州﹑天津﹑上海﹑瑞士﹑德國及法國, 維達力實業(深圳)有限公司隸屬與中南集團,主要從事真空鍍膜(IP鍍膜)行業,主要對鐘表,手飾及眼鏡﹑ ...…

查看全部問答∨

超簡單Mega8->USB軟件模似串口應用范例

USB TO RS-232 program Program:  Mega8   2434 bytes (29.7% Full) Data:              184 bytes (18.0% Full) USBASP硬件電路 超簡單AVRUSB軟件模似串口(COMx) ...…

查看全部問答∨

《單片機原理與應用》(金龍國)電子教案-

《單片機原理與應用》(金龍國)電子教案,希望能幫助需要的人~ 很好的資料 137頁,是我多年的珍藏!…

查看全部問答∨

坡莫合金的問題

論壇的兄弟姐妹們,小弟想用坡莫合金做一個開合式的互感器,測量感應電纜的內部電流電壓等參數,同時還要用來做能量獲取。 請問有做過類似項目的么?可否交流一下,多謝啦 ps:我以前用矽鋼片來做同樣的功能的,已經實現。…

查看全部問答∨

有償回答;cdma Modem收到的短信如何解碼為正確的內容

我有個WAVECOM cdma Modem,用手機發送“測試。”給Modem,用AT+CMGR=0后返回的短信內容是“mK嬚0”,我改如何解碼為正確的內容,最好能給個VB下調用函數。在我能力允許范圍內,可以給大蝦一下Q幣補償^-^;我的qq:228090184…

查看全部問答∨

求c8051f340單片機的usb通信或者數據采集范例

如題,圖書館書翻遍了,沒有找到相關范例,只好網上尋找高人…

查看全部問答∨

PB編譯一個OS時,出現如下錯誤.求解!

     各位高人,我在使用PB編譯一個OS時,出現如下錯誤,請叫如何進行調試才能夠正常編譯? Error - cannot open input file D:\\WINCE500\\PBWorkspaces\\QT2440_1103\\RelDir\\smdk2440a_ARMV4I_Release\\postproc\\nlscfg.i ...…

查看全部問答∨

PC6的TIM3_CH1要重映射,請問為什么這么設計?(已解決)

datasheet的table4中說:================================================                         Defa ...…

查看全部問答∨

求助:F169調試串口通信的時候遇到的問題

我用的是MSP430F169的板子,以下代碼的功能是把串口接收到數據直接發送出去,我用串口調試助手向串口發送數據,發現板子可以正常接收數據,也能正常給TXBUF1賦值,但是PC就是收不到數據,請教各位高手指點. #include <msp430x16x.h> void main(voi ...…

查看全部問答∨
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 天长市| 资讯 | 塔河县| 丁青县| 巫溪县| 民县| 乐亭县| 天全县| 容城县| 色达县| 顺义区| 义马市| 改则县| 阜新市| 宣恩县| 酒泉市| 南通市| 五指山市| 安新县| 黄骅市| 汝州市| 金沙县| 报价| 土默特左旗| 塔城市| 襄汾县| 奇台县| 车致| 汾西县| 汽车| 会宁县| 五寨县| 明水县| 北安市| 大洼县| 巍山| 苗栗县| 旬邑县| 洛川县| 常德市| 鄄城县|