Skip to content

Commit 5ec37af

Browse files
committed
Merge branch 'bugfix/fix_csi_init_twice_when_startup' into 'master'
bugfix(esp_video): Fix the CSI video device initializes twice when starting up Closes AEG-2765 See merge request espressif/esp-video-components!322
2 parents 957438b + a1955dc commit 5ec37af

File tree

3 files changed

+60
-39
lines changed

3 files changed

+60
-39
lines changed

esp_video/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Add the second SPI video device
44
- Improve AEC controller time precision
5+
- Fix the CSI video device initializes twice when starting up
56

67
## 1.2.0
78

esp_video/private_include/esp_video.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ struct esp_video {
7575

7676
SemaphoreHandle_t mutex; /*!< Video device mutex lock */
7777
uint8_t reference; /*!< video device open reference count */
78+
79+
uint8_t inited : 1; /*!< video device is initialized */
7880
};
7981

8082
/**

esp_video/src/esp_video.c

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

506515
exit_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

569587
exit_0:

0 commit comments

Comments
 (0)