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);

 

arrow
arrow
    全站熱搜

    JohnDX 發表在 痞客邦 留言(0) 人氣()