Skip to content

Commit e64101f

Browse files
6by9popcornmix
authored andcommitted
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 <[email protected]>
1 parent f45dc31 commit e64101f

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed

drivers/media/platform/bcm2835/bcm2835-camera.c

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static struct mmal_fmt formats[] = {
115115
.name = "RGB24 (LE)",
116116
.fourcc = V4L2_PIX_FMT_RGB24,
117117
.flags = 0,
118-
.mmal = MMAL_ENCODING_BGR24,
118+
.mmal = MMAL_ENCODING_RGB24,
119119
.depth = 24,
120120
.mmal_component = MMAL_COMPONENT_CAMERA,
121121
.ybbp = 3,
@@ -187,7 +187,7 @@ static struct mmal_fmt formats[] = {
187187
.name = "RGB24 (BE)",
188188
.fourcc = V4L2_PIX_FMT_BGR24,
189189
.flags = 0,
190-
.mmal = MMAL_ENCODING_RGB24,
190+
.mmal = MMAL_ENCODING_BGR24,
191191
.depth = 24,
192192
.mmal_component = MMAL_COMPONENT_CAMERA,
193193
.ybbp = 3,
@@ -1059,6 +1059,13 @@ static int mmal_setup_components(struct bm2835_mmal_dev *dev,
10591059
else
10601060
camera_port->format.encoding = mfmt->mmal;
10611061

1062+
if (dev->rgb_bgr_swapped) {
1063+
if (camera_port->format.encoding == MMAL_ENCODING_RGB24)
1064+
camera_port->format.encoding = MMAL_ENCODING_BGR24;
1065+
else if (camera_port->format.encoding == MMAL_ENCODING_BGR24)
1066+
camera_port->format.encoding = MMAL_ENCODING_RGB24;
1067+
}
1068+
10621069
camera_port->format.encoding_variant = 0;
10631070
camera_port->es.video.width = f->fmt.pix.width;
10641071
camera_port->es.video.height = f->fmt.pix.height;
@@ -1569,12 +1576,17 @@ static int set_camera_parameters(struct vchiq_mmal_instance *instance,
15691576
return ret;
15701577
}
15711578

1579+
#define MAX_SUPPORTED_ENCODINGS 20
1580+
15721581
/* MMAL instance and component init */
15731582
static int __init mmal_init(struct bm2835_mmal_dev *dev)
15741583
{
15751584
int ret;
15761585
struct mmal_es_format *format;
15771586
u32 bool_true = 1;
1587+
u32 supported_encodings[MAX_SUPPORTED_ENCODINGS];
1588+
int param_size;
1589+
struct vchiq_mmal_component *camera;
15781590

15791591
ret = vchiq_mmal_init(&dev->instance);
15801592
if (ret < 0)
@@ -1586,21 +1598,48 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
15861598
if (ret < 0)
15871599
goto unreg_mmal;
15881600

1589-
if (dev->component[MMAL_COMPONENT_CAMERA]->outputs <
1590-
MMAL_CAMERA_PORT_COUNT) {
1601+
camera = dev->component[MMAL_COMPONENT_CAMERA];
1602+
if (camera->outputs < MMAL_CAMERA_PORT_COUNT) {
15911603
ret = -EINVAL;
15921604
goto unreg_camera;
15931605
}
15941606

15951607
ret = set_camera_parameters(dev->instance,
1596-
dev->component[MMAL_COMPONENT_CAMERA],
1608+
camera,
15971609
dev);
15981610
if (ret < 0)
15991611
goto unreg_camera;
16001612

1601-
format =
1602-
&dev->component[MMAL_COMPONENT_CAMERA]->
1603-
output[MMAL_CAMERA_PORT_PREVIEW].format;
1613+
/* There was an error in the firmware that meant the camera component
1614+
* produced BGR instead of RGB.
1615+
* This is now fixed, but in order to support the old firmwares, we
1616+
* have to check.
1617+
*/
1618+
dev->rgb_bgr_swapped = true;
1619+
param_size = sizeof(supported_encodings);
1620+
ret = vchiq_mmal_port_parameter_get(dev->instance,
1621+
&camera->output[MMAL_CAMERA_PORT_CAPTURE],
1622+
MMAL_PARAMETER_SUPPORTED_ENCODINGS,
1623+
&supported_encodings,
1624+
&param_size);
1625+
if (ret == 0) {
1626+
int i;
1627+
1628+
for (i = 0; i < param_size/sizeof(u32); i++) {
1629+
if (supported_encodings[i] == MMAL_ENCODING_BGR24) {
1630+
/* Found BGR24 first - old firmware. */
1631+
break;
1632+
}
1633+
if (supported_encodings[i] == MMAL_ENCODING_RGB24) {
1634+
/* Found RGB24 first
1635+
* new firmware, so use RGB24.
1636+
*/
1637+
dev->rgb_bgr_swapped = false;
1638+
break;
1639+
}
1640+
}
1641+
}
1642+
format = &camera->output[MMAL_CAMERA_PORT_PREVIEW].format;
16041643

16051644
format->encoding = MMAL_ENCODING_OPAQUE;
16061645
format->encoding_variant = MMAL_ENCODING_I420;
@@ -1614,9 +1653,7 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
16141653
format->es->video.frame_rate.num = 0; /* Rely on fps_range */
16151654
format->es->video.frame_rate.den = 1;
16161655

1617-
format =
1618-
&dev->component[MMAL_COMPONENT_CAMERA]->
1619-
output[MMAL_CAMERA_PORT_VIDEO].format;
1656+
format = &camera->output[MMAL_CAMERA_PORT_VIDEO].format;
16201657

16211658
format->encoding = MMAL_ENCODING_OPAQUE;
16221659
format->encoding_variant = MMAL_ENCODING_I420;
@@ -1631,14 +1668,11 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
16311668
format->es->video.frame_rate.den = 1;
16321669

16331670
vchiq_mmal_port_parameter_set(dev->instance,
1634-
&dev->component[MMAL_COMPONENT_CAMERA]->
1635-
output[MMAL_CAMERA_PORT_VIDEO],
1671+
&camera->output[MMAL_CAMERA_PORT_VIDEO],
16361672
MMAL_PARAMETER_NO_IMAGE_PADDING,
16371673
&bool_true, sizeof(bool_true));
16381674

1639-
format =
1640-
&dev->component[MMAL_COMPONENT_CAMERA]->
1641-
output[MMAL_CAMERA_PORT_CAPTURE].format;
1675+
format = &camera->output[MMAL_CAMERA_PORT_CAPTURE].format;
16421676

16431677
format->encoding = MMAL_ENCODING_OPAQUE;
16441678

@@ -1660,8 +1694,7 @@ static int __init mmal_init(struct bm2835_mmal_dev *dev)
16601694
dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
16611695

16621696
vchiq_mmal_port_parameter_set(dev->instance,
1663-
&dev->component[MMAL_COMPONENT_CAMERA]->
1664-
output[MMAL_CAMERA_PORT_CAPTURE],
1697+
&camera->output[MMAL_CAMERA_PORT_CAPTURE],
16651698
MMAL_PARAMETER_NO_IMAGE_PADDING,
16661699
&bool_true, sizeof(bool_true));
16671700

drivers/media/platform/bcm2835/bcm2835-camera.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct bm2835_mmal_dev {
109109
unsigned int camera_num;
110110
unsigned int max_width;
111111
unsigned int max_height;
112+
unsigned int rgb_bgr_swapped;
112113
};
113114

114115
int bm2835_mmal_init_controls(

0 commit comments

Comments
 (0)