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