一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux下基于ffmpeg音視頻解碼

嵌入式技術(shù) ? 來(lái)源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-09-29 14:28 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

Linux下基于ffmpeg音視頻解碼

1.ffmpeg簡(jiǎn)介

FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻編解碼庫(kù)libavcodec,為了保證高可移植性和編解碼質(zhì)量,libavcodec里很多code都是從頭開(kāi)發(fā)的。
Fmpeg 是領(lǐng)先的多媒體框架,能夠解碼、編碼、轉(zhuǎn)碼、混合、解密、流媒體、過(guò)濾和播放人類(lèi)和機(jī)器創(chuàng)造的幾乎所有東西。它支持最晦澀的古老格式,直到最尖端的格式。無(wú)論它們是由某個(gè)標(biāo)準(zhǔn)委員會(huì)、社區(qū)還是公司設(shè)計(jì)的。它還具有高度的便攜性。

2.ffmpeg八大庫(kù)介紹

poYBAGM1OvOANQ4qAAJCJONC5QA301.png#pic_center
  • avutil工具庫(kù)

avutil: 工具庫(kù)(大部分庫(kù)都需要這個(gè)庫(kù)的支持),如AVLog日志輸出、AVOption (AVClass)選項(xiàng)設(shè)置、AVDictionary鍵值對(duì)存儲(chǔ)、ParseUtil字符串解析等;

  • avcodec編解碼庫(kù)

avcodec: 編解碼(最重要的庫(kù)) 。其中AVCodec是存儲(chǔ)編解碼器信息的結(jié)構(gòu)體,包含了解協(xié)議,解封裝,解碼操作;
AVCodec結(jié)構(gòu)體中重點(diǎn)參數(shù)說(shuō)明:

const char *name:編解碼器的名字,比較短
const char *long_name:編解碼器的名字,全稱,比較長(zhǎng)
enum AVMediaType type:指明了類(lèi)型,是視頻,音頻,還是字幕
enum AVCodecID id:ID,音視頻流ID信息,枚舉類(lèi)型
const AVRational *supported_framerates:支持的幀率(僅視頻)
const enum AVPixelFormat *pix_fmts:支持的像素格式(僅視頻)
const int *supported_samplerates:支持的采樣率(僅音頻)
const enum AVSampleFormat *sample_fmts:支持的采樣格式(僅音頻)
const uint64_t *channel_layouts:支持的聲道數(shù)(僅音頻)
int priv_data_size:私有數(shù)據(jù)的大小
  • avformat: 封裝格式處理
    ??AVFormatContext是一個(gè)貫穿始終的數(shù)據(jù)結(jié)構(gòu),很多函數(shù)都要用到它作為參數(shù)。它是FFMPEG解封裝(flv,mp4,rmvb,avi)功能的結(jié)構(gòu)體。
AVIOContext *pb;字節(jié)流IO上下文
unsigned int nb_streams;音視頻流個(gè)數(shù)
AVStream **streams;音視頻流
char filename[1024];輸入輸出文件名
int64_t duration;流持續(xù)時(shí)間,即總時(shí)長(zhǎng),單位為us
int bit_rate:比特率(碼率)(單位bps,轉(zhuǎn)換為kbps需要除以1000)
AVDictionary *metadata:元數(shù)據(jù)
  • avdevice: 各種設(shè)備的輸入輸出

可以讀取電腦(或其他設(shè)備上)的多媒體設(shè)備的數(shù)據(jù),或者輸出到指定的多媒體設(shè)備上。

  • avfilter: 濾鏡特效處理

libavfilter提供了一個(gè)通用的音視頻filter框架。使用avfilter可以對(duì)音視頻數(shù)據(jù)做一些效果處理如去色調(diào)、模糊、水平翻轉(zhuǎn)、裁剪、加方框、疊加文字等功能。

  • swscale: 視頻像素?cái)?shù)據(jù)格式轉(zhuǎn)換

libswscale 是 FFmpeg 中完成圖像尺寸縮放和像素格式轉(zhuǎn)換的庫(kù)。用戶可以編寫(xiě)程序,調(diào)用 libswscale 提供的 API 來(lái)進(jìn)行圖像尺寸縮放和像素格式轉(zhuǎn)換。
?? libswscale中常用函數(shù):

