Skip to content

Commit b6584a8

Browse files
author
Ahmed Ammar
committed
Updated Makefile and document ipukms_csc.
1 parent 539716b commit b6584a8

File tree

2 files changed

+64
-32
lines changed

2 files changed

+64
-32
lines changed

Makefile

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
CC=$(CROSS_COMPILE)gcc
22

3-
%.o: %.c
4-
$(CC) -O2 -c $^ -o $@
3+
all:
4+
$(CC) -o libvpu_encode libvpu_encode.c -lvpu -lpthread
5+
$(CC) -o ipukms_csc ipukms_csc.c -I /usr/include/libpng/ -lpng -ldrm
56

6-
all: libvpu_encode.o
7-
gcc -o libvpu_encode libvpu_encode.o -lvpu -lpthread

ipukms_csc.c

+61-28
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
#include <drm/imx-ipu-v3-ioctls.h>
77
#include <png.h>
88

9-
9+
// default width/height of input files
1010
#define WIDTH 640
1111
#define HEIGHT 360
1212

13+
// png creation helper functions
1314
#include "ipukms_png.c"
1415

16+
// structure to hold DRM framebuffer information
1517
struct csc_bo {
1618
uint32_t handle;
1719
uint32_t size;
@@ -21,6 +23,7 @@ struct csc_bo {
2123
uint32_t pitch;
2224
};
2325

26+
// framebuffer creation function
2427
struct csc_bo *csc_bo_create(int fd,
2528
const unsigned width, const unsigned height,
2629
const unsigned bpp)
@@ -54,6 +57,7 @@ struct csc_bo *csc_bo_create(int fd,
5457
return NULL;
5558
}
5659

60+
// framebuffer userspace mapping function
5761
static int csc_bo_map(int fd, struct csc_bo *bo)
5862
{
5963
struct drm_mode_map_dumb arg;
@@ -81,6 +85,7 @@ static int csc_bo_map(int fd, struct csc_bo *bo)
8185
return 0;
8286
}
8387

88+
// framebuffer destruction function
8489
static int csc_bo_destroy(int fd, struct csc_bo *bo)
8590
{
8691
struct drm_mode_destroy_dumb arg;
@@ -101,38 +106,44 @@ static int csc_bo_destroy(int fd, struct csc_bo *bo)
101106
return 0;
102107
}
103108

109+
// main function
104110
int main(void)
105111
{
106112
struct csc_bo* input_bo;
107113
struct csc_bo* output_bo;
108114
int ret, fd;
109115

110-
if ((fd = drmOpen("imx-drm", NULL)) < 0) {
116+
// open DRM device
117+
if ((fd = drmOpen("imx-drm", "platform:imx-drm:00")) < 0) {
111118
printf("drmOpen failed.\n");
112119
return -1;
113120
}
114121

115-
//create buffer for csc in/out
122+
// create buffer for csc input
116123
input_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32);
117124
if (!input_bo) {
118125
printf("Couldn't create input gem bo\n");
119126
return -1;
120127
}
128+
129+
// map the input buffer
121130
if (csc_bo_map(fd, input_bo)) {
122131
printf("Couldn't map input bo\n");
123132
return -1;
124133
}
125134

135+
// create buffer for csc output
126136
output_bo = csc_bo_create(fd, WIDTH, HEIGHT, 32);
127137
if (!output_bo) {
128138
printf("Couldn't create output gem bo\n");
129139
return -1;
130140
}
131141

142+
// create ipu csc request
132143
struct drm_imx_ipu_queue req = {
133144
.task = IPU_TASK_CSC,
134145
.input = {
135-
.phys = input_bo->phys, //id of gem_cma object
146+
.phys = input_bo->phys,
136147
.pix = {
137148
.pixelformat = V4L2_PIX_FMT_UYVY,
138149
.bytesperline = 2 * WIDTH,
@@ -145,12 +156,10 @@ int main(void)
145156
},
146157
},
147158
.output = {
148-
.phys = output_bo->phys, //id of gem_cma object
159+
.phys = output_bo->phys,
149160
.pix = {
150161
.pixelformat = V4L2_PIX_FMT_RGB32,
151162
.bytesperline = 4 * WIDTH,
152-
//.pixelformat = V4L2_PIX_FMT_YUV420,
153-
//.bytesperline = 1 * WIDTH,
154163
.width = WIDTH,
155164
.height = HEIGHT,
156165
},
@@ -159,58 +168,82 @@ int main(void)
159168
.height = HEIGHT,
160169
},
161170
},
162-
#if 0
163-
.csc_coeffs[4][3] = {
164-
{149, 0, 0}, /* C00, C01, C02 */
165-
{149, 0, 0}, /* C10, C11, C12 */
166-
{149, 0, 0}, /* C20, C21, C22 */
167-
{0, 0, 0}, /* A0, A1, A2 */
168-
},
169-
#endif
170171
};
172+
173+
// color-space conversion (csc) coefficient matrix values
171174
uint32_t *c0, *c1, *c2, *a0;
172-
c0 = calloc(3, sizeof(uint32_t));
175+
176+
/* i.MX6 Reference Manual (Chapter 36: Table 36-18)
177+
* Z0 = X0*C00 + X1*C01 +X2*C02+A0;
178+
* Z1 = X0*C10 + X1*C11 +X2*C12+A1;
179+
* Z2 = X0*C20 + X1*C21 +X2*C22+A2;
180+
*
181+
* Where c0[0] == C00, c0[1] == C01, c0[2] == C02
182+
*/
183+
184+
// allocate csc coefficients for kernel task
185+
c0 = calloc(3, sizeof(uint32_t));
173186
c1 = calloc(3, sizeof(uint32_t));
174187
c2 = calloc(3, sizeof(uint32_t));
175188
a0 = calloc(3, sizeof(uint32_t));
176189

177-
printf("%p %p %p %p\n", c0, c1, c2, a0);
178-
179-
c0[0] = 149;
180-
c1[0] = 149;
181-
c2[0] = 149;
182-
190+
// converting grayscale to RGB32 R = G = B = Y (dropping chroma)
191+
// Z0 = R = X0 * C00
192+
// Z1 = G = X0 * C10
193+
// Z2 = B = X0 * C20
194+
//
195+
// C00, C10, C20 = 0.99
196+
c0[0] = 255;
197+
c1[0] = 255;
198+
c2[0] = 255;
199+
200+
// set coefficients for kernel ioctl request
183201
req.csc_coeffs[0] = c0;
184202
req.csc_coeffs[1] = c1;
185203
req.csc_coeffs[2] = c2;
186204
req.csc_coeffs[3] = a0;
187205

188-
/* Open YUV420P sample file */
206+
// open grayscale sample input file
189207
FILE *fp = fopen("output.gray", "r");
190-
srand(time(NULL));
191-
//fseek(fp, WIDTH*HEIGHT*3/2*(rand()%87), 0);
208+
209+
// another version using a larger sample
210+
// FILE *fp = fopen("BigBuckBunny_640x360_small.yuv", "r");
211+
// srand(time(NULL));
212+
// fseek(fp, WIDTH*HEIGHT*3/2*(rand()%87), 0);
213+
214+
// read input into input framebuffer
192215
fread(input_bo->ptr, 1, WIDTH*HEIGHT*2, fp);
216+
217+
// close read file
193218
fclose(fp);
194219

195-
//convert to YUV420
220+
// convert to input framebuffer RGB32
196221
if (drmCommandWriteRead(fd, DRM_IMX_IPU_QUEUE, &req, sizeof(req))) {
197222
printf("drmCommandWriteRead failed. [%s]. (%d)\n", strerror(errno), sizeof(req));
198223
return -errno;
199224
}
200225

226+
// map the output framebuffer to userspace
201227
if (csc_bo_map(fd, output_bo)) {
202228
printf("Couldn't map output bo\n");
203229
return -1;
204230
}
205231

206-
//let's see it!
232+
// let's see it!
233+
// save output framebuffer to png (png only supports rgb24)
234+
235+
// allocate the rgb24 output array
207236
char* rgb_matrix = (char*) malloc(WIDTH * HEIGHT * 3);
208237
const char * rgb = (const char *)output_bo->ptr;
209238

210-
//rgba565_to_rgb888(rgb, rgb_matrix, WIDTH*HEIGHT);
239+
// convert rgb32 to rgb24 using helper function
211240
rgba8888_to_rgb888(rgb, rgb_matrix, WIDTH*HEIGHT);
212241

242+
// save output png using helper function
213243
save_png("output.png", rgb_matrix, WIDTH, HEIGHT);
244+
245+
// free the allocated rgb24 matrix
214246
free(rgb_matrix);
247+
215248
return 0;
216249
}

0 commit comments

Comments
 (0)