1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
From 34193c64b66da53cf36bec310fc4b660912847e1 Mon Sep 17 00:00:00 2001
From: Dave Stevenson <6by9@users.noreply.github.com>
Date: Wed, 25 May 2016 23:25:36 +0100
Subject: [PATCH 368/381] BCM2835-V4L2: Correct handling for BGR24 vs RGB24.
There was a bug in the GPU firmware that had reversed these
two formats.
Detect the old firmware, and reverse the formats if necessary.
Signed-off-by: Dave Stevenson <6by9@users.noreply.github.com>
---
drivers/media/platform/bcm2835/bcm2835-camera.c | 69 ++++++++++++++++++-------
drivers/media/platform/bcm2835/bcm2835-camera.h | 1 +
2 files changed, 52 insertions(+), 18 deletions(-)
--- a/drivers/media/platform/bcm2835/bcm2835-camera.c
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.c
@@ -115,7 +115,7 @@ static struct mmal_fmt formats[] = {
.name = "RGB24 (LE)",
.fourcc = V4L2_PIX_FMT_RGB24,
.flags = 0,
- .mmal = MMAL_ENCODING_BGR24,
+ .mmal = MMAL_ENCODING_RGB24,
.depth = 24,
.mmal_component = MMAL_COMPONENT_CAMERA,
.ybbp = 3,
@@ -187,7 +187,7 @@ static struct mmal_fmt formats[] = {
.name = "RGB24 (BE)",
.fourcc = V4L2_PIX_FMT_BGR24,
.flags = 0,
- .mmal = MMAL_ENCODING_RGB24,
+ .mmal = MMAL_ENCODING_BGR24,
.depth = 24,
.mmal_component = MMAL_COMPONENT_CAMERA,
.ybbp = 3,
@@ -1059,6 +1059,13 @@ static int mmal_setup_components(struct
else
camera_port->format.encoding = mfmt->mmal;
+ if (dev->rgb_bgr_swapped) {
+ if (camera_port->format.encoding == MMAL_ENCODING_RGB24)
+ camera_port->format.encoding = MMAL_ENCODING_BGR24;
+ else if (camera_port->format.encoding == MMAL_ENCODING_BGR24)
+ camera_port->format.encoding = MMAL_ENCODING_RGB24;
+ }
+
camera_port->format.encoding_variant = 0;
camera_port->es.video.width = f->fmt.pix.width;
camera_port->es.video.height = f->fmt.pix.height;
@@ -1569,12 +1576,17 @@ static int set_camera_parameters(struct
return ret;
}
+#define MAX_SUPPORTED_ENCODINGS 20
+
/* MMAL instance and component init */
static int __init mmal_init(struct bm2835_mmal_dev *dev)
{
int ret;
struct mmal_es_format *format;
u32 bool_true = 1;
+ u32 supported_encodings[MAX_SUPPORTED_ENCODINGS];
+ int param_size;
+ struct vchiq_mmal_component *camera;
ret = vchiq_mmal_init(&dev->instance);
if (ret < 0)
@@ -1586,21 +1598,48 @@ static int __init mmal_init(struct bm283
if (ret < 0)
goto unreg_mmal;
- if (dev->component[MMAL_COMPONENT_CAMERA]->outputs <
- MMAL_CAMERA_PORT_COUNT) {
+ camera = dev->component[MMAL_COMPONENT_CAMERA];
+ if (camera->outputs < MMAL_CAMERA_PORT_COUNT) {
ret = -EINVAL;
goto unreg_camera;
}
ret = set_camera_parameters(dev->instance,
- dev->component[MMAL_COMPONENT_CAMERA],
+ camera,
dev);
if (ret < 0)
goto unreg_camera;
- format =
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_PREVIEW].format;
+ /* There was an error in the firmware that meant the camera component
+ * produced BGR instead of RGB.
+ * This is now fixed, but in order to support the old firmwares, we
+ * have to check.
+ */
+ dev->rgb_bgr_swapped = true;
+ param_size = sizeof(supported_encodings);
+ ret = vchiq_mmal_port_parameter_get(dev->instance,
+ &camera->output[MMAL_CAMERA_PORT_CAPTURE],
+ MMAL_PARAMETER_SUPPORTED_ENCODINGS,
+ &supported_encodings,
+ ¶m_size);
+ if (ret == 0) {
+ int i;
+
+ for (i = 0; i < param_size/sizeof(u32); i++) {
+ if (supported_encodings[i] == MMAL_ENCODING_BGR24) {
+ /* Found BGR24 first - old firmware. */
+ break;
+ }
+ if (supported_encodings[i] == MMAL_ENCODING_RGB24) {
+ /* Found RGB24 first
+ * new firmware, so use RGB24.
+ */
+ dev->rgb_bgr_swapped = false;
+ break;
+ }
+ }
+ }
+ format = &camera->output[MMAL_CAMERA_PORT_PREVIEW].format;
format->encoding = MMAL_ENCODING_OPAQUE;
format->encoding_variant = MMAL_ENCODING_I420;
@@ -1614,9 +1653,7 @@ static int __init mmal_init(struct bm283
format->es->video.frame_rate.num = 0; /* Rely on fps_range */
format->es->video.frame_rate.den = 1;
- format =
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_VIDEO].format;
+ format = &camera->output[MMAL_CAMERA_PORT_VIDEO].format;
format->encoding = MMAL_ENCODING_OPAQUE;
format->encoding_variant = MMAL_ENCODING_I420;
@@ -1631,14 +1668,11 @@ static int __init mmal_init(struct bm283
format->es->video.frame_rate.den = 1;
vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_VIDEO],
+ &camera->output[MMAL_CAMERA_PORT_VIDEO],
MMAL_PARAMETER_NO_IMAGE_PADDING,
&bool_true, sizeof(bool_true));
- format =
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_CAPTURE].format;
+ format = &camera->output[MMAL_CAMERA_PORT_CAPTURE].format;
format->encoding = MMAL_ENCODING_OPAQUE;
@@ -1660,8 +1694,7 @@ static int __init mmal_init(struct bm283
dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
vchiq_mmal_port_parameter_set(dev->instance,
- &dev->component[MMAL_COMPONENT_CAMERA]->
- output[MMAL_CAMERA_PORT_CAPTURE],
+ &camera->output[MMAL_CAMERA_PORT_CAPTURE],
MMAL_PARAMETER_NO_IMAGE_PADDING,
&bool_true, sizeof(bool_true));
--- a/drivers/media/platform/bcm2835/bcm2835-camera.h
+++ b/drivers/media/platform/bcm2835/bcm2835-camera.h
@@ -109,6 +109,7 @@ struct bm2835_mmal_dev {
unsigned int camera_num;
unsigned int max_width;
unsigned int max_height;
+ unsigned int rgb_bgr_swapped;
};
int bm2835_mmal_init_controls(
|