avformat_open_input, avformat_find_stream_info, av_read_frame 這些 function 呢
都是有可能會因為 stream 不順導致 thread block 在 function 裡面跳不出來的
所以就需要在 AVFormatContext 設定 interrupt_callback
但是使用上要小心, 也許不會 block 的 function 也被你設定的 interrupt_callback 給 interrupt 掉了!
像是我自己遇到的狀況 avformat_close_input 莫名的沒有執行
追進去看才發現被自己 interrupt 了...
static int decode_interrupt_cb(void *ctx)
{
// abort blocking operation
bool *interrupt= (bool *)(ctx);
if (*interrupt)
return 1; // abort
else
return 0;
}
avContext->interrupt_callback.callback = decode_interrupt_cb;
avContext->interrupt_callback.opaque = &b_closed;
if(avformat_open_input(&avContext, url, NULL, &opts) != 0){
av_dict_free(&opts);
avformat_free_context(avContext);
return;
}
av_dict_free(&opts);
if(avformat_find_stream_info(avContext, NULL) < 0){
avformat_close_input(&avContext);
avformat_free_context(avContext);
return;
}
for(i = 0; i < avContext->nb_streams; i++){
if(avContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
stream_index = i;
}
state = avContext->priv_data;
while(av_read_frame(avContext, &packet) >= 0 && !b_closed){
if(packet.stream_index == stream_index){
}
}
av_free_packet(&packet);
avContext->interrupt_callback.callback = NULL;
avContext->interrupt_callback.opaque = NULL;
state->rtsp_hd_out->interrupt_callback.callback = NULL;
state->rtsp_hd_out->interrupt_callback.opaque = NULL;
avformat_close_input(&avContext);
avformat_free_context(avContext);
另外除了 interrupt_callback 也可以使用設定 stimeout (Set socket TCP I/O timeout in micro seconds.) 的方式
不過一旦 stimeout 連線就會關掉
av_dict_set(&opts, "stimeout", "2000000", 0);