I believe you need a lock around avformat_open_input() and 
avformat_find_stream_info(). That is what Video::FFmpeg does and it seems to 
work.

-Mischa Spiegelmock

On Jun 14, 2013, at 6:32 AM, "Eberhard, Holger" <[email protected]> 
wrote:

> Hi, I use libav API (0.8.7) to show a live view of IP camera via RTSP.stream.
> We have an embedded platform with hardware decoder and display.
> To show 4 IP cameras in a mosaic we use an array of 4 threads to capture 4 
> RTSP streams
> in parallel. This is running well.
> 
> But we get a problem if we start/stop IP camera capturing too often.
> I investigated that the problem occurs if we use avformat_open_input() with 
> an array of contexts.
> It seems that some memory is not released in this case. If we only use one 
> camera this problem does
> not occur.
> Currently I am not sure if we can use libav functions for multiple RTSP.
> Has anybody experience with this topic ?
> 
> 
> Attached here the main parts of my code:
> 
> 
> 
> static AVPacket packet[IPCAM_MAX_CHN];
> static Bool keyframe_flag[IPCAM_MAX_CHN];
> static char* ipcam_url[IPCAM_MAX_CHN];
> static Bool ipcam_flag[IPCAM_MAX_CHN];
> static AVFormatContext* context[IPCAM_MAX_CHN];
> 
> 
> /* Start IP-camera capturing for a selected channel */
> int dmp_IPcamCaptureChannelStart(char* url, int chn)
> {
>    int i;
> 
>    sprintf(ipcam_url[chn], "%s", url);
>    if(avformat_open_input(&context[chn], ipcam_url[chn], NULL, NULL) != 0)
>    {
>        LOG(LOG_ERR, "%s: Can't open RTSP stream %s, Channel 
> %d!",__FUNCTION__, ipcam_url[chn], chn);
>        avformat_close_input(&context[chn]);
>        return(-1);
>    }
> 
>    if(avformat_find_stream_info(context[chn],NULL) < 0)
>    {
>        LOG(LOG_ERR, "%s: Can't find RTSP stream %s, Channel 
> %d!",__FUNCTION__, ipcam_url[chn], chn);
>        avformat_close_input(&context[chn]);
>        return(-1);
>    }
> 
>    /* Search video stream */
>    for(i=0; i<context[chn]->nb_streams; i++)
>    {
>        if(context[chn]->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
>            video_stream_index[chn] = i;
>    }
> 
>    if( video_stream_index[chn] == -1 )
>    {
>        LOG(LOG_ERR, "%s: Could not find video content %s, Channel 
> %d!",__FUNCTION__, ipcam_url[chn], chn);
>        avformat_close_input(&context[chn]);
>        return(-1);
>    }
> 
>    if( context[chn]->streams[video_stream_index[chn]]->codec->codec_id != 
> CODEC_ID_H264 )
>    {
>        LOG(LOG_ERR, "%s: Invalid video codec %s, Channel %d!",__FUNCTION__, 
> ipcam_url[chn], chn);
>        avformat_close_input(&context[chn]);
>        return(-1);
>    }
> 
>     av_init_packet(&packet[chn]);
> 
>    /* Play RTSP */
>    av_read_play(context[chn]);
> 
>    ipcam_flag[chn] = TRUE;
> 
>    semSignal(&ipcam_start_semaphore[chn]);
> 
>    return(0);
> }
> 
> 
> 
> 
> /* IP camera thread */
> static void* VdecVdis_IPcam_Thread(void* prm)
> {
>    int chn;
> 
>    if( prm == NULL )
>    {
>        LOG(LOG_ERR, "%s: Invalid thread parameter!", __FUNCTION__);
>        ipcam_thread_exit[thread_parameter[chn]] = TRUE;
>    }
>    else
>        memcpy(&chn, prm, sizeof(int));
> 
> 
>    semWait(&ipcam_start_semaphore[thread_parameter[chn]], 
> OSA_TIMEOUT_FOREVER);
> 
>    while( !ipcam_thread_exit[thread_parameter[chn]] )
>    {
>        if(ipcam_flag[thread_parameter[chn]]) /* Start reading packets from 
> stream */
>        {
>            if( av_read_frame(context[thread_parameter[chn]], 
> &packet[thread_parameter[chn]]) >= 0 )
>            {
>                /* A new frame arrived */
>                if( packet[thread_parameter[chn]].stream_index == 
> video_stream_index[thread_parameter[chn]] ) /* Packet is video ? */
>                {
>                        pthread_mutex_lock(&ipcam_mutex[chn]);
> 
>                        /* Deliver frame to Decoder and Display here */
> 
>                        pthread_mutex_unlock(&ipcam_mutex[chn]);
>                }
>            }
>        }
>        else
>        {
>           waitMsecs(100);
>        }
>    }
> 
>    return(NULL);
> }
> 
> 
> 
> 
> /* Stop IP-camera capturing for a selected channel */
> int dmp_IPcamCaptureChannelStop(int chn)
> {
>    ipcam_flag[chn] = FALSE;
>    waitMsecs(100);
>    av_read_pause(context[chn]);
>    avformat_close_input(&context[chn]);
>    av_free_packet(&packet[chn]);
>    context[chn] = NULL;
>    return(0);
> }
> 
> _______________________________________________
> libav-api mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-api

_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api

Reply via email to