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保存文件,网络流转发, 编码,解码,播放器制作,以及服务端搭建等等,适合初学者,有需要的朋友的可以关注: ...
随机推荐
- PTA L2-023 图着色问题-前向星建图 团体程序设计天梯赛-练习集
L2-023 图着色问题 (25 分) 图着色问题是一个著名的NP完全问题.给定无向图,,问可否用K种颜色为V中的每一个顶点分配一种颜色,使得不会有两个相邻顶点具有同一种颜色? 但本题并不是要你解 ...
- 转:攻击JavaWeb应用[7]-Server篇[1]
转:http://static.hx99.net/static/drops/tips-604.html 攻击JavaWeb应用[7]-Server篇[1] 园长 · 2013/09/22 15:39 ...
- js中复制方法总结
js中有深拷贝和浅拷贝两种复制形式,下面总结一下常用方法,方便平时工作复习使用 一.浅拷贝 1.json对象浅拷贝 var newObj = JSON.parse(JSON.stringify( so ...
- 叙Windows平台下基于MBR和UEFI的bootkit(一)--以MBR为例
安全的对抗首先在权限方面,权限高的进程对权限低的权限就是就是降维打击,无往不利.当权限相同时,启动得早便为王.所谓的bootkit也就是基于这个思路设计的一种复杂病毒.它优先于Windows系统启动, ...
- CentOS7系统防火墙开关、状态与自启
首先需要说明的是CentOS7使用的是firewalld.service,而不是iptables.service [xf@xuexi ~]$ systemctl status firewalld.se ...
- 30、Flask实战第30天:cms模版抽离和个人信息页面完成
cms模版抽离 新建一个cms_base.html文件作为基础模板,把cms_index.html的内容拷贝到cms_base.html中. 编辑 cms_base.html,把在不同页面会变动的部分 ...
- oracle latch工作原理
latch是一种轻量级用于保护oracle共享内存结构,用户并发操作一致性的串行化锁定机制,如SGA中,各种数据被反复从磁盘读取到内存,又被重新写回到磁盘上,如果有并发用户做相同的事情,oracle必 ...
- 「NOI2018」归程
「NOI2018」归程 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 >\(1\) 个节点. \(m\) 条边的无向连通图(节点的编号从 \( ...
- xtuoj 1235 CQRXLB(博弈论)
CQRXLB Accepted : 19 Submit : 40 Time Limit : 1000 MS Memory Limit : 65536 KB CQRXLB Problem Des ...
- 【Java】【高精度】【递推】UVA - 11375 - Matches
d[i+c[j]]+=d[i](c[j]是拼成j所需的火柴数) d[0]=1: 别忘了不能有前导零,所以当i为零时,不要尝试去拼成零.反而应该在n>=6时,最后给答案加1(单独拼出0). imp ...