sws_getContext();初始化一個(gè)SwsContext。
sws_scale();處理圖像數(shù)據(jù)。
sws_freeContext();釋放一個(gè)SwsContext。
  • swresample: 音頻采樣數(shù)據(jù)格式轉(zhuǎn)換

libswresample庫(kù)功能主要包括高度優(yōu)化的音頻重采樣、rematrixing和樣本格式轉(zhuǎn)換操作。

  • postproc:后加工

(同步、時(shí)間計(jì)算的簡(jiǎn)單算法)用于后期效果處理;

3.ffmpeg解碼流程

  1. 打開(kāi)文件avformat_open_input;
  2. 尋找解碼器avformat_find_stream_info;
  3. 尋找音視頻流信息av_find_best_stream;
  4. 尋找音視頻解碼器avcodec_find_decoder;
  5. 配置音頻參數(shù):聲道、采樣格式、采樣率、樣本數(shù)量、通道個(gè)數(shù),進(jìn)行音頻重采樣swr_alloc_set_opts(音頻格式轉(zhuǎn)碼);
  6. 配置視頻解碼參數(shù):分配視頻幀,申請(qǐng)存放圖像數(shù)據(jù)空間,計(jì)算一幀空間大小,進(jìn)行圖像轉(zhuǎn)碼sws_getContext;
  7. 初始化SDL,實(shí)現(xiàn)圖像渲染和音頻播放;
  8. 讀取數(shù)據(jù)包av_read_frame,實(shí)現(xiàn)視頻解析和音頻解析;

4.ffmpeg解碼示例

  • 開(kāi)發(fā)環(huán)境
開(kāi)發(fā)平臺(tái): ubuntu18.04.6
ffmpeg版本: 4.2.5
SDL版本: 2.0.14
  • 工程示例
#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 "123.flv"
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef enum
{
	false,
	true,
}bool;
uint8_t *out_buffer;
#define MAX_AUDIO_FRAME_SIZE 1024*100 
static Uint8* audio_chunk; 
static unsigned int audio_len=0;
static unsigned char *audio_pos;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//互斥鎖

//保存音頻數(shù)據(jù)鏈表
struct AUDIO_DATA
{
	unsigned char* audio_buffer;
	int audio_size;
	struct AUDIO_DATA *next;
};
//定義一個(gè)鏈表頭
struct AUDIO_DATA *list_head=NULL;
struct AUDIO_DATA *List_CreateHead(struct AUDIO_DATA *head);//創(chuàng)建鏈表頭
void List_AddNode(struct AUDIO_DATA *head,unsigned char* audio_buffer,int audio_size);//添加節(jié)點(diǎn)
void List_DelNode(struct AUDIO_DATA *head,unsigned char* audio_buffer);//刪除節(jié)點(diǎn)
int List_GetNodeCnt(struct AUDIO_DATA *head);//遍歷
int List_GetNode(struct AUDIO_DATA *head,char *audio_buff,int *audio_size);

int file_stat=1;

void  AudioCallback(void *userdata, Uint8 * stream,int len)
{
	SDL_memset(stream, 0,len);
	if(audio_len<=0)
	{
		return ;
	}
	len=(len>audio_len?audio_len:len);
	SDL_MixAudio(stream,audio_pos,len,SDL_MIX_MAXVOLUME);
	audio_pos+=len;
	audio_len-=len;
	//printf("len=%dn",len);
}

