FFmpeg 源代码简单分析:avformat_network_init ()

=====================================================

FFmpeg的库函数源代码分析文章列表:

架构图】

FFmpeg源代码结构图解码

FFmpeg源代码结构图编码

【通用】

FFmpeg 源代码简单分析:av_register_all()

FFmpeg 源代码简单分析:avcodec_register_all()

FFmpeg 源代码简单分析:avformat_network_init ()

FFmpeg 源代码简单分析:内存的分配和释放(av_malloc()av_free()等)

FFmpeg 源代码简单分析:常见结构体的初始化和销毁(AVFormatContextAVFrame等)

FFmpeg 源代码简单分析:avio_open2()

FFmpeg 源代码简单分析:av_find_decoder()av_find_encoder()

FFmpeg 源代码简单分析:avcodec_open2()

FFmpeg 源代码简单分析:avcodec_close()

【解码】

图解FFMPEG打开媒体的函数avformat_open_input

FFmpeg 源代码简单分析:avformat_open_input()

FFmpeg 源代码简单分析:avformat_find_stream_info()

FFmpeg 源代码简单分析:av_read_frame()

FFmpeg 源代码简单分析:avcodec_decode_video2()

FFmpeg 源代码简单分析:avformat_close_input()

【编码】

FFmpeg 源代码简单分析:avformat_alloc_output_context2()

FFmpeg 源代码简单分析:avformat_write_header()

FFmpeg 源代码简单分析:avcodec_encode_video()

FFmpeg 源代码简单分析:av_write_frame()

FFmpeg 源代码简单分析:av_write_trailer()

【其它】

FFmpeg源代码简单分析:日志输出系统(av_log()等)

FFmpeg源代码简单分析:结构体成员管理系统-AVClass

FFmpeg源代码简单分析:结构体成员管理系统-AVOption

FFmpeg源代码简单分析:libswscalesws_getContext()

FFmpeg源代码简单分析:libswscalesws_scale()

FFmpeg源代码简单分析:libavdeviceavdevice_register_all()

FFmpeg源代码简单分析:libavdevicegdigrab

【脚本】

FFmpeg源代码简单分析:makefile

FFmpeg源代码简单分析:configure

H.264

FFmpegH.264解码器源代码简单分析:概述

=====================================================

Avformat.h (libavformat)

Utils.c (libavformat)

#include "libavformat/avformat.h"

/**

* Do global initialization of network components. This is optional,

* but recommended, since it avoids the overhead of implicitly

* doing the setup for each session.

*

* Calling this function will become mandatory if using network

* protocols at some major version bump.

*/

int avformat_network_init(void);

1.加载socket库以及网络加密协议相关的库,为后续使用网络相关提供支持

PS:

OpenSSL Open Secure Sockets Layer 开放式安全套接层协议

是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

OpenSSL被曝出现严重安全漏洞后,发现多数通过SSL协议加密的网站使用名为OpenSSL开源软件包。OpenSSL漏洞不仅影响以https开头的网站,黑客还可利用此漏洞直接对个人电脑发起"心脏出血"Heartbleed)攻击。据分析,Windows上有大量软件使用了存在漏洞的OpenSSL代码库,可能被黑客攻击抓取用户电脑上的内存数据

GnuTLS 是一个加密协议库,实现了 SSLTLS  DTLS 协议和相关技术,提供了简单的 C 语言编程接口用来访问这些安全通讯协议,提供解析和读写 X.509PKCS #12OpenPGP 和其他相关结构。特点是可移植性和高效。虽然不像之前传出重大漏洞的OpenSSL函数库那么流行,不过GnuTLS的使用范围也相当广泛,包含在Red HatUbuntuDebianLinux操作系统及350种相关软件

打开网络流的话,前面要加上函数avformat_network_init()

ES:socket编程

源代码:

  1. int avformat_network_init(void)  
  2. {  
  3. #if CONFIG_NETWORK  
  4.     int ret;  
  5.     ff_network_inited_globally = 1;  
  6.     if ((ret = ff_network_init()) < 0)  
  7.         return ret;  
  8.     if ((ret = ff_tls_init()) < 0)  
  9.         return ret;  
  10. #endif  
  11.     return 0;  
  12. }  
  1. int ff_network_inited_globally;  
  2.    
  3. int ff_network_init(void)  
  4. {  
  5. #if HAVE_WINSOCK2_H  
  6.     WSADATA wsaData;  
  7. #endif  
  8.    
  9.     if (!ff_network_inited_globally)  
  10.         av_log(NULL, AV_LOG_WARNING, "Using network protocols without global "  
  11.                                      "network initialization. Please use "  
  12.                                      "avformat_network_init(), this will "  
  13.                                      "become mandatory later.\n");  
  14. #if HAVE_WINSOCK2_H  
  15.     if (WSAStartup(MAKEWORD(1,1), &wsaData))  
  16.         return 0;  
  17. #endif  
  18.     return 1;  
  19. }  
  20.  
  21.  
  22.  
  23.  
  24.  
  25. int ff_tls_init(void)  
  26. {  
  27. #if CONFIG_TLS_OPENSSL_PROTOCOL  
  28.     int ret;  
  29.     if ((ret = ff_openssl_init()) < 0)  
  30.         return ret;  
  31. #endif  
  32. #if CONFIG_TLS_GNUTLS_PROTOCOL  
  33.     ff_gnutls_init();  
  34. #endif  
  35.     return 0;  
  36. }  

