ffmpeg-URL(转)
ffmpeg中为方便对资源进行访问,定义了两个结构体,URLContext中是对具体资源文件进行操作的上下文,URLProtocol则是在将资源进行分类的基础上,对某一类资源操作的函数集,熟悉Linux设备驱动程序的话,很容易联想到file_operations结构体typedef struct URLContext {const AVClass *av_class; /**< information for av_log(). Set by url_open(). */struct URLProtocol *prot;void *priv_data;char *filename; /**< specified URL */int flags;int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */int is_streamed; /**< true if streamed (no seek possible), default = false */int is_connected;AVIOInterruptCB interrupt_callback;int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */} URLContext;typedef struct URLProtocol {const char *name;int (*url_open)( URLContext *h, const char *url, int flags);/*** This callback is to be used by protocols which open further nested* protocols. options are then to be passed to ffurl_open()/ffurl_connect()* for those nested protocols.*/int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);/*** Read data from the protocol.* If data is immediately available (even less than size), EOF is* reached or an error occurs (including EINTR), return immediately.* Otherwise:* In non-blocking mode, return AVERROR(EAGAIN) immediately.* In blocking mode, wait for data/EOF/error with a short timeout (0.1s),* and return AVERROR(EAGAIN) on timeout.* Checking interrupt_callback, looping on EINTR and EAGAIN and until* enough data has been read is left to the calling function; see* retry_transfer_wrapper in avio.c.*/int (*url_read)( URLContext *h, unsigned char *buf, int size);int (*url_write)(URLContext *h, const unsigned char *buf, int size);int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);int (*url_close)(URLContext *h);struct URLProtocol *next;int (*url_read_pause)(URLContext *h, int pause);int64_t (*url_read_seek)(URLContext *h, int stream_index,int64_t timestamp, int flags);int (*url_get_file_handle)(URLContext *h);int (*url_get_multi_file_handle)(URLContext *h, int **handles,int *numhandles);int (*url_shutdown)(URLContext *h, int flags);int priv_data_size;const AVClass *priv_data_class;int flags;int (*url_check)(URLContext *h, int mask);}URLProtocol;在代码中搜索url_open,很容易能够找到ffmpeg中支持的几个协议:URLProtocol ff_bluray_protocol = {.name = "bluray",.url_close = bluray_close,.url_open = bluray_open,.url_read = bluray_read,.url_seek = bluray_seek,.priv_data_size = sizeof(BlurayContext),.priv_data_class = &bluray_context_class,};URLProtocol ff_data_protocol = {.name = "data",.url_open = data_open,.url_close = data_close,.url_read = data_read,.priv_data_size = sizeof(DataContext),};URLProtocol ff_file_protocol = {.name = "file",.url_open = file_open,.url_read = file_read,.url_write = file_write,.url_seek = file_seek,.url_close = file_close,.url_get_file_handle = file_get_handle,.url_check = file_check,.priv_data_size = sizeof(FileContext),.priv_data_class = &file_class,};URLProtocol ff_pipe_protocol = {.name = "pipe",.url_open = pipe_open,.url_read = file_read,.url_write = file_write,.url_get_file_handle = file_get_handle,.url_check = file_check,.priv_data_size = sizeof(FileContext),.priv_data_class = &pipe_class,};URLProtocol ff_ftp_protocol = {.name = "ftp",.url_open = ftp_open,.url_read = ftp_read,.url_write = ftp_write,.url_seek = ftp_seek,.url_close = ftp_close,.url_get_file_handle = ftp_get_file_handle,.url_shutdown = ftp_shutdown,.priv_data_size = sizeof(FTPContext),.priv_data_class = &ftp_context_class,.flags = URL_PROTOCOL_FLAG_NETWORK,};URLProtocol ff_hls_protocol = {.name = "hls",.url_open = hls_open,.url_read = hls_read,.url_close = hls_close,.flags = URL_PROTOCOL_FLAG_NESTED_SCHEME,.priv_data_size = sizeof(HLSContext),};URLProtocol ff_httpproxy_protocol = {.name = "httpproxy",.url_open = http_proxy_open,.url_read = http_buf_read,.url_write = http_proxy_write,.url_close = http_proxy_close,.url_get_file_handle = http_get_file_handle,.priv_data_size = sizeof(HTTPContext),.flags = URL_PROTOCOL_FLAG_NETWORK,};... 还有很多协议,不全部列出了,例如tcp, udp, ...支持这些协议而定义的结构体在av_register_all()函数被调用时而注册,例如:REGISTER_PROTOCOL(FILE, file);#define REGISTER_PROTOCOL(X, x) \{ \extern URLProtocol ff_##x##_protocol; \if (CONFIG_##X##_PROTOCOL) \ffurl_register_protocol(&ff_##x##_protocol); \}ffurl_register_protocol(&ff_file_protocol);int ffurl_register_protocol(URLProtocol *protocol){URLProtocol **p;p = &first_protocol;while (*p != NULL)p = &(*p)->next;*p = protocol;protocol->next = NULL;return 0;}注册到以static URLProtocol *first_protocol = NULL;为头的一个链表中,每一个协议结构体是链表中的一项;以avio_open2为例:int avio_open2(AVIOContext **s, const char *filename, int flags,const AVIOInterruptCB *int_cb, AVDictionary **options){URLContext *h;int err;err = ffurl_open(&h, filename, flags, int_cb, options);if (err < 0)return err;err = ffio_fdopen(s, h);if (err < 0) {ffurl_close(h);return err;}return 0;}ffurl_open--->ffurl_alloc--->static struct URLProtocol *url_find_protocol(const char *filename)url_find_protocol函数会根据filename判断协议,这个函数的定义没太看懂,但是其作用,无非是先判断具体的协议,然后根据判读出来的协议,调用URLProtocol *ffurl_protocol_next(URLProtocol *prev){return prev ? prev->next : first_protocol;}函数,在之前注册的first_protocol链表上找到相应的协议结构体,然后返回给函数url_alloc_for_protocol,在这个函数中,则是根据判断的协议,生成URLContext结构体,uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);*puc = uc;在ffurl_open函数中,ffurl_alloc函数返回之后,URLContext **puc结构体就已经被设置完毕,然后在ffurl_open函数中,再调用ret = ffurl_connect(*puc, options);int ffurl_connect(URLContext *uc, AVDictionary **options){int err =uc->prot->url_open2 ? uc->prot->url_open2(uc,uc->filename,uc->flags,options) :uc->prot->url_open(uc, uc->filename, uc->flags);if (err)return err;uc->is_connected = 1;/* We must be careful here as ffurl_seek() could be slow,* for example for http */if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file"))if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)uc->is_streamed = 1;return 0;}prot是协议,在url_alloc_for_protocol函数中设置的:uc->prot = up;然后url_open2, url_open都是在协议结构体中定义的函数指针,以"file"协议为例:URLProtocol ff_file_protocol = {.name = "file",.url_open = file_open,.url_read = file_read,.url_write = file_write,.url_seek = file_seek,.url_close = file_close,.url_get_file_handle = file_get_handle,.url_check = file_check,.priv_data_size = sizeof(FileContext),.priv_data_class = &file_class, };url_open2是NULL,则调用url_open函数指针指向的函数file_open:static int file_open(URLContext *h, const char *filename, int flags){FileContext *c = h->priv_data;int access;int fd;struct stat st;av_strstart(filename, "file:", &filename);if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) {access = O_CREAT | O_RDWR;if (c->trunc)access |= O_TRUNC;} else if (flags & AVIO_FLAG_WRITE) {access = O_CREAT | O_WRONLY;if (c->trunc)access |= O_TRUNC;} else {access = O_RDONLY;}#ifdef O_BINARYaccess |= O_BINARY;#endiffd = avpriv_open(filename, access, 0666);if (fd == -1)return AVERROR(errno);c->fd = fd;h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode);return 0;}
http://blog.csdn.net/xiruanliuwei/article/details/24928237
ffmpeg-URL(转)相关推荐
- 使用ffmpeg推流到Wowza
2019独角兽企业重金招聘Python工程师标准>>> Step by step instructions for using FFmpeg as a live video/audi ...
- Windows系统使用minGW+msys 编译ffmpeg 0.5的全过程详述
一.环境配置 1.下载并安装 MinGW-5.1.4.exe (http://jaist.dl.sourceforge.net/sourcef - -5.1.4.exe),安装时选中 g++, min ...
- 13 rtsp视频服务 基于node+ffmpeg 转换为 flv 视频服务
前言 接上一篇文章 rtsp视频服务 转换为 rtmp服务 转换为前端可用的服务 继续讨论 前端播放 rtsp 视频服务 rtsp视频服务 转换为 rtmp服务 转换为前端可用的服务 会使用到 ffm ...
- FFmpeg进行笔记本摄像头+麦克风实现流媒体直播服务,展示在浏览器上。
0.本文中所用软件下载包 1.前置工作 1.1 下载 ffmpeg,Download FFmpeg, 1.1.1配置ffmpeg如下图 1.1.2测试ffmpeg 安装成功:ffmpeg -versi ...
- node.js使用ffmpeg将RTSP转码服务
因为最近项目有直接连接海康摄像头的实时视频播放需求,海康的子码流是RTSP是不能自己在浏览器中播放,之前也没接触过此方面的技术和需求,特此记录一下,node.js使用ffmpeg将海康的子码流进行转码 ...
- 使用express+vue在网页上显示RTSP流视频
这里使用的方式是将获取过来的RTSP流通过express转成flv格式,再在网页上呈现出来,自从flash淘汰之后,网页好像就不能直接出RTSP流了,之前可以使用vlc插件直接播放,现在不行咯. 使用 ...
- android x86启动卡死,[更新]Android-x86启动成功,但是还有点小问题。
在放着4个版本的MeeGo优盘上再加上一个android-x86-2.2-generic.iso.方法跟MeeGo的一样的操作过程,同时对启动参数也做了一些小修改.结果如下: android-x86- ...
- vue实现rtsp视频直播流
实现摄像头的直播功能其实有许多方案,像是安装vlc插件.rtsp转rtmp然后使用videojs通过flash播放rtmp**(由于chrome已经不使用flash所以放弃使用videojs,并且vi ...
- Vision-based User Interface Programming in Java一书简介
1.概述 <Vision-based User Interface Programming in Java>这本书介绍了如何用java做摄像头程序和游戏,可以作为一个计算机视觉的启蒙读物. ...
- 使用flv.js + websokect播放rtsp格式视频流
1.问题背景 在最近的项目中,涉及到海康接入的视频播放的问题,海康这边获取到的视频流是rtsp格式,web端目前没有直接可以播放的组件,于是最开始是后端处理了视频流,返回hls格式的m3u8地址,这样 ...
最新文章
- 分享:bbed修改数据文件头推进scn与其他数据文件相同
- python变量类型-Python 变量类型详解
- 刷新记录! CVPR2021全新目标检测机制达到SOTA!
- AS出现Error:Cause: peer not authenticated
- Spark执行任务卡死:SparkException: Failed to connect to driver! unable to launch application master
- tomcat ---- 常用服务器
- 使用thead,tbody,tfoot来实现表格的分页打印
- Delphi的StringReplace 字符串替换函数
- ToolStripStatusRollingLabel——滚动显示状态栏标签
- Kotlin — 适用于移动端跨平台
- ffmpeg 在linux下编译
- mysql数据库数据表的指令_mysql数据库和表操作命令
- sublime 安装 sql 格式化插件
- 录音文件下载_录音啦(文字语音转换)软件安装教程
- 树莓派使用USB摄像头和motion实现监控
- Vue 2.0的建议学习顺序(尤雨溪)
- English Grammar(二)
- 福瑞泰克完成数亿元B+轮融资,行泊一体+NOA进入大规模量产周期
- 麦澜德医疗科创板上市:年营收3.4亿市值44亿 深耕盆底康复
- 企业研发人员配备比例_一般公司职能结构及人员分布比例配备
热门文章
- 阿里云linux下web服务器配置
- Vue.js2.0核心思想
- iOS10 资料汇总:值得回看的 10 篇 iOS 热文
- c#中控制不能从一个case标签贯穿到另一个case标签
- 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集
- JavaScriptSerializer序列化与反序列化--备忘
- C语言 内存分配 地址 指针 数组 参数 解析
- IOS基础之NSFounation框架的NSDictionary,NSMutableDictionary的使用
- python一到10整数的平方和_零基础学python_10_列表(创建数值列表 )
- python字符串数字求和_python处理字符串:将字符串中的数字相加求和