ffmpeg怎么样处理网络流
http://blog.sina.com.cn/s/blog_675142dc01010otk.html
最近遇到好几个人在问ffmpeg如何处理网络流,刚好前段时间也在做这方面,抽空整理了下,把主要代码发出来,希望对大家有用。为简单处理,我这里只简单介绍UDP接收TS流,其实只要是socket接收的都可以类似处理。
#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怎么样处理网络流的更多相关文章
- FFmpeg 如何探测网络流格式/如何从内存中获取数据
文章转自:http://blog.csdn.net/rootusers/article/details/42551935 一般ffmpeg都是直接从文件中读取或者从网络流中读取,比如rtp://xx. ...
- FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放
前言 ffmpeg播放rtsp网络流和摄像头流. Demo 使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克 使用ffmpeg播放网络rtsp文件流 ...
- 可用的rtmp互联网地址
rtmp://live.hkstv.hk.lxdns.com/live/hks 测试可用. vlc使用ffmpeg取rtmp网络流. 代码文件路径: vlc-2.2.1\modules\access\ ...
- ffmpeg处理网络流
最近遇到好几个人在问ffmpeg如何处理网络流,刚好前段时间也在做这方面,抽空整理了下,把主要代码发出来,希望对大家有用.为简单处理,我这里只简单介绍UDP接收TS流,其实只要是socket接收的都可 ...
- live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)
live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)开发流媒体播放器的时候,特别是在windows mobile,symbian(S60)平台开发时,很可能遇到需要自己开发播放器的情况.S ...
- ffmpeg入门
总入口 http://blog.csdn.net/leixiaohua1020/article/details/15811977 各结构体介绍 http://blog.csdn.net/leixiao ...
- 最简单的基于FFmpeg的推流器(以推送RTMP为例)
===================================================== 最简单的基于FFmpeg的推流器系列文章列表: <最简单的基于FFmpeg的推流器(以 ...
- 基于ffmpeg网络播放器的教程与总结
基于ffmpeg网络播放器的教程与总结 一. 概述 为了解决在线无广告播放youku网上的视频.(youku把每个视频切换成若干个小视频). 视频资源解析可以从www.flvcd. ...
- Ffmpeg 视频教程
最近一段时间找时间录制了一些Ffmpeg视频教程,还有录制完毕,会持续更新,内容会包含Ffmeg保存文件,网络流转发, 编码,解码,播放器制作,以及服务端搭建等等,适合初学者,有需要的朋友的可以关注: ...
随机推荐
- 【PHPExcel实例】 php 导出 excel 实例
CREATE TABLE `person` ( `) DEFAULT NULL, `name` ) DEFAULT NULL, `birthday` date DEFAULT NULL ) ENGIN ...
- 安装 gcc 编译器
1.安装编译工具 gcc.gcc-c++.make 注意解决依赖关系,推荐使用 yum 安装,若不能联网可使用安装光 盘做为 yum 源 1)编辑 yum 配置文件: Mount /dev/cdrom ...
- sublime插件总汇
本人用过多个编辑器(非IDE),发现sublime的样式非常帮,现在做个插件总汇 ChineseLocalzations 中文插件 Emmet ...
- React Hooks useState为什么顺序很重要
一个Function Component的state状态整体是作为memoizedState存在FIber中的. function执行时,首先取memoizedState第一个base state,作 ...
- 【leetcode】200. Number of Islands
原题: Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is s ...
- NetCore2.0 RozarPage自动生成增删改查
原文链接:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/web-api-help-pages-using-swagger 上面的只是原文 ...
- 离线情报分析工具CaseFile
离线情报分析工具CaseFile CaseFile是Maltego的姊妹工具,功能非常类似于Maltego.CaseFile主要针对数据进行离线分析,缺少Maltego的数据采集功能.它可以导入各 ...
- Xamarin Android项目真机测试闪退
Xamarin Android项目真机测试闪退 项目在模拟器中运行正常,但在真机上闪退.这是由于项目设置使用共享的Mono运行时.Visual Studio中,在项目属性-Android Option ...
- BestCoder Round #65 (ZYB's Premutation)
ZYB's Premutation Accepts: 220 Submissions: 983 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- 【分类讨论】【set】Codeforces Round #407 (Div. 2) B. Masha and geometric depression
模拟一下那个过程,直到绝对值超过l,或者出现循环为止. 如果结束之后,绝对值是超过l的,就输出当前写在黑板上的数量. 如果出现循环,则如果写在黑板上的数量非零,则输出inf(注意!如果陷入的循环是一个 ...