Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83625
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 153
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-13 11:26
文章分类

全部博文(14)

文章存档

2015年(2)

2014年(7)

2013年(5)

我的朋友

分类: C/C++

2014-03-28 17:05:54

1:
如果数据是rtp/rtsp传输的话,ffmpeg会每隔30s(哪里设置该值?)发送一个keepalive包,如果ipc支持GET_PARAMETER命令,就发该命令等ipc回复以确认ipc还活着。
某些ipc(IPCamera)不支持GET_PARAMETER的rtsp命令。则会通过OPTIONS *来是keepalive,不过这会导致连接断掉
原代码,及修改部分如下。先这样处理,有时间再研究原代码为什么不这么处理。

点击(此处)折叠或打开

  1. //ffmpeg/libavformat/rtspdec.c rtsp_read_packet()
  2. if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
  3.         /* send dummy request to keep TCP connection alive */
  4.         if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
  5.             rt->auth_state.stale) {
  6.             if (rt->server_type == RTSP_SERVER_WMS ||
  7.                 (rt->server_type != RTSP_SERVER_REAL &&
  8.                  rt->get_parameter_supported)) {
  9.                 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
  10.             } else {
  11.                 // ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);                 //原代码
  12.                 ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);        //修改后的代码,这样就算ipc不支持GET_PARAMETER的命令可以keepalive了
  13.             }
  14.             /* The stale flag should be reset when creating the auth response in
  15.              * ff_rtsp_send_cmd_async, but reset it here just in case we never
  16.              * called the auth code (if we didn't have any credentials set). */
  17.             rt->auth_state.stale = 0;
  18.         }
  19.     }

2:
如果数据是rtp/rtsp/tcp传输,如果没有设置stimeout(socket timeout),那么server断线后av_read_frame会阻塞

点击(此处)折叠或打开

  1. AVFormatContext *pFormatCtx = NULL;
  2.     AVPacket packet;
  3.     AVDictionary *optionsDict = NULL;
  4.     char *streamurl1 = "rtsp://test:test@192.168.11.111:554/test.stream";
  5.     
  6.     // Register all formats and codecs
  7.     av_register_all();
  8.     avformat_network_init();

  9.     pFormatCtx = avformat_alloc_context();
  10.     av_dict_set(&optionsDict, "rtsp_transport", "tcp", 0);                //采用tcp传输
  11.     av_dict_set(&optionsDict, "stimeout", "2000000", 0);                  //如果没有设置stimeout,那么把ipc网线拔掉,av_read_frame会阻塞(时间单位是微妙)

  12.     // Open video file
  13.     if(avformat_open_input(&pFormatCtx, streamurl, NULL, &optionsDict)!=0){
  14.         printf("linesize = %d\n", __LINE__);    
  15.         return -1; // Couldn't open file
  16.     }

  17.     // Retrieve stream information
  18.     if(avformat_find_stream_info(pFormatCtx, NULL)<0){
  19.         printf("linesize = %d\n", __LINE__);    
  20.         return -1; // Couldn't find stream information
  21.     }

  22.     // Find the first video stream
  23.     int videoStream=-1;
  24.     for(i=0; i<pFormatCtx->nb_streams; i++){
  25.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
  26.             videoStream=i;
  27.             break;
  28.         }
  29.     }
  30.     
  31.     if(videoStream==-1){
  32.         printf("linesize = %d\n", __LINE__);    
  33.         return -1; // Didn't find a video stream
  34.     }
  35.     
  36.     // Read frames and save first five frames to disk
  37.     while(av_read_frame(pFormatCtx, &packet)>=0) {
  38.         av_free_packet(&packet);
  39.     }
如果是ffmpeg2.0.1版本的话,添加一句就ok了。可是旧版本ffmpeg1.2.*没有stimeout这个字段可以设置
那么只好自己添加了。
在ffmpeg/libavformat/rtsp.h  struct RTSPState添加一个stimeout字段

点击(此处)折叠或打开

  1. typedef struct RTSPState {
  2.     /**
  3.      * timeout of socket i/o operations.(this version do not have this segment. added by yqing, refer to ffmpeg-2.0.1)
  4.      */
  5.     int stimeout;
  6. } RTSPState;
在ffmpeg/libavformat/rtsp.c  ff_rtsp_options添加一个stimeout字段

点击(此处)折叠或打开

  1. const AVOption ff_rtsp_options[] = {
  2.     { "stimeout", "timeout (in micro seconds) of socket i/o operations.", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },    //添加这行代码
  3.     RTSP_REORDERING_OPTS(),
  4.     { NULL },
  5. };
在ffmpeg/libavformat/rtsp.c  ff_rtsp_connect函数修改部分代码如下

点击(此处)折叠或打开

  1. //ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);                            //原代码
  2.   ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, "?timeout=%d", rt->stimeout);     //修改后的代码

阅读(15219) | 评论(0) | 转发(0) |
1

上一篇:AVI封装

下一篇:ffmpeg - tutorial02

给主人留下些什么吧!~~