ffmpeg h264+ts +udp传输
http://bbs.csdn.net/topics/370246456
http://1229363.blog.163.com/blog/static/19743427201001244711137/?ffmpeg windows 下編譯
http://www.360doc.com/content/13/0913/15/13084517_314201133.shtml?h264幀邊界識別
http://fs-linux.org/forum.php?mod=viewthread&tid=21&extra=page%3D1&page=2?ffmpeg 轉碼樣例
http://www.360doc.com/content/09/0427/20/59579_3292893.shtml?h264 nal技術
http://bbs.csdn.net/topics/390217270?qt 范例
?
?
最近遇到好幾個人在問ffmpeg如何處理網絡流,剛好前段時間也在做這方面,抽空整理了下,把主要代碼發出來,希望對大家有用。為簡單處理,我這里只簡單介紹UDP接收TS流,其實只要是socket接收的都可以類似處理。
/*
?*?main.c
?*
?*??Created?on:?2011-9-18
?*??????Author:?wudegang
?*/
#include?"utils.h"
#include?<pthread.h>
#include?<libavcodec/avcodec.h>
#include?<libavformat/avformat.h>
UdpQueue?recvqueue;
UdpParam?udpParam;
//注冊av_read_frame的回調函數,這里只是最簡處理,實際應用中應加上出錯處理,超時等待...
int?read_data(void?*opaque,?uint8_t?*buf,?int?buf_size)?{
int?size?=?buf_size;
int?ret;
// printf("read?data?%d\n",?buf_size);
do?{
ret?=?get_queue(&recvqueue,?buf,?buf_size);
}?while?(ret);
// printf("read?data?Ok?%d\n",?buf_size);
return?size;
}
#define?BUF_SIZE 4096*500
int?main(int?argc,?char**?argv)?{
init_queue(&recvqueue,?1024*500);
udpParam.argv?=?argv;
udpParam.queue?=?&recvqueue;
uint8_t?*buf?=?av_mallocz(sizeof(uint8_t)*BUF_SIZE);
//UDP接收線程
pthread_t?udp_recv_thread;
pthread_create(&udp_recv_thread,?NULL,?udp_ts_recv,?&udpParam);
pthread_detach(udp_recv_thread);
av_register_all();
AVCodec?*pVideoCodec,?*pAudioCodec;
AVCodecContext?*pVideoCodecCtx?=?NULL;
AVCodecContext?*pAudioCodecCtx?=?NULL;
AVIOContext?*?pb?=?NULL;
AVInputFormat?*piFmt?=?NULL;
AVFormatContext?*pFmt?=?NULL;
//step1:申請一個AVIOContext
pb?=?avio_alloc_context(buf,?BUF_SIZE,?0,?NULL,?read_data,?NULL,?NULL);
if?(!pb)?{
fprintf(stderr,?"avio?alloc?failed!\n");
return?-1;
}
//step2:探測流格式
if?(av_probe_input_buffer(pb,?&piFmt,?"",?NULL,?0,?0)?<?0)?{
fprintf(stderr,?"probe?failed!\n");
return?-1;
}?else?{
fprintf(stdout,?"probe?success!\n");
fprintf(stdout,?"format:?%s[%s]\n",?piFmt->name,?piFmt->long_name);
}
pFmt?=?avformat_alloc_context();
pFmt->pb?=?pb; //step3:這一步很關鍵
//step4:打開流
if?(avformat_open_input(&pFmt,?"",?piFmt,?NULL)?<?0)?{
fprintf(stderr,?"avformat?open?failed.\n");
return?-1;
}?else?{
fprintf(stdout,?"open?stream?success!\n");
}
//以下就和文件處理一致了
if?(av_find_stream_info(pFmt)?<?0)?{
fprintf(stderr,?"could?not?fine?stream.\n");
return?-1;
}
av_dump_format(pFmt,?0,?"",?0);
int?videoindex?=?-1;
int?audioindex?=?-1;
for?(int?i?=?0;?i?<?pFmt->nb_streams;?i++)?{
if?(?(pFmt->streams[i]->codec->codec_type?==?AVMEDIA_TYPE_VIDEO)?&&
(videoindex?<?0)?)?{
videoindex?=?i;
}
if?(?(pFmt->streams[i]->codec->codec_type?==?AVMEDIA_TYPE_AUDIO)?&&
(audioindex?<?0)?)?{
audioindex?=?i;
}
}
if?(videoindex?<?0?||?audioindex?<?0)?{
fprintf(stderr,?"videoindex=%d,?audioindex=%d\n",?videoindex,?audioindex);
return?-1;
}
AVStream?*pVst,*pAst;
pVst?=?pFmt->streams[videoindex];
pAst?=?pFmt->streams[audioindex];
pVideoCodecCtx?=?pVst->codec;
pAudioCodecCtx?=?pAst->codec;
pVideoCodec?=?avcodec_find_decoder(pVideoCodecCtx->codec_id);
if?(!pVideoCodec)?{
fprintf(stderr,?"could?not?find?video?decoder!\n");
return?-1;
}
if?(avcodec_open(pVideoCodecCtx,?pVideoCodec)?<?0)?{
fprintf(stderr,?"could?not?open?video?codec!\n");
return?-1;
}
pAudioCodec?=?avcodec_find_decoder(pAudioCodecCtx->codec_id);
if?(!pAudioCodec)?{
fprintf(stderr,?"could?not?find?audio?decoder!\n");
return?-1;
}
if?(avcodec_open(pAudioCodecCtx,?pAudioCodec)?<?0)?{
fprintf(stderr,?"could?not?open?audio?codec!\n");
return?-1;
}
int?got_picture;
uint8_t?samples[AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2];
AVFrame?*pframe?=?avcodec_alloc_frame();
AVPacket?pkt;
av_init_packet(&pkt);
while(1)?{
if?(av_read_frame(pFmt,?&pkt)?>=?0)?{
if?(pkt.stream_index?==?videoindex)?{
fprintf(stdout,?"pkt.size=%d,pkt.pts=%lld,?pkt.data=0x%x.",?pkt.size,?pkt.pts,(unsigned?int)pkt.data);
avcodec_decode_video2(pVideoCodecCtx,?pframe,?&got_picture,?&pkt);
if?(got_picture)?{
fprintf(stdout,?"decode?one?video?frame!\n");
}
}else?if?(pkt.stream_index?==?audioindex)?{
int?frame_size?=?AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2;
if?(avcodec_decode_audio3(pAudioCodecCtx,?(int16_t?*)samples,?&frame_size,?&pkt)?>=?0)?{
fprintf(stdout,?"decode?one?audio?frame!\n");
}
}
av_free_packet(&pkt);
}
}
av_free(buf);
av_free(pframe);
free_queue(&recvqueue);
return?0;
}
總結
以上是生活随笔為你收集整理的ffmpeg h264+ts +udp传输的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS7时代我们用什么来追踪和识别用户?
- 下一篇: IOS程序内发短信