void *Audio_decode(void *arg)
{
	int res;
	int audio_size;
	char audio_buff[4096*3];
	while(1)
	{
		res=List_GetNode(list_head,audio_buff,&audio_size);
		if(res==0)
		{
			audio_chunk = audio_buff; //指向音頻數(shù)據(jù) (PCM data)
			while(audio_len>0){}//等待數(shù)據(jù)處理完
			audio_len =audio_size;//音頻長(zhǎng)度
			audio_pos = audio_buff;//當(dāng)前播放位置
		}
	}
}
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("格式:./app 文件名n");
		return 0;
	}
	char *file_name=argv[1];
	/*SDL初始化*/
	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_TIMER);
	printf("pth:%sn",avcodec_configuration());/*獲取ffmpeg配置信息*/
	/*初始化所有組件*/
	//av_register_all();
	/*打開(kāi)文件*/
	AVCodecContext  *pCodecCtx;//解碼器上下文
	AVFormatContext *ps=NULL;//音視頻封裝格式結(jié)構(gòu)體信息
	printf("name:%sn",file_name);
	int res=avformat_open_input(&ps,file_name,NULL,NULL);
	if(res!=0)
	{
		printf("open err: %dn",res);
		return 0;
	}
	/*尋找解碼信息*/
	avformat_find_stream_info(ps,NULL);
	int64_t time=ps->duration;
	printf("time:%ld sn",time/1000000);
	/*打印有關(guān)輸入或輸出格式的詳細(xì)信息*/
	av_dump_format(ps,0,file_name,0);
	/*尋找視頻流信息*/
	int videostream=-1;
	int audiostream=-1;
	AVCodec *vcodec;
	videostream=av_find_best_stream(ps,AVMEDIA_TYPE_VIDEO,-1,-1,NULL, 0);
	printf("video=%dn",videostream);
	/*尋找音頻流信息*/
	audiostream=av_find_best_stream(ps,AVMEDIA_TYPE_AUDIO,-1,-1,NULL, 0);
	printf("audio=%dn",audiostream);
	AVStream *stream;
	int frame_rate;
	if(videostream!=-1)//判斷是否找到視頻流數(shù)據(jù)
	{
		/*尋找視頻解碼器*/
		AVStream *stream = ps->streams[videostream];
		vcodec=avcodec_find_decoder(stream->codecpar->codec_id);
		if(!vcodec)
		{
			printf("未找到視頻解碼器n");
			return -1;
		}/*申請(qǐng)AVCodecContext空間。需要傳遞一個(gè)編碼器,也可以不傳,但不會(huì)包含編碼器。*/
		res=avcodec_open2(stream->codec,vcodec,NULL);
		if(res)
		{
			printf("打開(kāi)解碼器失敗n");
			return -1;
		}
		frame_rate=stream->avg_frame_rate.num/stream->avg_frame_rate.den;//每秒多少幀
		printf("fps=%dn",frame_rate);
		printf("視頻流ID=%#xn",vcodec->id);//音頻流
	}
	/*音頻流數(shù)據(jù)處理*/
	AVCodec *audcodec;
	AVStream *audstream;
	SwrContext *swrCtx;//保存重采樣數(shù)據(jù),即解碼的信息
	uint64_t out_channel_layout;//聲道
	int out_sample_fmt;//采樣格式
	int out_sample_rate;//采樣率
	int out_nb_samples;//樣本數(shù)量
	int out_channels;//通道數(shù)量
	uint64_t in_channel_layout;//輸入音頻聲道
	SDL_AudioSpec desired;//SDL音頻格式信息
	AVFrame *audioframe;//保存音頻數(shù)據(jù)
	int out_buffer_size;//音頻緩沖區(qū)大小
	if(audiostream>=0)//判斷是否有音頻流
	{
		/*尋找音頻解碼器*/
		audstream = ps->streams[audiostream];
		audcodec=avcodec_find_decoder(audstream->codecpar->codec_id);
		if(!audcodec)
		{
			printf("audcodec failedn");
			return -1;
		}
		/*申請(qǐng)音頻AVCodecContext空間。需要傳遞一個(gè)編碼器,也可以不傳,但不會(huì)包含編碼器。*/
		pCodecCtx=audstream->codec;//解碼器上下文
		res=avcodec_open2(audstream->codec,audcodec,NULL);
		if(res)
		{
			printf("未找到音頻解碼器n");
			return -1;
		}
		printf("音頻流ID=%#xn",audcodec->id);//音頻流
		printf("配置音頻參數(shù)n");
		//輸出音頻參數(shù)
		out_channel_layout  = AV_CH_LAYOUT_STEREO;  //聲道格式
		out_sample_fmt=AV_SAMPLE_FMT_S16;//AV_SAMPLE_FMT_S32;//;//采樣格式
		printf("pCodecCtx->sample_rate=%dn",pCodecCtx->sample_rate);
		out_sample_rate =pCodecCtx->sample_rate;//采樣率,多為44100
		/*樣本數(shù)量*/
		printf("frame_size=%dn",pCodecCtx->frame_size);
		if(pCodecCtx->frame_size>0)out_nb_samples=pCodecCtx->frame_size;
		else if(audcodec->id == AV_CODEC_ID_AAC) out_nb_samples=1024;/*樣本數(shù)量nb_samples: AAC-1024 MP3-1152  格式大小 */
		else if(audcodec->id == AV_CODEC_ID_MP3)out_nb_samples=1152;
		else out_nb_samples=1024;
		out_channels=av_get_channel_layout_nb_channels(out_channel_layout);//通道個(gè)數(shù)
		out_buffer_size=av_samples_get_buffer_size(NULL,out_channels,out_nb_samples,out_sample_fmt,1);//獲取緩沖區(qū)大小
		out_buffer=(uint8_t*)av_malloc(MAX_AUDIO_FRAME_SIZE);
		memset(out_buffer,0,out_buffer_size);
		printf("聲道格式:%dn",out_channel_layout);
		printf("采樣格式:%dn",out_sample_fmt);	
		printf("樣本數(shù)量:%dn",out_nb_samples);	
		printf("采樣率:%dn",out_sample_rate);
		printf("通道個(gè)數(shù):%dn",out_channels);
		printf("緩沖區(qū)大小:%dn",out_buffer_size);
		//輸入音頻參數(shù)
		in_channel_layout=av_get_default_channel_layout(pCodecCtx->channels);//輸入聲道格式
		swrCtx = swr_alloc();
		/*對(duì)解碼數(shù)據(jù)進(jìn)行重采樣*/
		swrCtx=swr_alloc_set_opts(swrCtx,out_channel_layout,out_sample_fmt,out_sample_rate,/*輸入音頻格式*/
								in_channel_layout,pCodecCtx->sample_fmt,pCodecCtx->sample_rate,/*輸出音頻格式*/
								0,NULL);				
		swr_init(swrCtx);//初始化swrCtx
		
		printf("輸入音頻格式:%dn",in_channel_layout);
		printf("輸入采樣格式:%dn",pCodecCtx->sample_fmt);
		printf("輸入采樣率:%dn",pCodecCtx->sample_rate);
		
		/*設(shè)置音頻數(shù)據(jù)格式*/
		desired.freq=out_sample_rate;/*采樣率*/
		desired.format=AUDIO_S16SYS;/*無(wú)符號(hào)16位*/
		desired.channels=out_channels;/*聲道*/
		desired.samples=out_nb_samples;/*樣本數(shù)1024*/
		desired.silence=0;/*靜音值*/
		desired.callback=AudioCallback;
		SDL_OpenAudio(&desired,NULL);
		SDL_PauseAudio(0);/*開(kāi)始播放音頻,1為播放靜音值*/
		//分配內(nèi)存
		audioframe=av_frame_alloc();/*分配音頻幀*/
		printf("音頻數(shù)據(jù)初始化完成");
	}
	//視頻解碼
	AVFrame *frame=av_frame_alloc();/*分配視頻幀*/
	AVFrame *frameYUV=av_frame_alloc();/*申請(qǐng)yuv空間*/
	/*分配空間,進(jìn)行圖像轉(zhuǎn)換*/
	int width=ps->streams[videostream]->codecpar->width;
	int height=ps->streams[videostream]->codecpar->height;
	int fmt=ps->streams[videostream]->codecpar->format;/*流格式*/
	printf("fmt=%dn",fmt);
	int size=avpicture_get_size(AV_PIX_FMT_RGB24, width,height);
	unsigned char *buff=NULL;
	printf("w=%d,h=%d,size=%dn",width,height,size);
	buff=av_malloc(size);
	/*計(jì)算一幀空間大小*/
	avpicture_fill((AVPicture *)frameYUV,buff,AV_PIX_FMT_RGB24,width,height);
	/*轉(zhuǎn)換上下文*/
	struct SwsContext *swsctx=sws_getContext(width,height, fmt,width,height, AV_PIX_FMT_RGB24,SWS_BICUBIC,NULL,NULL,NULL);
	/*讀幀*/
	int go=0;
	int go_audio;	
	list_head=List_CreateHead(list_head);//創(chuàng)建鏈表頭
	/*創(chuàng)建音頻處理線程*/
	pthread_t pthid;
	pthread_create(&pthid,NULL,Audio_decode,(void *)ps);
	pthread_detach(pthid);//設(shè)置為分離屬性
	/*創(chuàng)建窗口*/
	SDL_Window *window=SDL_CreateWindow("SDL_VIDEO", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,1280,720,SDL_WINDOW_SHOWN);
	/*創(chuàng)建渲染器*/
	SDL_Renderer *render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
	/*清空渲染器*/
	SDL_RenderClear(render);	
	/*創(chuàng)建紋理*/
	SDL_Texture *sdltext=SDL_CreateTexture(render,SDL_PIXELFORMAT_RGB24,SDL_TEXTUREACCESS_STREAMING,width,height);		
	bool quit=true;
	SDL_Event event;
	printf("read fream buffn");
	//初始化轉(zhuǎn)碼器
	AVPacket *packet=av_malloc(sizeof(AVPacket));/*分配包*/
	av_init_packet(packet);//初始化
	int i=0;
	int index=0;
	long video_pts_time=0;
	long audio_pts_time=0;//音頻解碼時(shí)間
	time=(1000000/frame_rate-10000);//時(shí)間
	printf("time=%dn",time);
	while((av_read_frame(ps,packet)>=0) && (quit))
	{
		SDL_PollEvent(&event);
		if(event.type==SDL_QUIT)
		{
			quit=false;
			continue;
		}
		if(packet->stream_index == videostream)/*判斷是否為視頻*/
		{
			res=avcodec_send_packet(ps->streams[videostream]->codec,packet);
			if(res)
			{
				av_packet_unref(packet);//釋放這個(gè)pkt
				continue;
			}
			
			res=avcodec_receive_frame(ps->streams[videostream]->codec,frame);
			if(res)
			{
				av_packet_unref(packet);//釋放這個(gè)pkt	
				continue;
			}
			sws_scale(swsctx,(const uint8_t **)frame->data,frame->linesize,0,height,(const uint8_t **)frameYUV->data,frameYUV->linesize);
			video_pts_time=packet->pts;
			//printf("視頻=%ldn",video_pts_time);
			SDL_UpdateTexture(sdltext,NULL,buff, width*3);
			SDL_RenderCopy(render, sdltext, NULL, NULL); // 拷貝紋理到渲染器
			SDL_RenderPresent(render); //渲染
			usleep(time);
		}
		if(packet->stream_index == audiostream)  //如果為音頻標(biāo)志
		{
			if(audiostream<0)continue;
			res=avcodec_send_packet(pCodecCtx,packet);
			if(res)
			{
				printf("avcodec_send_packet failed,res=%dn",res);
				av_packet_unref(packet);//釋放這個(gè)pkt	
				continue;
			}
			res=avcodec_receive_frame(pCodecCtx,audioframe);
			if(res)
			{
				printf("avcodec_receive_frame failed,res=%dn",res);
				av_packet_unref(packet);//釋放這個(gè)pkt
				continue;
			}
			//數(shù)據(jù)格式轉(zhuǎn)換
			res=swr_convert(swrCtx,&out_buffer,out_buffer_size,/*重采樣之后的數(shù)據(jù)*/
						(const uint8_t **)audioframe->data,audioframe->nb_samples/*重采樣之前數(shù)據(jù)*/
						);
			audio_pts_time=packet->pts;
			//printf("音頻:%ldn",audio_pts_time);
			if(res>0)
			{
				//audio_chunk =out_buffer; //指向音頻數(shù)據(jù) (PCM data)
				//while(audio_len>0){}//等待數(shù)據(jù)處理完
				//audio_len =audioframe->nb_samples;//out_buffer_size;//音頻長(zhǎng)度
				//audio_pos =out_buffer;//當(dāng)前播放位置
				List_AddNode(list_head,out_buffer,out_buffer_size);//添加節(jié)點(diǎn)
			}
		}
		//釋放數(shù)據(jù)包
		av_packet_unref(packet);
	}
	sws_freeContext(swsctx);
	av_frame_free(&frame);
	av_frame_free(&frameYUV);
	avformat_free_context(ps);
	return 0;
}
/*創(chuàng)建鏈表頭*/
struct AUDIO_DATA *List_CreateHead(struct AUDIO_DATA *head)
{
	if(head==NULL)
	{
		head=malloc(sizeof(struct AUDIO_DATA));
		head->next=NULL;
	}
	return head;	
}