关于WSAStartup分析如下:

WSAStartup( )

这里用通俗的语言解释一下这个函数,就类似于opencv一样,要添加链接库函数,cv.lib等,要添加到附加依赖项,或者通过#pragma comment(lib,"cv.lib")一样,然后才能包含头文件进行各种函数的调用。当然了,socket编程要调用各种socket函数,但是需要库Ws2_32.lib和头文件Winsock2.h,这里的WSAStartup就是为了向操作系统说明,我们要用哪个库文件,让该库文件与当前的应用程序绑定,从而就可以调用该版本的socket的各种函数了。

头文件 header  Winsock2.h

library      Ws2_32.lib
原型:
int   PASCAL   FAR  WSAStartup ( WORD  wVersionRequested, LPWSADATA   lpWSAData );
参数:wVersionRequestedWindows Sockets API提供的调用方可使用的最高版本号。高位字节指出副版本(修正)号,低位字节指明主版本号
        lpWSAData 
是指向WSADATA数据结构指针,用来接收Windows Sockets实现的细节

WSADATA数据类型:这个结构被用来存储 WSAStartup函数调用后返回的 Windows Sockets数据。它包含Winsock.dll执行的数据。

  结构原型:  

struct WSAData {

  WORD wVersion;

  WORD wHighVersion;

  char szDescription[WSADESCRIPTION_LEN+1];

  char szSystemStatus[WSASYSSTATUS_LEN+1];

  unsigned short iMaxSockets;

  unsigned short iMaxUdpDg;

  char *lpVendorInfo;};

  WSADATA结构被用来保存函数WSAStartup返回的Windows Sockets初始化信息。

  成员:

  wVersion

  Windows Sockets DLL期望调用者使用的Windows Sockets规范的版本。 高位字节存储副版本号, 低位字节存储主版本号,可以用WORD MAKEWORD(BYTE,BYTE ) 返回这个值,例如:MAKEWORD(1,1)

  wHighVersion

  这个DLL能够支持的Windows Sockets规范的最高版本。通常它与wVersion相同。

  szDescription

  以null结尾的ASCII字符串,Windows Sockets DLL将对Windows Sockets实现的描述拷贝到这个字符串中,包括制造商标识。文本(最多可以有256个字符)可以包含任何字符,但是要注意不能包含控制字符和格式字符,应用程序对其最可能的使用方式是把它(可能被截断)显示在在状态信息中。

  szSystemStatus

  以null结尾的ASCII字符串,Windows Sockets DLL把有关的状态或配置信息拷贝到该字符串中。Windows Sockets DLL应当仅在这些信息对用户或支持人员有用时才使用它们,它不应被作为szDescription域的扩展。

  iMaxSockets

  单个进程能够打开的socket的最大数目Windows Sockets的实现能提供一个全局的socket池,可以为任何进程分配;或者它也可以为socket分配属于进程的资源。这个数字能够很好地反映Windows Sockets DLL或网络软件的配置方式。应用程序的编写者可以通过这个数字来粗略地指明Windows Sockets的实现方式对应用程序是否有用。例如,X Windows服务器在第一次启动的时候可能会检查iMaxSockets的值:如果这个值小于8,应用程序将显示一条错误信息,指示用户重新配置网络软件(这是一种可能要使用szSystemStatus文本的场合)。显然无法保证某个应用程序能够真正分配iMaxSocketssocket,因为可能有其它WindowsSockets应用程序正在使用。

  iMaxUdpDg Windows Sockets应用程序能够发送或接收的最大的用户数据包协议(UDP)的数据包大小,以字节为单位。如果实现方式没有限制,那么iMaxUdpDg为零。在Berkeley sockets的许多实现中,对于UDP数据包有个固有的限制(在必要时被分解),大小为8192字节。Windows Sockets的实现可以对碎片重组缓冲区的分配作出限制。对于适合的WindowsSockets 实现,iMaxUdpDg的最小值为512。注意不管iMaxUdpDg的值是什么,都不推荐你发回一个比网络的最大传送单元(MTU)还大的广播数据包。(Windows Sockets API 没有提供发现MTU的机制,但是它不会小于512个字节)WinSock2.0版中已被废弃。

  lpVendorInfo 指向销售商的数据结构的指针。这个结构的定义(如果有)超出了WindowsSockets规范的范围。WinSock2.0版中已被废弃。

