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怎么样处理网络流的更多相关文章

  1. FFmpeg 如何探测网络流格式/如何从内存中获取数据

    文章转自:http://blog.csdn.net/rootusers/article/details/42551935 一般ffmpeg都是直接从文件中读取或者从网络流中读取,比如rtp://xx. ...

  2. FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放

    前言   ffmpeg播放rtsp网络流和摄像头流.   Demo   使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克     使用ffmpeg播放网络rtsp文件流 ...

  3. 可用的rtmp互联网地址

    rtmp://live.hkstv.hk.lxdns.com/live/hks 测试可用. vlc使用ffmpeg取rtmp网络流. 代码文件路径: vlc-2.2.1\modules\access\ ...

  4. ffmpeg处理网络流

    最近遇到好几个人在问ffmpeg如何处理网络流,刚好前段时间也在做这方面,抽空整理了下,把主要代码发出来,希望对大家有用.为简单处理,我这里只简单介绍UDP接收TS流,其实只要是socket接收的都可 ...

  5. live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)

    live555+ffmpeg如何提取关键帧(I帧,P帧,B帧)开发流媒体播放器的时候,特别是在windows  mobile,symbian(S60)平台开发时,很可能遇到需要自己开发播放器的情况.S ...

  6. ffmpeg入门

    总入口 http://blog.csdn.net/leixiaohua1020/article/details/15811977 各结构体介绍 http://blog.csdn.net/leixiao ...

  7. 最简单的基于FFmpeg的推流器(以推送RTMP为例)

    ===================================================== 最简单的基于FFmpeg的推流器系列文章列表: <最简单的基于FFmpeg的推流器(以 ...

  8. 基于ffmpeg网络播放器的教程与总结

    基于ffmpeg网络播放器的教程与总结   一.         概述 为了解决在线无广告播放youku网上的视频.(youku把每个视频切换成若干个小视频). 视频资源解析可以从www.flvcd. ...

  9. Ffmpeg 视频教程

    最近一段时间找时间录制了一些Ffmpeg视频教程,还有录制完毕,会持续更新,内容会包含Ffmeg保存文件,网络流转发, 编码,解码,播放器制作,以及服务端搭建等等,适合初学者,有需要的朋友的可以关注: ...

随机推荐

  1. POJ 1655.Balancing Act-树的重心(DFS) 模板(vector存图)

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17497   Accepted: 7398 De ...

  2. POJ 1679 The Unique MST 【最小生成树/次小生成树模板】

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22668   Accepted: 8038 D ...

  3. Python3 文件基本修改替换

    现有原文件: Somehow, it seems the love I knew was always the most destructive kind 不知为何,我经历的爱情总是最具毁灭性的的那种 ...

  4. 启动Ubuntu时出现 /dev/sda2 clean 和 /dev/sda2 recovering journal 现象的解决办法

    最近在Ubuntu 18.4上安装Nvidia显卡后,显卡似乎总是不能完全兼容. 第一次出现问题时,是登录账号后,发现系统采用了默认显卡驱动,而已装过的显卡驱动则有损坏导致无法使用. 第二次出现问题时 ...

  5. HDU 5862 Counting Intersections(离散化 + 树状数组)

    Counting Intersections Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  6. Flask实战第66天:celery实现异步任务

    Celery文档:http://docs.celeryproject.org Celery 通过消息进行通信,用专用的工作线程不断监视任务队列以执行新工作. Celery需要消息传输来发送和接收消息. ...

  7. 【Numpy】python机器学习包Numpy基础知识学习

    一.安装:在之前的博客中已经写过:http://www.cnblogs.com/puyangsky/p/4763234.html 二.python数组切片知识: python中序列类有list.str ...

  8. Codeforces 961E 主席树

    题意: 给出一个n个数的序列,求有几对(i,j)满足a[i]>=j&&a[j]>=i,(i,j)和(j,i)只能算一对. 考虑第i个数会有几个j(j<i)满足条件,首 ...

  9. [BZOJ1494]生成树计数

    [BZOJ1494] [NOI2007]生成树计数 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现:·n个结点的环的生成树个数为n.·n个结点的完全图的生成树 ...

  10. 【线段树+离散化】POJ2528-Mayor's posters

    [题目大意] 在墙上贴海报,问最后能看到几张海报? [注意点] 1.首先要注意这是段线段树,而非点线段树.读题的时候注意观察图.来看discuss区下面这组数据: 3 5 6 4 5 6 8 上面数据 ...