/*添加節(jié)點(diǎn)*/
void List_AddNode(struct AUDIO_DATA *head,unsigned char* audio_buffer,int audio_size)
{
	struct AUDIO_DATA *tmp=head;
	struct AUDIO_DATA *new_node;
	pthread_mutex_lock(&mutex);
	/*找到鏈表尾部*/
	while(tmp->next)
	{
		tmp=tmp->next;
	}
	/*插入新的節(jié)點(diǎn)*/
	new_node=malloc(sizeof(struct AUDIO_DATA));
	new_node->audio_size=audio_size;
	new_node->audio_buffer=malloc(audio_size);//分配保存音頻數(shù)據(jù)大小空間
	memcpy(new_node->audio_buffer,audio_buffer,audio_size);
	new_node->next=NULL;
	/*將新節(jié)點(diǎn)接入到鏈表*/
	tmp->next=new_node;	
	pthread_mutex_unlock(&mutex);
}
/*
函數(shù)功能:刪除節(jié)點(diǎn)
*/
void List_DelNode(struct AUDIO_DATA *head,unsigned char* audio_buffer)
{
	struct AUDIO_DATA *tmp=head;
	struct AUDIO_DATA *p;
	/*找到鏈表中要?jiǎng)h除的節(jié)點(diǎn)*/
	pthread_mutex_lock(&mutex);
	while(tmp->next)
	{
		p=tmp;
		tmp=tmp->next;
		if(tmp->audio_buffer==audio_buffer)
		{
			p->next=tmp->next;
			free(tmp->audio_buffer);
			free(tmp);
			break;
		}
	}
	pthread_mutex_unlock(&mutex);
}
/*
函數(shù)功能:遍歷鏈表,得到節(jié)點(diǎn)總數(shù)量
*/
int List_GetNodeCnt(struct AUDIO_DATA *head)
{
	int cnt=0;
	struct AUDIO_DATA *tmp=head;
	pthread_mutex_lock(&mutex);
	while(tmp->next)
	{
		tmp=tmp->next;
		cnt++;
	}
	pthread_mutex_unlock(&mutex);
	return cnt;
}
/*
從鏈表頭取數(shù)據(jù)
*/
int List_GetNode(struct AUDIO_DATA *head,char *audio_buff,int *audio_size)
{
	struct AUDIO_DATA *tmp=head;
	struct AUDIO_DATA *ptemp=head;
	pthread_mutex_lock(&mutex);
	while(tmp->next!=NULL)
	{
		ptemp=tmp;
		tmp=tmp->next;
		
		if(tmp!=NULL)
		{
			*audio_size=tmp->audio_size;
			memcpy(audio_buff,tmp->audio_buffer,tmp->audio_size);
			ptemp->next=tmp->next;
			free(tmp->audio_buffer);
			free(tmp);
			pthread_mutex_unlock(&mutex);
			return 0;
		}
	}
	pthread_mutex_unlock(&mutex);
	return -1;
}
  • Makefile文件
