omx cam: add test app
[glsdk/omapdrmtest.git] / omx_cam / output.cpp
1 /*
2  *  Copyright (C) 2009-2012 Texas Instruments, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
17 #include <limits.h>
19 extern "C" {
20 #include <util.h>
21 }
23 #include <config.h>
24 #include <output.h>
26 int Output::open() {
27   char* argv[10];
28   int argc = 0;
29   // Prog name
30   char prog[] = "omx_cam_test";
31   argv[argc++] = prog;
32   // 2D
33   char t_option[] = "-t";
34   char t_option_value[] = "auto";
35   if (twoD_) {
36     argv[argc++] = t_option;
37     argv[argc++] = t_option_value;
38   }
39   // Single plane buffers
40   char one_option[] = "-1";
41   if (! twoD_) {
42     argv[argc++] = one_option;
43   }
44   // KMS display size (ignore by X11)
45   char s_option[] = "-s";
46   char s_option_value[32];
47   sprintf(s_option_value, "%d:%dx%d", 6, display_width_, display_height_);
48   argv[argc++] = s_option;
49   argv[argc++] = s_option_value;
50   // X11 window size (ignored by KMS)
51   char w_option[] = "-w";
52   char w_option_value[32];
53   sprintf(w_option_value, "%dx%d", image_width_, image_height_);
54   argv[argc++] = w_option;
55   argv[argc++] = w_option_value;
56   struct display* d = disp_open(argc, argv);
57   if (d == NULL) {
58     ERROR("Failed to open display");
59     return -1;
60   }
61   handle_ = d;
62   struct buffer** b = disp_get_vid_buffers(d, numBuffers_, color_,
63     buffer_width_, buffer_height_);
64   if (b == NULL) {
65     ERROR("Failed to create buffers");
66     return -1;
67   }
68   buffers_ = b;
69   // Also save to file
70   if (fd_ != NULL) {
71     char file_name[NAME_MAX + 1];
72     sprintf(file_name, "output_%dx%d_%dHz.raw", image_width_, image_height_, 30);
73     fd_ = fopen(file_name, "w");
74     if (fd_ == NULL) {
75       ERROR("%m opening file %s\n", file_name);
76       return -1;
77     }
78     MSG("Opened file %s\n", file_name);
79   }
80   return 0;
81 }
83 int Output::close() {
84   // Can't see what to call for display close
85   if (fd_ != NULL) {
86     return fclose(fd_);
87   }
88   return 0;
89 }
91 struct buffer* Output::alloc(BufferMeta* meta) {
92   struct display* d = static_cast<struct display*>(handle_);
93   struct buffer* b = disp_get_vid_buffer(d);
94   MSG(" -> buffer=%p w=%d h=%d fourcc=%x", b, b->width, b->height, b->fourcc);
95   if (meta) {
96     int p;
97     for (p = 0; p < b->nbo; ++p) {
98       meta->buffer = b;
99       meta->fd[p] = omap_bo_dmabuf(b->bo[p]);
100       meta->map[p] = omap_bo_map(b->bo[p]);
101       MSG(" ---> bo[%d]=%p pitch=%u fd=%d map=%p", p, b->bo[p], b->pitches[p],
102         meta->fd[p], meta->map[p]);
103     }
104   }
105   return b;
108 int Output::free(BufferMeta* meta) {
109   struct display* d = static_cast<struct display*>(handle_);
110   disp_put_vid_buffer(d, meta->buffer);
111   return 0;
114 int Output::render(BufferMeta* meta) {
115   struct display* d = static_cast<struct display*>(handle_);
116   int rc = disp_post_vid_buffer(d, meta->buffer, 0, 0, image_width_, image_height_);
117   if (fd_ != NULL) {
118     const char* buffer;
119     switch (meta->buffer->fourcc) {
120       case FOURCC('U','Y','V','Y'):
121       case FOURCC('Y','U','Y','V'):
122         buffer = static_cast<const char*>(meta->map[0]);
123         for (size_t y = 0; y < image_height_; ++y) {
124           size_t j = y * buffer_width_;
125           fwrite(&buffer[j], 1, image_width_ * 2, fd_);  // bpp = 16
126         }
127         break;
128       case FOURCC('N','V','1','2'):
129         buffer = static_cast<const char*>(meta->map[0]);
130         for (size_t y = 0; y < image_height_; ++y) {
131           size_t j = y * buffer_width_;
132           fwrite(&buffer[j], 1, image_width_, fd_);
133         }
134         if (meta->buffer->nbo == 1) {
135           buffer += meta->buffer->width * meta->buffer->height;
136           for (size_t y = 0; y < image_height_ / 2; ++y) {
137             size_t j = y * buffer_width_;
138             fwrite(&buffer[j], 1, image_width_, fd_);
139           }
140         } else {
141           buffer = static_cast<const char*>(meta->map[1]);
142           for (size_t y = 0; y < image_height_ / 2; ++y) {
143             size_t j = y * buffer_width_;
144             fwrite(&buffer[j], 1, image_width_, fd_);
145           }
146         }
147         break;
148       default:
149         errno = EINVAL;
150         return -1;
151     }
152   }
153   return rc;