summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0375-BCM2835-V4L2-Correct-handling-for-BGR24-vs-RGB24.patch
blob: 8e6f2fea5b6ad25554e6f31caaff242af6c0fe20 (plain)
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 e773144578da8e21392ce8b6e99cfcd313779da9 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 375/423] 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,
+		&param_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(