OBJ=main.o
CFLAGS=-I/home/wbyq/src_pack/ffmpeg-4.2.5/_install/include -L/home/wbyq/src_pack/ffmpeg-4.2.5/_install/lib
-I/home/wbyq/src_pack/SDL2-2.0.14/_install/include -I/home/wbyq/src_pack/SDL2-2.0.14/_install/include/SDL2 -L/home/wbyq/src_pack/SDL2-2.0.14/_install/lib 
-lSDL2 -lpthread -lm -ldl  -lavcodec -lavfilter -lavutil -lswresample -lavdevice -lavformat -lpostproc -lswscale -lpthread -lstdc++ -lm -lasound -lx264
app:$(OBJ)
	gcc -o $@ $^ $(CFLAGS)  

  • 運(yùn)行示例
pYYBAGM1OvOAfAfWAAj_fYOpR5U378.png#pic_centerpoYBAGM1OvSAaXklAAQ70R2x0y8093.png#pic_center

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5145

    文章

    19597

    瀏覽量

    316141
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11496

    瀏覽量

    213225
  • 嵌入式開(kāi)發(fā)

    關(guān)注

    18

    文章

    1075

    瀏覽量

    48707
  • 音視頻
    +關(guān)注

    關(guān)注

    4

    文章

    524

    瀏覽量

    30435
  • ffmpeg
    +關(guān)注

    關(guān)注

    0

    文章

    46

    瀏覽量

    7657
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    【RTC程序設(shè)計(jì):實(shí)時(shí)音視頻權(quán)威指南】音視頻的編解碼壓縮技術(shù)

    音視頻所載有的信息在通過(guò)傳輸?shù)臅r(shí)候就需要壓縮編碼。 其中,文本壓縮是指通過(guò)使用各種算法和技術(shù),將文本數(shù)據(jù)表示為更緊湊的形式,以減少存儲(chǔ)空間。 霍夫曼編碼是一種無(wú)損壓縮算法,它可以根據(jù)字符出現(xiàn)
    發(fā)表于 04-28 21:04

    數(shù)字音視頻解碼技術(shù)與標(biāo)準(zhǔn)

    數(shù)字音視頻解碼技術(shù)與標(biāo)準(zhǔn)數(shù)字電視技術(shù)標(biāo)準(zhǔn)的范疇?? 信道傳輸技術(shù)標(biāo)準(zhǔn)– 衛(wèi)星傳輸– 有線傳輸(浙大)– 地面?zhèn)鬏敚ㄇ迦A、上交大)?? 信源編解碼技術(shù)標(biāo)準(zhǔn)(本工作組)– 數(shù)據(jù)與命令格式(系統(tǒng)
    發(fā)表于 06-04 13:49

    dm8168 音視頻同步問(wèn)題

    我在8168上用dvrrdk 4.0.03做音視頻,我的視頻和音頻都來(lái)自網(wǎng)絡(luò),經(jīng)過(guò)解碼處理后,再編碼,但是編碼后的視頻音頻數(shù)據(jù)有同步的問(wèn)題,rdk里面有沒(méi)有什么接口或者API能讓
    發(fā)表于 06-23 04:51

    基于ARM Linux的無(wú)線音視頻對(duì)講系統(tǒng)

    新一代視頻解碼標(biāo)準(zhǔn)H.264進(jìn)行編譯碼,并通過(guò)無(wú)線網(wǎng)絡(luò)傳輸音視頻。它充分利用S3C6410微處理器內(nèi)部集成的多媒體編解碼器(Multi-FormatvideoCodec,MFC),有
    發(fā)表于 07-24 13:48

    音視頻解碼的標(biāo)準(zhǔn)

    音視頻解碼標(biāo)準(zhǔn)簡(jiǎn)介
    發(fā)表于 01-21 06:53

    什么是音視頻同步?音視頻同步的影響因素有哪些?

    什么是音視頻同步?有什么要求?音視頻同步的影響因素有哪些?音視頻同步的常見(jiàn)技術(shù)有哪些?
    發(fā)表于 06-15 08:48

    FFMPEG如何進(jìn)行音視頻同步的

    精妙絕倫,完全不用擔(dān)心隨著時(shí)間的推移會(huì)發(fā)生如上問(wèn)題!下面簡(jiǎn)述FFMPEG如何進(jìn)行音視頻同步的吧!  FFMPEG有三種同步方式,
    發(fā)表于 08-23 16:27

    音視頻

    對(duì)音視頻技術(shù)都喜歡深究?jī)?nèi)部最核心的原理和機(jī)制,尤其是ffmpeg這個(gè)編解碼庫(kù),可以說(shuō)是音視頻領(lǐng)域事實(shí)上的標(biāo)準(zhǔn)。語(yǔ)音智能算法,語(yǔ)言語(yǔ)義分析和理解,流媒體服務(wù)器等高端技術(shù)也都基于它而構(gòu)建。
    發(fā)表于 11-23 08:51

    數(shù)字音視頻解碼技術(shù)(AVS標(biāo)準(zhǔn))

    數(shù)字音視頻解碼技術(shù)標(biāo)準(zhǔn)AVS黃鐵軍數(shù)字音視頻解碼標(biāo)準(zhǔn)是數(shù)字音視頻產(chǎn)業(yè)的共性基礎(chǔ)標(biāo)準(zhǔn),具有巨大的產(chǎn)業(yè)需求。跨入新世紀(jì)以來(lái),隨著編
    發(fā)表于 08-25 12:43 ?63次下載

    基于MIPS體系結(jié)構(gòu)的嵌入式MPEG-2音視頻解碼設(shè)計(jì)

    本文介紹了基于MIPS體系結(jié)構(gòu)的32位SOC芯片 GC3210和嵌入式Linux操作系統(tǒng)的MPEG-2音視頻解碼器的軟件優(yōu)化以及音視頻同步機(jī)制的設(shè)計(jì)。采用多媒體指令對(duì)MPEG-2
    發(fā)表于 02-24 11:40 ?18次下載

    IPTV音視頻解碼技術(shù)

    IPTV音視頻解碼技術(shù) 三足鼎立   當(dāng)前在IPTV業(yè)務(wù)中,音視頻解碼技術(shù)的選擇呈現(xiàn)了三足鼎立的狀況,即MPEG4ASP、H.264和AVS。其中MPEG4和H.264都是國(guó)
    發(fā)表于 11-27 10:04 ?1124次閱讀

    ffmpeg支持的音視頻格式有哪些

    FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序。采用LGPL或GPL許可證。它提供了錄制、轉(zhuǎn)換以及流化音視頻的完整解決方案。它包含了非常先進(jìn)的音頻/視頻
    發(fā)表于 11-01 08:43 ?2.3w次閱讀

    音視頻解碼生成與流媒體傳輸?shù)慕Y(jié)合

    音視頻解碼生成與流媒體傳輸是現(xiàn)代數(shù)字媒體技術(shù)中兩個(gè)不可或缺的部分,它們的結(jié)合為用戶提供了高質(zhì)量、實(shí)時(shí)性的多媒體體驗(yàn)。 1. 解碼生成與流媒體傳輸?shù)年P(guān)系 解碼生成是流媒體傳輸?shù)那疤帷T诹?/div>
    的頭像 發(fā)表于 02-21 14:36 ?654次閱讀

    音視頻解碼生成常見(jiàn)問(wèn)題及解決方案

    音視頻解碼生成的過(guò)程中,我們可能會(huì)遇到一些常見(jiàn)問(wèn)題,這些問(wèn)題可能會(huì)影響解碼的效果和效率。以下是一些常見(jiàn)問(wèn)題及其解決方案: 問(wèn)題1:解碼失敗 原因 :可能是文件本身有問(wèn)題,如損壞或格式
    的頭像 發(fā)表于 02-21 14:39 ?2381次閱讀

    音視頻解碼器優(yōu)化技巧:提升播放體驗(yàn)的關(guān)鍵步驟

    播放效果呢?以下是幾個(gè)關(guān)鍵步驟。 1. 選擇合適的解碼器 不同的解碼器在處理不同類(lèi)型和格式的音視頻文件時(shí),性能可能會(huì)有所不同。因此,選擇適合您需求的解碼器至關(guān)重要。對(duì)于大多數(shù)常見(jiàn)的
    的頭像 發(fā)表于 02-21 14:45 ?1480次閱讀