ffmpeg怎么样处理网络流

#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 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值