1 /*
2 * Copyright (C) 2012 Texas Instruments
3 * Author: Ramprasad <x0038811@ti.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <libdce.h>
21 #include <xf86drm.h>
22 #include <omap_drm.h>
23 #include <omap_drmif.h>
24 #include <string.h>
25 #include "util.h"
28 int width , height;
29 char format[10];
31 struct YuvRgb {
32 struct display *disp;
33 int width;
34 int height;
35 int pitch;
36 float bpp;
37 int num_outBuf;
38 FILE *inFile;
39 };
41 static void
42 usage(char *name)
43 {
44 MSG("Usage: %s -s <connector_id>:<mode> INFILE -W width -H height -c colorformat ", name);
45 MSG("example: %s -s 32:1280x800 file.yuv -W 176 -H 144 -c nv12 ", name);
46 MSG("example: %s --kmscube --connector 36 file.yuv -W 176 -H 144 -c nv12 ", name);
47 MSG("example: %s -w 800x480 file.rgb -W 352 -H 288 -c abgr32 ", name);
48 MSG("Test of YUVdisplay");
49 MSG("");
50 MSG("YUVdisplay options:");
51 MSG("\t --help: Print this help and exit.");
52 MSG("");
53 disp_usage();
54 }
56 static void
57 YuvRgb_close(struct YuvRgb *YuvRgb)
58 {
59 if(!YuvRgb) goto bailout;
60 /* free output buffers allocated by display */
61 disp_free_buffers(YuvRgb->disp,YuvRgb->num_outBuf);
63 if (YuvRgb->disp) disp_close(YuvRgb->disp);
64 free(YuvRgb);
65 bailout:
66 return;
67 }
69 static struct YuvRgb *
70 YuvRgb_open(int argc, char** argv)
71 {
72 struct YuvRgb *YuvRgb;
73 char *infile = NULL;
74 int i;
75 char drm_fourcc[10];
77 YuvRgb = calloc(1, sizeof(*YuvRgb));
78 if (!YuvRgb)
79 return NULL;
81 MSG("%p: Opening Display..", YuvRgb);
82 YuvRgb->disp = disp_open(argc, argv);
83 if (!YuvRgb->disp)
84 goto usage;
86 /* loop thru args, find input file.. */
87 for (i = 1; i < argc; i++) {
88 int fd;
89 if (!argv[i]) {
90 continue;
91 }
92 fd = open(argv[i], 0);
93 if (fd > 0) {
94 infile = argv[i];
95 argv[i] = NULL;
96 close(fd);
97 break;
98 }
99 }
101 width = ALIGN2 (width, 4); /* round up to macroblocks */
102 height = ALIGN2 (height, 4); /* round up to macroblocks */
104 YuvRgb->num_outBuf = 2;
105 YuvRgb->width = width;
106 YuvRgb->height = height;
108 if(!strcmp(format, "nv12")){
109 strcpy(drm_fourcc, "NV12");
110 YuvRgb->bpp = 1.5;
111 }
112 else if(!strcmp(format, "yuyv")){
113 strcpy(drm_fourcc, "YUYV");
114 YuvRgb->bpp = 2;
115 }
116 else if(!strcmp(format, "uyvy")){
117 strcpy(drm_fourcc, "UYVY");
118 YuvRgb->bpp = 2;
119 }
120 else if(!strcmp(format, "rgb24")){
121 strcpy(drm_fourcc, "RG24");
122 YuvRgb->bpp = 3;
123 }
124 else if(!strcmp(format, "bgr24")){
125 strcpy(drm_fourcc, "RG24");
126 YuvRgb->bpp = 3;
127 }
128 else if(!strcmp(format, "argb32")){
129 strcpy(drm_fourcc, "AR24");
130 YuvRgb->bpp = 4;
131 }
132 else if(!strcmp(format, "abgr32")){
133 strcpy(drm_fourcc, "AR24");
134 YuvRgb->bpp = 4;
135 }
136 else{
137 MSG("Not a valid format\n");
138 }
139 MSG("DRM FORUCC is %s\n", drm_fourcc);
140 if (check_args(argc, argv) || !infile)
141 goto usage;
143 /* calculate output buffer parameters: */
145 YuvRgb->inFile = fopen(infile, "rb");
146 if(YuvRgb->inFile == NULL){
147 ERROR("%p: could not open input file", YuvRgb);
148 goto fail;
149 }
152 if (! disp_get_vid_buffers(YuvRgb->disp, YuvRgb->num_outBuf,
153 FOURCC_STR(drm_fourcc), width, height)) {
154 ERROR("%p: could not allocate buffers", YuvRgb);
155 goto fail;
156 }
158 YuvRgb->pitch = YuvRgb->width * YuvRgb->bpp;
160 MSG("width = %d, height = %d format = %s, pitch = %d\n", width,
161 height, format, YuvRgb->pitch);
163 disp_get_fb(YuvRgb->disp);
165 return YuvRgb;
167 usage:
168 usage(argv[0]);
169 fail:
170 if (YuvRgb)
171 YuvRgb_close(YuvRgb);
172 return NULL;
173 }
175 static int
176 YuvRgb_process(struct YuvRgb *YuvRgb)
177 {
178 struct buffer *buf;
179 int bufSize = YuvRgb->width * YuvRgb->height * YuvRgb->bpp;
180 char *dst;
181 int bytes;
183 while(1){
184 buf = disp_get_vid_buffer(YuvRgb->disp);
185 if (!buf) {
186 ERROR("%p: fail: out of buffers", YuvRgb);
187 return -1;
188 }
189 dst = (char*)omap_bo_map(buf->bo[0]);
190 bytes = fread(dst, bufSize, sizeof(char), YuvRgb->inFile);
192 if(bytes == 0 )
193 break;
195 disp_post_vid_buffer(YuvRgb->disp, buf, 0,0, YuvRgb->width,YuvRgb->height);
197 disp_put_vid_buffer(YuvRgb->disp, buf);
198 }
200 return 0;
201 }
203 int
204 main(int argc, char **argv)
205 {
206 struct YuvRgb *YuvRgb = NULL;
207 int i;
208 for (i = 1; i < argc; i++){
209 if ( !strcmp(argv[i], "--help")) {
210 usage(argv[0]);
211 exit(0);
212 }
213 if(!strcmp(argv[i],"-W")){
214 argv[i] = NULL;
215 width = atoi(argv[i+1]);
216 argv[i+1] = NULL;
217 i++;
218 continue;
219 } if(!strcmp(argv[i], "-H")){
220 argv[i] = NULL;
221 height = atoi(argv[i+1]);
222 argv[i+1] = NULL;
223 i++;
224 continue;
225 } if(!strcmp(argv[i], "-c")){
226 argv[i] = NULL;
227 strcpy(format,argv[i+1]);
228 argv[i+1] = NULL;
229 i++;
230 continue;
231 }
233 }
234 YuvRgb = YuvRgb_open(argc,argv);
236 if(YuvRgb)
237 YuvRgb_process(YuvRgb);
239 if(YuvRgb)
240 YuvRgb_close(YuvRgb);
242 YuvRgb = NULL;
244 return 0;
245 }