在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Tiny4412移植ffmpeg實現視頻解碼

嵌入式技術 ? 來源:嵌入式技術 ? 作者:嵌入式技術 ? 2022-09-29 15:31 ? 次閱讀

Tiny4412移植ffmpeg實現視頻解碼

?FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并能將其轉化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec里很多code都是從頭開發的。

1.硬件平臺

硬件平臺:Tiny4412(Cortex-A9)
交叉編譯器:arm-linux-gcc(Ver4.5.1)
開發板系統:linux3.5
ffmpeg版本:ffmpeg-4.2.5

2.ffmpeg源碼編譯

??安裝ffmpeg庫之前需要先安裝x264庫。

?2.1 x264編譯安裝

??x264下載地址:https://www.videolan.org/developers/x264.html

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

?安裝x264

#解壓
tar xvf /mnt/hgfs/ubuntu/software_pack/x264-master.tar.bz2
#配置信息,生成Makefile
./configure --prefix=$PWD/_install --enable-shared --disable-asm --host=arm-linux
#修改config.mak 
gedit config.mak 
watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

??編譯 make

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

若編譯出現報錯:undefined reference to `clock_gettime’,則添加動態鏈接: -lrt
??重新編譯 make

/*編譯*/
make && make install
/*生成文件*/
[wbyq@wbyq x264-master]$ tree _install/
_install/
├── bin
│   └── x264
├── include
│   ├── x264_config.h
│   └── x264.h
└── lib
    ├── libx264.so -> libx264.so.164
    ├── libx264.so.164
    └── pkgconfig
        └── x264.pc

4 directories, 6 files

?2.2 ffmpeg編譯安裝

??下載地址:http://www.ffmpeg.org/download.html

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASVRf6Zi_5rC0,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center

??編譯安裝ffmpeg

/*解壓*/
tar xvf /mnt/hgfs/ubuntu/software_pack/ffmpeg-4.2.5.tar.bz2 
/*配置信息,生成makefile文件*/
./configure --enable-shared --enable-static --prefix=$PWD/_install --cross-prefix=arm-linux- --arch=arm --target-os=linux --enable-gpl --extra-cflags=-I/home/wbyq/tiny4412_pack/x264-master/_install/include --extra-ldflags=-L/home/wbyq/tiny4412_pack/x264-master/_install/lib --enable-ffmpeg --enable-libx264
/*編譯源碼*/
make && make install

3.視頻解碼

#include 
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 

#define FILE_NAME "1.mp4"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
extern const unsigned char ascii_32_16[][32*16/8];
static  struct fb_var_screeninfo vinfo;/*lcd可變形參結構體*/
static struct fb_fix_screeninfo finfo;/*lcd固定參數結構體*/
static unsigned char *lcd_p;/*lcd緩沖區首地址*/

u32 lcd_widht;/*LCD屏寬度*/
u32 lcd_hight;/*LCD屏高度*/

static unsigned char *lcd_p2;/*圖像數據*/
u32 map_w;
u32 map_h;
/*畫點函數*/
void LCD_DrawPoint(int x,int y,int c)
{
	unsigned int *p=(unsigned int *)(y*finfo.line_length+x*vinfo.bits_per_pixel/8+lcd_p);
	*p=c;
}
/*畫點函數*/
void LCD_DrawPoint2(int x,int y,int c)
{
	unsigned int *p=(unsigned int *)(y*map_w*3+x*3+lcd_p2);
	*p=c;
}
/*顯示數據*/
void LCD_DisplayData(int x,int y,int w,int h,const unsigned char *data)
{
	int i,j;
	int x0=x;
	unsigned char temp;
	for(i=0;i0x80)
    {
		str+=2;
    }
    else
    {
      LCD_DisplayData(x,y,size/2,size,ascii_32_16[*str-' ']);
      str++;
      x+=size/2;
    }
  }
}
/*顯示圖片函數(居中顯示)*/
void LCD_Image(int map_w,int map_h,u8 *map_rgb)
{
    u32 w=map_w;//圖片寬度
    u32 h=map_h;//圖片高度
    //printf("w=%d,h=%dn",w,h);
   // u16 x=(lcd_widht-w)/2;
  //  u16 y=(lcd_hight-h)/2;
	u16 x=0;
	u16 y=0;
    int i,j;
    int cnt=0;
    u32 rgb=0xff0000;
    u8 *image_rgb=map_rgb;
    u32 *p=(unsigned int *)(y*finfo.line_length+x*vinfo.bits_per_pixel/8+lcd_p);//獲取到坐標地址
    for(i=0;istreams[videostream];
	AVCodec *vcodec=avcodec_find_decoder(stream->codecpar->codec_id);
	if(!vcodec)
	{
		printf("未找到解碼器n");
		return -1;
	}
	/*申請視頻AVCodecContext空間。需要傳遞一個編碼器,也可以不傳,但不會包含編碼器。*/
	res=avcodec_open2(stream->codec,vcodec,NULL);
	if(res)
	{
		printf("打開解碼器失敗n");
		return -1;
	}
	
	/*尋找音頻解碼器*/
	AVStream *audstream = ps->streams[audiostream];
	AVCodec *audcodec=avcodec_find_decoder(audstream->codecpar->codec_id);
	if(!audcodec)
	{
		printf("audcodec failedn");
		return -1;
	}
	/*申請音頻AVCodecContext空間。需要傳遞一個編碼器,也可以不傳,但不會包含編碼器。*/
	res=avcodec_open2(audstream->codec,audcodec,NULL);
	if(res)
	{
		printf("open audio failedn");
		return -1;
	}
	printf("sucessn");
	int sample_rate=audstream->codec->sample_rate;/*采樣率*/
	int channel=audstream->codec->channels;/*通道數*/
	
	printf("sample_rate:%dn",sample_rate);
	printf("channel:%dn",channel);
	int sample_fmt;
	switch(audstream->codec->sample_fmt)
	{
		case AV_SAMPLE_FMT_U8:/*8位*/
			sample_fmt=AV_SAMPLE_FMT_U8;
			break;
		case AV_SAMPLE_FMT_FLTP:/*浮點型*/
			sample_fmt=AV_SAMPLE_FMT_FLTP;
			break;
	}
	int go_audio;
	AVPacket *packet=av_malloc(sizeof(AVPacket));/*分配包*/
	AVFrame *frame=av_frame_alloc();/*分配視頻幀*/
	AVFrame *audioframe=av_frame_alloc();/*分配音頻幀*/
	int audiosize=2*1024*2;
	char *out_buffer = (char*)av_malloc(audiosize);
	/*對解碼數據進行重采樣*/
	SwrContext *swrCtx = swr_alloc();
	enum AVSampleFormat in_sample_fmt=audstream->codec->sample_fmt;/*輸入采樣格式*/
	enum AVSampleFormat out_sample_fmt=AV_SAMPLE_FMT_S16;/*輸出采樣格式:16bit PCM*/
	int in_sample_rate=audstream->codec->sample_rate;/*輸入采樣率*/
	int out_sample_rate=44100;/*輸出采樣率*/
	
	uint64_t in_ch_layout=audstream->codecpar->channel_layout;//輸入的聲道布局
	uint64_t out_ch_layout=audstream->codecpar->channel_layout;/*立體聲*/
	
	swr_alloc_set_opts(swrCtx,out_ch_layout,out_sample_fmt,out_sample_rate,/*輸入音頻格式*/
								in_ch_layout,in_sample_fmt,in_sample_rate,/*輸出音頻格式*/
								0,NULL);
	
	swr_init(swrCtx);
	//視頻解碼
	AVFrame *frameRGB=av_frame_alloc();/*申請yuv空間*/
	/*分配空間,進行圖像轉換*/
	int width=ps->streams[videostream]->codecpar->width;
	int height=ps->streams[videostream]->codecpar->height;
	int fmt=ps->streams[videostream]->codecpar->format;/*流格式*/
	map_w=800;
	map_h=480;
	int size=avpicture_get_size(AV_PIX_FMT_BGR24, map_w,map_h);
	unsigned char *buff=NULL;
	printf("w=%d,h=%d,size=%dn",width,height,size);
	buff=av_malloc(size);
	/*計算一幀空間大小*/
	avpicture_fill((AVPicture *)frameRGB,buff,AV_PIX_FMT_BGR24,map_w,map_h);
	/*轉換上下文*/
	struct SwsContext *swsctx=sws_getContext(width,height, fmt,map_w,map_h, AV_PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);

	/*讀幀*/
	int go=0;
	int Framecount=0;
	printf("read fream buffn");
	int audio_count=0;
	time_t sec=0,sec2=0;
	char buff_time[200]={0};
	struct tm result;
	while((av_read_frame(ps,packet)>=0))
	{
		sec=time(NULL);
		if(sec!=sec2)
		{
			sec2=sec;
			localtime_r(&sec2,&result);//將秒單位時間轉換為時間結構體
			strftime(buff_time,sizeof(buff_time),"%H:%M:%S",&result);//時間格式化打印	
		}

		if(packet->stream_index == AVMEDIA_TYPE_VIDEO)/*判斷是否為視頻*/
		{
			res=avcodec_decode_video2(ps->streams[videostream]->codec,frame,&go,packet);
			if(res<0)
			{
				printf("avcodec_decode_video2 failedn");
				return -1;
			}
			if(go)
			{
				sws_scale(swsctx,(const uint8_t **)frame->data,frame->linesize,0,map_h,(const uint8_t **)frameRGB->data,frameRGB->linesize);
				lcd_p2=buff;
				NT35310_DisplayStr(lcd_widht/2-strlen(buff_time)/2*16,50,32,buff_time);
				LCD_Image(map_w,map_h,buff);
				Framecount++;
				//printf("frame index:%dn",Framecount);
			}
		}
		else if(packet->stream_index==AVMEDIA_TYPE_AUDIO)/*音頻流*/
		{
			res=avcodec_decode_audio4(audstream->codec,audioframe,&go_audio,packet);
			if(res<0)
			{
				printf("decode_audio4 failedn");
				return -1;
			}
			if(go_audio)//音頻數據處理
			{
			}
		}
	}
	av_free_packet(packet);
	sws_freeContext(swsctx);
	av_frame_free(&frame);
	av_frame_free(&frameRGB);
	avformat_free_context(ps);
	return 0;
}

*3;j+=3)>*w>

??makefile文件

CFLAGS=-I/home/wbyq/tiny4412_pack/ffmpeg-4.2.5/_install/include -L/home/wbyq/tiny4412_pack/ffmpeg-4.2.5/_install/lib 
CFLAGS+=-I/home/wbyq/tiny4412_pack/x264-master/_install/include -L/home/wbyq/tiny4412_pack/x264-master/_install/lib
CFLAGS+= -lpthread -lm -ldl -lavcodec -lavfilter -lavutil -lswresample -lavdevice -lavformat -lpostproc -lswscale -lpthread -lstdc++ -lm -lasound -lx264
OBJ=main.c ascii.c
app:
	arm-linux-gcc -o app $(OBJ) $(CFLAGS)   

4.相關函數介紹

4.1 打開輸入流并讀取頭數據avformat_open_input

int avformat_open_input(AVFormatContext **ps, const char *filename, ff_const59 AVInputFormat *fmt, AVDictionary **options);
函數功能:打開一個輸入流并讀取頭部信息,但編解碼器不會打開
???1.分配一個AVFormatContext的實例。
???2.調用init_input函數初始化輸入流的信息。這里會初始化AVInputFormat。
???3.根據上一步初始化好的AVInputFormat的類型,調用它的read_header方法,讀取文件頭。
形 參: AVFormatContext **ps 媒體文件或媒體流的構成和基本信息
???filename 輸入文件名
???AVInputFormat *fmt 輸入文件格式,一般填NULL即可。
?????如果fmt參數非空,也就是人為的指定了一個AVInputFormat的實例,那么這個函數就不會再檢測輸入文件的格式了;如果fmt為空,那么這個函數就會自動探測輸入文件的格式等信息。
?????AVDictionary **options 附加的一些選項,一般填NULL即可;
返回值: 成功返回0

4.2 查找流信息avformat_find_stream_info

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
函數功能:查找流信息
形參: AVFormatContext *ic 輸入的流信息
???AVDictionary **options 附加的一些選項,一般填NULL即可;
返回值: 成功返回0

4.3 查找輸入流中的音視頻信息av_find_best_stream

int av_find_best_stream(AVFormatContext *ic,
???????????enum AVMediaType type,
???????????int wanted_stream_nb,
??????????? int related_stream,
??????????? AVCodec **decoder_ret,
???????????int flags);
形參: AVFormatContext *ic 輸入的流信息
????type 查找類型AVMEDIA_TYPE_VIDEO視頻、AVMEDIA_TYPE_AUDIO音頻
???? wanted_stream_nb 用戶請求的流編號,-1用于自動選擇,
????related_stream 嘗試查找與此相關的流(例如,在同一程序中),如果沒有,則為-1
????decoder_ret 如果非空,則返回所選流的解碼器,可以填NULL,
???? flags 標志,當前未定義任何
返回值: 成功情況下的非負流編號

4.4 初始化音視頻編解碼器avcodec_open2

int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
函數功能:該函數用于 初始化 一個視音頻編解碼器的AVCodecContext。
形參:avctx 編解碼器上下文
???codec 要打開的編解碼器
???options 一個包含AVcodeContext和編解碼器專用選項的存儲工具。
返回值: 成功返回0,失敗返回負數

4.5 分配一個重采樣swr_alloc_set_opts

struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
???????????int64_t out_ch_layout,
???????????enum AVSampleFormat out_sample_fmt,
???????????int out_sample_rate,
???????????int64_t in_ch_layout,
???????????enum AVSampleFormat in_sample_fmt,
???????????int in_sample_rate,
???????????int log_offset,
???????????void *log_ctx);
函數功能:分配一個重采樣,設置/重置公共參數
形參: s 現有的Swr上下文(如果可用),或NULL(如果不可用)
????out_ch_layout 輸出聲道格式
????out_sample_fmt 輸出采樣頻率
????in_ch_layout 輸入的聲道布局
????in_sample_fmt 輸入采樣格式
????log_offse、log_ctx 日志信息,填0和NULL即可
返回值: 錯誤時為NULL,否則為已分配上下文

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 開源
    +關注

    關注

    3

    文章

    3348

    瀏覽量

    42498
  • 視頻解碼
    +關注

    關注

    1

    文章

    49

    瀏覽量

    18158
  • ffmpeg
    +關注

    關注

    0

    文章

    46

    瀏覽量

    7403
收藏 人收藏

    評論

    相關推薦

    Linux下基于ffmpeg視頻解碼

    FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并能將其轉化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻
    的頭像 發表于 09-29 14:28 ?3621次閱讀
    Linux下基于<b class='flag-5'>ffmpeg</b>音<b class='flag-5'>視頻</b><b class='flag-5'>解碼</b>

    如何移植FFmpeg

    ?FFmpeg是一款專門用于處理數字音頻和視頻,支持錄制、轉換,并能將這些媒體內容轉化為實時流數據的開源計算機程序。它遵循LGPL或GPL許可協議,為用戶提供了涵蓋音視頻錄制、格式轉換及流媒體分發
    的頭像 發表于 06-07 15:28 ?1676次閱讀
    如何<b class='flag-5'>移植</b><b class='flag-5'>FFmpeg</b>

    【OK210申請】基于OK210的WIFI無線視頻監控小車的設計與實現

    申請理由:1.有著對ARM的渴求度,對LINUX有一定的掌握2.本著自己為畢業一年的硬件開發工程師,希望能夠接觸到軟硬結合的ARM系統3.資金有限,只能獲得免費申請4.手里有一塊TINY4412板子
    發表于 08-04 16:34

    免費試用“Tiny4412開發板——友善之臂Cortex-A9”

    本帖最后由 L490351555 于 2015-8-19 08:38 編輯 大家好,這兩天咱們的論壇搞了一個開發板投票試用活動。現在有一個投票項就是“Tiny4412開發板——友善之臂
    發表于 08-18 19:09

    請問在4412的USB驅動程序里該如何修改?

    tiny4412遇到一個問題,4412作為USB設備與作為主機的PC連接,物理連接是USB線,在4412上需要把USB上的特殊數據解析出來,當做并口數據處理。請問在4412的USB驅
    發表于 05-17 00:12

    Tiny4412-Uboot啟動后無法加載uImage

    好吧。。在這里先祈求,有哪位大大,或者老師,能關注下。個人一度試圖移植tiny4412的uboot和kernel還有根文件系統。。。。。然后順帶學習一下設備樹的用法這個是uboot配置ls/dev
    發表于 08-30 05:45

    怎么實現ffmpeg解碼器到龍芯3B的移植

    本文實現ffmpeg解碼器到龍芯3B的移植,并針對龍芯3B實現了對向量擴展指令支持的特點,對ffmpe
    發表于 06-02 06:57

    TINY4412 UART程序設計得相關資料分享

    嵌入式實驗: TINY4412 UART 程序設計一、實驗目的熟悉UART通信相關的寄存器的功能和設置方法,設置引腳復用,選擇UART接收和發送對應的引腳用于UART通信,數據流格式設置,設置
    發表于 11-09 06:11

    如何實現Tiny4412通過NRF24L01 2.4G無線模塊發送數據呢

    Linux下SPI設備驅動該怎樣去編寫呢?如何實現Tiny4412通過NRF24L01 2.4G無線模塊發送數據呢?
    發表于 12-17 06:36

    iny4412嵌入式Linux操作系統啟動流程是怎樣的

    本次介紹一下友善之臂tiny4412嵌入式Linux操作系統分析首先,可以從官方提供的用戶手冊中得到這樣一張圖,它簡單表達了裸機燒寫啟動系統的流程,不過這張圖中缺少對BL2的描述,所以我就自己手繪了
    發表于 12-20 07:50

    基于FFmpeg + SDL2實現視頻播放功能資料分享

    1、使用FFmpeg+SDL2在ART-Pi Smart平臺上實現視頻播放功能簡介X264 是由 VideoLAN 開發的一個免費開源軟件庫和命令行實用程序,用于將視頻流編碼為 H.2
    發表于 08-05 11:40

    FFMPEG視頻解碼流程 H.264硬件編解碼實現

    本文闡述了基于FFMpeg的 H.264視頻 硬件編解碼在 S3C6410 處理器上的實現方法,為數字娛樂、視頻監控和
    發表于 04-03 11:28 ?1.9w次閱讀
    <b class='flag-5'>FFMPEG</b><b class='flag-5'>視頻</b>編<b class='flag-5'>解碼</b>流程 H.264硬件編<b class='flag-5'>解碼</b><b class='flag-5'>實現</b>

    友善之臂Tiny4412核心板介紹

    Tiny4412是一款高性能的四核Cortex-A9核心板,由廣州友善之臂設計、生產和發行銷售。
    的頭像 發表于 11-05 17:40 ?1.2w次閱讀
    友善之臂<b class='flag-5'>Tiny4412</b>核心板介紹

    嵌入式實驗: TINY4412 UART 程序設計

    嵌入式實驗: TINY4412 UART 程序設計一、實驗目的熟悉UART通信相關的寄存器的功能和設置方法,設置引腳復用,選擇UART接收和發送對應的引腳用于UART通信,數據流格式設置,設置
    發表于 11-03 20:06 ?13次下載
    嵌入式實驗: <b class='flag-5'>TINY4412</b> UART 程序設計

    在QT上構建ffmpeg環境實現音頻的解碼

    在QT上構建ffmpeg環境,實現音頻的解碼
    發表于 06-09 09:05 ?1161次閱讀
    在QT上構建<b class='flag-5'>ffmpeg</b>環境<b class='flag-5'>實現</b>音頻的<b class='flag-5'>解碼</b>
    主站蜘蛛池模板: 黄色三级在线看| 成成人看片在线| 天天综合在线观看| 欧美性xxxx极品高清| 在线亚洲综合| 猛操女人| 色综合天天综合网看在线影院 | 亚州视频一区二区| 日本三级日产三级国产三级| 一级特黄a 大片免费| 很黄的网站在线观看| 色婷婷亚洲十月十月色天| 成年片免费网址网站| 欧美性色综合网| 四虎影院在线免费观看视频| 超级碰碰青草久热国产| 五月丁五月丁开行停停乱| 四虎新网站| 亚洲高清日韩精品第一区| 亚洲视频入口| 欧美freesex| 久久v| 亚洲aⅴ久久久噜噜噜噜| 成年看片免费高清观看| 奇米影视亚洲四色8888| 三级在线免费观看| 天天操国产| 在线看av的网址| www.黄网| 人人澡人人添| 狠狠色视频| kkk4444免费观看| 免费的色网站| 99久久免费午夜国产精品| 色婷婷色综合缴情在线| 人人爱天天做夜夜爽毛片| 亚洲人成亚洲人成在线观看| 夜夜做夜夜爽| 在线看片一区| 有坂深雪在线| 在线天堂中文新版www|