其实说白了wsastartup主要就是进行相应的socket库绑定。

WSAStartup() - 功能

一、WSAStartup函数 
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData ); 
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
二、WSACleanup函数 
int WSACleanup (void); 
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。

  

WSAStartup() - 使用方法

当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。该函数执行成功后返回0 
例:假如一个程序要使用2.1版本的Socket,那么程序代码如下 
wVersionRequested = MAKEWORD( 2, 1 ); 
err = WSAStartup( wVersionRequested, &wsaData );

二、WSACleanup函数 
int WSACleanup (void); 
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。 

 Socket接口的检索有关域名、通信服务和协议Internet信息的数据库函数,如

gethostbyaddrgethostbynamegethostnamegetprotolbyname

getprotolbynumbergetserverbynamegetservbyport 
1
gethostname()

函数原型】int PASCAL FAR gethostname (char FAR * name, int namelen);

【使用说明】该函数可以获取本地主机的主机名,其中:

  name:用于指向所获取的主机名的缓冲区指针

  Namelen:缓冲区的大小,以字节为单位。

  返回值:若无错误,返回0;否则,返回错误代吗。 
2
gethostbyname()

  【函数原型】

struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name);

  【使用说明】

  该函数可以从主机名数据库中得到对应的"主机"

  该函数唯一的参数name就是前面调用函数gethostname()得到的主机名。若无错误,刚返回一个指向hostent结构的指针,它可以标识一个"主机"列表。

        

本协议允许Windows Sockets DLLWindows Sockets应用程序共同支持一定范围的Windows Sockets版本.如果版本范围有重叠,应用程序就可以成功地使用Windows Sockets DLL.下列的图表给出了WSAStartup()在不同的应用程序和Windows Sockets DLL版本中是如何工作的:
应用程序版本  DLL版本  wVersionRequested   wVersion   wHighVersion  最终结果
1.1             1.1             1.1             1.1             1.1             use 1.1
1.0 1.1         1.0             1.1                 1.0             1.0             use 1.0 
1.0             1.0 1.1         1.0                 1.0             1.1             use 1.0
1.1             1.0 1.1         1.1                 1.1             1.1             use 1.1
1.1             1.0             1.1                 1.0             1.0            
 失败
1.0             1.1             1.0                 
-             -    WSAVERNOTSUPPORTED
1.0 1.1         1.0 1.1         1.1                 1.1             1.1             use 1.1
1.1 2.0         1.1             2.0                 1.1             1.1             use 1.1
2.0             1.1             2.0                 1.1             1.1            
 失败

   
 下列代码段给出了只支持Windows Sockets 1.1版本的应用程序是如何进行WSAStartup()调用的:
WORD wVersionRequested;
WSADATA wsaData;

int err;
wVersionRequested = MAKEWORD( 1, 1 );

 err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
                
               
                return;
             }

 

  

 
 
 
 if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )

{
 
 
 WSACleanup( );
 return;

 }

下面的代码段示例了只支持1.1版的Windows Sockets DLL是如何进行WSAStartup()协商的:
if ( LOBYTE( wVersionRequested ) < 1 || ( LOBYTE( wVersionRequested ) == 1 &&
    HIBYTE( wVersionRequested ) < 1 ) )

{
 return WSAVERNOTSUPPORTED;

 }

 lpWsaData->wVersion = MAKEWORD( 1, 1 );
 lpWsaData->wHighVersion = MAKEWORD( 1, 1 );
       
 一旦应用程序或DLL进行了一次成功的WSAStartup()调用,它就可以继续进行其它所需的Windows Sockets API调用.当它完成了使用该Windows Sockets DLL的服务后,应用程序或DLL必须调用WSACleanup()以允许Windows Sockets DLL释放任何该应用程序的资源.
错误代码:
WSASYSNOTREADY      指出网络通信依赖的网络子系统还没有准备好.
WSAVERNOTSUPPORTED  所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供.
WSAEINVAL    应用程序指出的Windows Sockets版本不被该DLL支持.
参见:
        send(), sendto(), WSACleanup()

Windows下,Socket是以DLL的形式实现的。在DLL内部维持着一个计数器,只有第一次调用WSAStartup才真正装载DLL,以后的 调用只是简单的增加计数器,而WSACleanup函数的功能则刚好相反,每调用一次使计数器减1,当计数器减到0时,DLL就从内存中被卸载!因此,你 调用了多少次WSAStartup,就应相应的调用多少次的WSACleanup. 

 

猜你喜欢

转载自blog.csdn.net/flyztek/article/details/73974632