使用ffmpeg的av_read_frame,如何控制連接超時


  最近使用ffmpeg來做一個rtsp的客戶端,這過程也遇到不少問題,不過相應都比較好,一路走下來.不過到項目結尾時,且遇到一個比較糾結的問題.那就是客戶端在使用的過程中,把rtsp服務器的網斷了.這時客戶端會卡死.無法操作.嘗試了各種線程的處理,還不行.最后追蹤代碼來到av_read_frame這個函數.問題就出現在它身上了.當服務器斷網后,這個函數會一直沒有返回,且整個線程也停在那里了.

       難道就沒有連接超時的判斷.

 

       原來要想實現連接超時的判斷,得用回調函數.網上有兩種設置方法.不過我這邊只有這種是有效的.

      直接上代碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
AVCodec         *pCodec;
 
     
 
     // Register all formats and codecs
 
     
 
     av_register_all();
 
     avcodec_register_all();
 
     avformat_network_init();
 
     
 
     pFormatCtx = avformat_alloc_context();
 
     pFormatCtx->interrupt_callback.callback = interrupt_cb;--------注冊回調函數
 
     pFormatCtx->interrupt_callback.opaque = pFormatCtx;
 
     AVDictionary* options = NULL;
 
     av_dict_set(&options,  "rtsp_transport" "tcp" , 0);
 
    // ret = avformat_open_input(&pFormatCtx, cFullPath, 0, &options);
 
     //avformat_network_init();
 
     // Open video file
 
     if (avformat_open_input(&pFormatCtx, [url cStringUsingEncoding:NSASCIIStringEncoding], 0, &options) != 0) {
 
         av_log(NULL, AV_LOG_ERROR,  "Couldn't open file\n" );
 
         goto  initError;
 
      }

 

 

再另外定義一下函數

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static  int  interrupt_cb( void  *ctx)
{
     // do something
     NSLog(@ "%d" ,time_out);
     time_out++;
     if  (time_out > 40) {
         NSLog(@ "------%d" , firsttimeplay);
         time_out=0;
         if  (firsttimeplay) {
             firsttimeplay=0;
             NSLog(@ "++++++++" );
             return  1; //這個就是超時的返回
         }
     }
     return  0;
}

 

 

這樣,回調函數就會一直在后台運行着,然后就可以在上面加一些邏輯讓超時返回1了,返回1,系統就自動結束,把主動權交回給主線程,這樣用戶就可以再操作ui了,卡死的問題ok


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM