GFFMPEG系统结构简介
来源:互联网 发布:打字淘宝兼职是真的吗 编辑:程序博客网 时间:2024/05/17 01:17
FFMPEG系统结构
主要接口
(1) int av_open_input_file(AVFormatContext **ic_ptr, const char
*filename,
AVInputFormat *fmt,
int buf_size,
AVFormatParameters *ap)
{
int err, probe_size;
AVProbeData probe_data, *pd =&probe_data;
//此结构中成员包括:数据操作,缓冲区块等(读取的数据先存入此结构中的缓冲区)
ByteIOContext *pb = NULL;
pd->filename = "";
if (filename)
pd->filename = filename;
pd->buf = NULL;
pd->buf_size = 0;
if (!fmt)
{
/* guess format if no file can be opened*/
fmt = av_probe_input_format(pd, 0);
}
/* Do not open file if the format does not need it. XXX: specific
hack needed to handle RTSP/TCP */
if (!fmt || !(fmt->flags & AVFMT_NOFILE))
{
/* if no file needed do not try to openone */
//根据filename中协议头,准备相应的网络连接,并初始化pb结构体变量
if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0)
{
goto fail;
}
if (buf_size > 0)
{
url_setbufsize(pb,buf_size);
}
for (probe_size= PROBE_BUF_MIN;probe_size<=PROBE_BUF_MAX &&!fmt; probe_size<<=1)
{
int score= probe_size <PROBE_BUF_MAX ? AVPROBE_SCORE_MAX/4 : 0;
/* read probe data */
pd->buf=av_realloc(pd->buf, probe_size + AVPROBE_PADDING_SIZE);
//从ByteIOContext中获取数据
pd->buf_size = get_buffer(pb, pd->buf, probe_size);
memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
if (url_fseek(pb, 0,SEEK_SET) < 0)
{
url_fclose(pb);
if (url_fopen(&pb,filename, URL_RDONLY) < 0)
{
pb = NULL;
err = AVERROR(EIO);
gotofail;
}
}
//解析获取的数据
fmt = av_probe_input_format2(pd, 1, &score);
}
av_freep(&pd->buf);
}
/* if still no format found, error */
if (!fmt)
{
err = AVERROR_NOFMT;
goto fail;
}
/* check filename in case an image number is expected */
if (fmt->flags & AVFMT_NEEDNUMBER)
{
if (!av_filename_number_test(filename))
{
err = AVERROR_NUMEXPECTED;
goto fail;
}
}
err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);
if (err)
goto fail;
return 0;
fail:
av_freep(&pd->buf);
if (pb)
url_fclose(pb);
*ic_ptr = NULL;
return err;
}
(1.1)int url_fopen(ByteIOContext **s, const char *filename, int flags)
{
URLContext *h; //
int err;
//根据filename中协议头,来初始化初始化URLContext变量,并进行
//相应的网络连接
err = url_open(&h,filename, flags);
if (err < 0)
return err;
//创建并初始化ByteIOContext变量
err = url_fdopen(s,h);
if (err < 0)
{
url_close(h);
return err;
}
return 0;
}
(1.2)int url_open(URLContext **puc, const char *filename, int flags)
{
URLProtocol *up;
const char *p;
char proto_str[128], *q;
p = filename;
q = proto_str;
//----解析出协议头(如HTTP,TCP)--------//
while (*p != '\0' && *p != ':')
{
/* protocols can only contain alphabeticchars */
if (!isalpha(*p))
goto file_proto;
if ((q - proto_str) <sizeof(proto_str) - 1)
*q++ = *p;
p++;
}
/* if the protocol has length 1, we consider it is a dos drive */
if (*p == '\0' || is_dos_path(filename))
{
file_proto:
strcpy(proto_str, "file");
}
else
{
*q = '\0';
}
//遍历URLProtocol全局指针变量链表(这个在av_register_all()中预先
//准备好了), 根据协议头找到对应的协议URLProtocol变量, 再创建并初始化URLContext,然后进行相应的网络连接(如TCP会去连接相应的服务器)
up = first_protocol;
while (up != NULL)
{
if (!strcmp(proto_str, up->name))
return url_open_protocol(puc, up, filename, flags);
up = up->next;
}
*puc = NULL;
return AVERROR(ENOENT);
}
(1.3)int url_fdopen(ByteIOContext **s, URLContext *h)
{
uint8_t *buffer;
int buffer_size, max_packet_size;
//设置缓冲块大小(默认值IO_BUFFER_SIZE:32768)
max_packet_size = url_get_max_packet_size(h);
if (max_packet_size)
{
buffer_size = max_packet_size; /* no needto bufferize more than one packet */
}
else
{
buffer_size = IO_BUFFER_SIZE;
}
//创建缓冲块
buffer = av_malloc(buffer_size);
if (!buffer)
return AVERROR(ENOMEM);
//创建ByteIOContext
*s = av_mallocz(sizeof(ByteIOContext));
if (!*s)
{
av_free(buffer);
return AVERROR(ENOMEM);
}
//初始化ByteIOContext,如缓冲块大小,读写等操作函数指针
if (init_put_byte(*s, buffer, buffer_size,
(h->flags & URL_WRONLY || h->flags &URL_RDWR), h,
url_read, url_write, url_seek) < 0)
{
av_free(buffer);
av_freep(s);
return AVERROR(EIO);
}
(*s)->is_streamed = h->is_streamed;
(*s)->max_packet_size = max_packet_size;
if (h->prot)
{
(*s)->read_pause = (int (*)(void *,int))h->prot->url_read_pause;
(*s)->read_seek = (int64_t(*)(void *, int, int64_t, int))h->prot->url_read_seek;
}
return 0;
}
(1.4) int get_buffer(ByteIOContext *s, unsigned char *buf, int size)
{
int len, size1;
size1 = size;
while (size > 0)
{
//缓冲块中还没被读取的数据量
len = s->buf_end - s->buf_ptr;
if (len > size)
len = size;
if (len == 0)
{
if (size >s->buffer_size && !s->update_checksum)
{
if(s->read_packet)
len = s->read_packet(s->opaque, buf, size);
if (len <=0)
{
/* do not modify buffer if EOF reached so that a seek backcan
be done without rereading data */
s->eof_reached = 1;
if (len<0)
s->error= len;
break;
}
else
{
s->pos += len;
size -= len;
buf += len;
s->buf_ptr = s->buffer;
s->buf_end = s->buffer/* + len*/;
}
}
else
{
//根据ByteIOContext先初始的成员变量,从文件或网络源获取数据
//后COPY到缓冲块中,实际的操作由先初始化的URLProtocol变量
//中成员方法来完成(如url_read,url_seek等)
fill_buffer(s);
len =s->buf_end - s->buf_ptr;
if (len == 0)
break;
}
}
else //直接从缓冲中获取数据
{
memcpy(buf, s->buf_ptr,len);
buf += len;
s->buf_ptr += len;
size -= len;
}
}
return size1 - size;
}
(1.5) 识别文件格式并相应的Demuxer
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int*score_max)
(2) AVCodec *avcodec_find_decoder(enumAVCodecID id)
(3) int avcodec_decode_video2(AVCodecContext*avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt)
(4) int avcodec_decode_audio4(AVCodecContext*avctx, AVFrame *frame, int *got_frame_ptr, const AVPacket *avpkt)
(5) intsws_scale(struct SwsContext *c, const uint8_t * const srcSlice[],const intsrcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[],const intdstStride[])
(6) int swr_convert(struct SwrContext *s,uint8_t *out_arg[SWR_CH_MAX], int out_count, const uint8_t *in_arg[SWR_CH_MAX], int in_count)
- GFFMPEG系统结构简介
- iOS系统结构简介
- ECSHOP文件结构系统简介
- 浏览器简介2-浏览器系统结构
- 浏览器简介2-浏览器系统结构
- Mac os x系统文件结构简介
- linux系统的开机加载流程及其系统结构简介
- Objective-C语言和iOS系统(简介,语法,系统结构)
- ATSAMV7Xult板卡调试Nuttx系统----NuttX系统目录结构简介
- MTK手机软件系统的目录结构简介(2)
- 分布式存储系统FastDFS手册之一简介及系统结构
- ebs系统架构简介1——三层结构上篇
- Android源码和系统的目录结构简介
- Objective-C语法之Objective-C语言和iOS系统(简介,语法,系统结构)
- Objective-C语法之Objective-C语言和IOS系统(简介,语法,系统结构)
- Objective-C语法之Objective-C语言和IOS系统(简介,语法,系统结构)
- 1,Objective-C语法之Objective-C语言和iOS系统(简介,语法,系统结构)
- Objective-C语法之Objective-C语言和iOS系统(简介,语法,系统结构)
- 如何修正DIV float之后导致的外部容器不能撑开的问题
- Windows下安装sphinx和sphinx搜索标红
- 子Div使用Float后如何撑开父Div
- weblogic 由于异常关闭导致文件AdminServer.lok被锁,启动报错
- Oracle(入门一)
- GFFMPEG系统结构简介
- 元素hidden与opacity=0的区别
- LeetCode 88. Merge Sorted Array
- ubuntu 安装vagrant过程
- 数据结构笔记--图的邻接表存储及非递归深度优先遍历
- How to get file path in onActivityResult in Android 4.4
- 模态弹出的页面push或pop到其他页面
- 基于R语言的用户征信行为分类预测模型搭建总结
- NAT和代理服务器解析