ffmpeg处理网络流
来源:互联网 发布:百知尚行科技有限公司 编辑:程序博客网 时间:2024/05/19 17:27
#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
;
}
阅读全文
0 0
- ffmpeg处理网络流
- ffmpeg处理网络流
- ffmpeg怎么样处理网络流
- ffmpeg怎么样处理网络流
- ffmpeg怎么样处理网络流
- ffmpeg怎么样处理网络流
- ffmpeg网络流解码
- FFMpeg处理RTMP流
- 使用 ffmpeg 进行网络推流:拉流->解封装->解码->处理原始数据(音频、视频)->编码->编码->推流
- ffmpeg探测网络流格式方法
- ffmpeg探测网络流格式方法
- ffmpeg探测网络流格式方法
- 利用ffmpeg 解码ps网络流视频
- ffmpeg接收网络流AVFormatContext设置
- 使用FFmpeg转录网络直播流
- 【FFmpeg(2016)】AVCodecContext解码网络流
- 程序代码:使用ffmpeg从网络拉流
- ffmpeg 将网络流保存到本地文件
- Java中的进制转换
- 考试时的一些策略
- CSS实现中间自适应的三栏布局,共4种方法
- servelet的执行原理与生命周期
- PhpStorm配置Xdebug
- ffmpeg处理网络流
- Android 异常Error:Unable to resolve dependency ,Could not resolve project
- Android本地文件选择器
- 《重构改善既有代码设计》读书笔记 第一章
- spring mvc注解详解
- 1123: 最佳校友
- 面对对象编程
- matlab mex 找不到编译器解决方法
- 数据库实验二记录