@@ -371,6 +371,7 @@ struct esp_video *esp_video_create(const char *name, uint8_t id, const struct es
371371 video -> id = id ;
372372 video -> caps = caps ;
373373 video -> device_caps = device_caps ;
374+ video -> inited = 0 ;
374375 SLIST_INSERT_HEAD (& s_video_list , video , node );
375376
376377 ret = snprintf (vfs_name , sizeof (vfs_name ), "video%d" , id );
@@ -476,31 +477,39 @@ esp_err_t esp_video_open(const char *name, struct esp_video **video_ret)
476477 goto exit_0 ;
477478 }
478479
479- if (video -> ops -> init ) {
480- /* video device operation "init" sets buffer information and video format */
480+ /**
481+ * Only initialize the video device although reference is 1, because the
482+ * reference can be set by other tasks.
483+ */
484+ if (!video -> inited ) {
485+ if (video -> ops -> init ) {
486+ /* video device operation "init" sets buffer information and video format */
481487
482- ret = video -> ops -> init (video );
483- if (ret != ESP_OK ) {
484- if (ret != ESP_ERR_NOT_FOUND ) {
485- ESP_LOGE (TAG , "video->ops->init=%x" , ret );
486- }
487- goto exit_0 ;
488- } else {
489- int stream_count = video -> caps & V4L2_CAP_VIDEO_M2M ? 2 : 1 ;
488+ ret = video -> ops -> init (video );
489+ if (ret != ESP_OK ) {
490+ if (ret != ESP_ERR_NOT_FOUND ) {
491+ ESP_LOGE (TAG , "video->ops->init=%x" , ret );
492+ }
493+ goto exit_0 ;
494+ } else {
495+ int stream_count = video -> caps & V4L2_CAP_VIDEO_M2M ? 2 : 1 ;
490496
491- portMUX_INITIALIZE (& video -> stream_lock );
492- for (int i = 0 ; i < stream_count ; i ++ ) {
493- struct esp_video_stream * stream = & video -> stream [i ];
497+ portMUX_INITIALIZE (& video -> stream_lock );
498+ for (int i = 0 ; i < stream_count ; i ++ ) {
499+ struct esp_video_stream * stream = & video -> stream [i ];
494500
495- stream -> buffer = NULL ;
496- memset (& stream -> param , 0 , sizeof (struct esp_video_param ));
497- TAILQ_INIT (& stream -> queued_list );
498- TAILQ_INIT (& stream -> done_list );
501+ stream -> buffer = NULL ;
502+ memset (& stream -> param , 0 , sizeof (struct esp_video_param ));
503+ TAILQ_INIT (& stream -> queued_list );
504+ TAILQ_INIT (& stream -> done_list );
505+ }
506+
507+ video -> inited = 1 ;
499508 }
509+ } else {
510+ ESP_LOGD (TAG , "video->ops->init=NULL" );
511+ ret = ESP_ERR_NOT_SUPPORTED ;
500512 }
501- } else {
502- ESP_LOGD (TAG , "video->ops->init=NULL" );
503- ret = ESP_ERR_NOT_SUPPORTED ;
504513 }
505514
506515exit_0 :
@@ -541,29 +550,38 @@ esp_err_t esp_video_close(struct esp_video *video)
541550 goto exit_0 ;
542551 }
543552
544- if (video -> ops -> deinit ) {
545- ret = video -> ops -> deinit (video );
546- if (ret != ESP_OK ) {
547- ESP_LOGE (TAG , "video->ops->deinit=%x" , ret );
548- } else {
549- int stream_count = video -> caps & V4L2_CAP_VIDEO_M2M ? 2 : 1 ;
550-
551- for (int i = 0 ; i < stream_count ; i ++ ) {
552- struct esp_video_stream * stream = & video -> stream [i ];
553-
554- if (stream -> ready_sem ) {
555- vSemaphoreDelete (stream -> ready_sem );
556- stream -> ready_sem = NULL ;
553+ /**
554+ * Only deinitialize the video device although reference is 0, because the
555+ * reference can be set by other tasks.
556+ */
557+ if (video -> inited ) {
558+ if (video -> ops -> deinit ) {
559+ ret = video -> ops -> deinit (video );
560+ if (ret != ESP_OK ) {
561+ ESP_LOGE (TAG , "video->ops->deinit=%x" , ret );
562+ } else {
563+ int stream_count = video -> caps & V4L2_CAP_VIDEO_M2M ? 2 : 1 ;
564+
565+ for (int i = 0 ; i < stream_count ; i ++ ) {
566+ struct esp_video_stream * stream = & video -> stream [i ];
567+
568+ if (stream -> ready_sem ) {
569+ vSemaphoreDelete (stream -> ready_sem );
570+ stream -> ready_sem = NULL ;
571+ }
572+
573+ if (stream -> buffer ) {
574+ esp_video_buffer_destroy (stream -> buffer );
575+ stream -> buffer = NULL ;
576+ }
557577 }
558578
559- if (stream -> buffer ) {
560- esp_video_buffer_destroy (stream -> buffer );
561- stream -> buffer = NULL ;
562- }
579+ video -> inited = 0 ;
563580 }
581+ } else {
582+ ESP_LOGD (TAG , "video->ops->deinit=NULL" );
583+ ret = ESP_ERR_NOT_SUPPORTED ;
564584 }
565- } else {
566- ESP_LOGD (TAG , "video->ops->deinit=NULL" );
567585 }
568586
569587exit_0 :
0 commit comments