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

Reply via email to