1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker *
5*abb65b4bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker *
8*abb65b4bSAndroid Build Coastguard Worker * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker *
11*abb65b4bSAndroid Build Coastguard Worker * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker *
15*abb65b4bSAndroid Build Coastguard Worker * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker * without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker *
19*abb65b4bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker */
31*abb65b4bSAndroid Build Coastguard Worker #ifndef _OAPV_APP_Y4M_H_
32*abb65b4bSAndroid Build Coastguard Worker #define _OAPV_APP_Y4M_H_
33*abb65b4bSAndroid Build Coastguard Worker
34*abb65b4bSAndroid Build Coastguard Worker typedef struct y4m_params {
35*abb65b4bSAndroid Build Coastguard Worker int w;
36*abb65b4bSAndroid Build Coastguard Worker int h;
37*abb65b4bSAndroid Build Coastguard Worker int fps_num;
38*abb65b4bSAndroid Build Coastguard Worker int fps_den;
39*abb65b4bSAndroid Build Coastguard Worker int color_format;
40*abb65b4bSAndroid Build Coastguard Worker int bit_depth;
41*abb65b4bSAndroid Build Coastguard Worker } y4m_params_t;
42*abb65b4bSAndroid Build Coastguard Worker
y4m_test(FILE * fp)43*abb65b4bSAndroid Build Coastguard Worker static int y4m_test(FILE *fp)
44*abb65b4bSAndroid Build Coastguard Worker {
45*abb65b4bSAndroid Build Coastguard Worker
46*abb65b4bSAndroid Build Coastguard Worker char buffer[9] = { 0 };
47*abb65b4bSAndroid Build Coastguard Worker
48*abb65b4bSAndroid Build Coastguard Worker /*Peek to check if y4m header is present*/
49*abb65b4bSAndroid Build Coastguard Worker if(!fread(buffer, 1, 8, fp))
50*abb65b4bSAndroid Build Coastguard Worker return -1;
51*abb65b4bSAndroid Build Coastguard Worker fseek(fp, 0, SEEK_SET);
52*abb65b4bSAndroid Build Coastguard Worker buffer[8] = '\0';
53*abb65b4bSAndroid Build Coastguard Worker if(memcmp(buffer, "YUV4MPEG", 8)) {
54*abb65b4bSAndroid Build Coastguard Worker return 0;
55*abb65b4bSAndroid Build Coastguard Worker }
56*abb65b4bSAndroid Build Coastguard Worker return 1;
57*abb65b4bSAndroid Build Coastguard Worker }
58*abb65b4bSAndroid Build Coastguard Worker
y4m_parse_tags(y4m_params_t * y4m,char * tags)59*abb65b4bSAndroid Build Coastguard Worker static int y4m_parse_tags(y4m_params_t *y4m, char *tags)
60*abb65b4bSAndroid Build Coastguard Worker {
61*abb65b4bSAndroid Build Coastguard Worker
62*abb65b4bSAndroid Build Coastguard Worker char *p;
63*abb65b4bSAndroid Build Coastguard Worker char *q;
64*abb65b4bSAndroid Build Coastguard Worker char t_buff[20];
65*abb65b4bSAndroid Build Coastguard Worker int found_w = 0, found_h = 0, found_cf = 0;
66*abb65b4bSAndroid Build Coastguard Worker int fps_n, fps_d, pix_ratio_n, pix_ratio_d;
67*abb65b4bSAndroid Build Coastguard Worker
68*abb65b4bSAndroid Build Coastguard Worker for(p = tags;; p = q) {
69*abb65b4bSAndroid Build Coastguard Worker
70*abb65b4bSAndroid Build Coastguard Worker /*Skip any leading spaces.*/
71*abb65b4bSAndroid Build Coastguard Worker while(*p == ' ')
72*abb65b4bSAndroid Build Coastguard Worker p++;
73*abb65b4bSAndroid Build Coastguard Worker
74*abb65b4bSAndroid Build Coastguard Worker /*If that's all we have, stop.*/
75*abb65b4bSAndroid Build Coastguard Worker if(p[0] == '\0')
76*abb65b4bSAndroid Build Coastguard Worker break;
77*abb65b4bSAndroid Build Coastguard Worker
78*abb65b4bSAndroid Build Coastguard Worker /*Find the end of this tag.*/
79*abb65b4bSAndroid Build Coastguard Worker for(q = p + 1; *q != '\0' && *q != ' '; q++) {
80*abb65b4bSAndroid Build Coastguard Worker }
81*abb65b4bSAndroid Build Coastguard Worker
82*abb65b4bSAndroid Build Coastguard Worker /*Process the tag.*/
83*abb65b4bSAndroid Build Coastguard Worker switch(p[0]) {
84*abb65b4bSAndroid Build Coastguard Worker case 'W': {
85*abb65b4bSAndroid Build Coastguard Worker if(sscanf(p + 1, "%d", &y4m->w) != 1)
86*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
87*abb65b4bSAndroid Build Coastguard Worker found_w = 1;
88*abb65b4bSAndroid Build Coastguard Worker break;
89*abb65b4bSAndroid Build Coastguard Worker }
90*abb65b4bSAndroid Build Coastguard Worker case 'H': {
91*abb65b4bSAndroid Build Coastguard Worker if(sscanf(p + 1, "%d", &y4m->h) != 1)
92*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
93*abb65b4bSAndroid Build Coastguard Worker found_h = 1;
94*abb65b4bSAndroid Build Coastguard Worker break;
95*abb65b4bSAndroid Build Coastguard Worker }
96*abb65b4bSAndroid Build Coastguard Worker case 'F': {
97*abb65b4bSAndroid Build Coastguard Worker if(sscanf(p + 1, "%d:%d", &fps_n, &fps_d) != 2)
98*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
99*abb65b4bSAndroid Build Coastguard Worker y4m->fps_num = fps_n;
100*abb65b4bSAndroid Build Coastguard Worker y4m->fps_den = fps_d;
101*abb65b4bSAndroid Build Coastguard Worker break;
102*abb65b4bSAndroid Build Coastguard Worker }
103*abb65b4bSAndroid Build Coastguard Worker case 'I': {
104*abb65b4bSAndroid Build Coastguard Worker // interlace = p[1];
105*abb65b4bSAndroid Build Coastguard Worker break;
106*abb65b4bSAndroid Build Coastguard Worker }
107*abb65b4bSAndroid Build Coastguard Worker case 'A': {
108*abb65b4bSAndroid Build Coastguard Worker if(sscanf(p + 1, "%d:%d", &pix_ratio_n, &pix_ratio_d) != 2)
109*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
110*abb65b4bSAndroid Build Coastguard Worker break;
111*abb65b4bSAndroid Build Coastguard Worker }
112*abb65b4bSAndroid Build Coastguard Worker case 'C': {
113*abb65b4bSAndroid Build Coastguard Worker if(q - p > 16)
114*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
115*abb65b4bSAndroid Build Coastguard Worker memcpy(t_buff, p + 1, q - p - 1);
116*abb65b4bSAndroid Build Coastguard Worker t_buff[q - p - 1] = '\0';
117*abb65b4bSAndroid Build Coastguard Worker found_cf = 1;
118*abb65b4bSAndroid Build Coastguard Worker break;
119*abb65b4bSAndroid Build Coastguard Worker }
120*abb65b4bSAndroid Build Coastguard Worker /*Ignore unknown tags.*/
121*abb65b4bSAndroid Build Coastguard Worker }
122*abb65b4bSAndroid Build Coastguard Worker }
123*abb65b4bSAndroid Build Coastguard Worker
124*abb65b4bSAndroid Build Coastguard Worker if(!(found_w == 1 && found_h == 1)) {
125*abb65b4bSAndroid Build Coastguard Worker logerr("Mandatory arugments are not found in y4m header");
126*abb65b4bSAndroid Build Coastguard Worker return OAPV_ERR;
127*abb65b4bSAndroid Build Coastguard Worker }
128*abb65b4bSAndroid Build Coastguard Worker /* Setting default colorspace to yuv420 and input_bd to 8 if header info. is NA */
129*abb65b4bSAndroid Build Coastguard Worker if(!found_cf) {
130*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR420;
131*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 8;
132*abb65b4bSAndroid Build Coastguard Worker }
133*abb65b4bSAndroid Build Coastguard Worker
134*abb65b4bSAndroid Build Coastguard Worker if(strcmp(t_buff, "420jpeg") == 0 || strcmp(t_buff, "420") == 0 ||
135*abb65b4bSAndroid Build Coastguard Worker strcmp(t_buff, "420mpeg2") == 0 || strcmp(t_buff, "420paidv") == 0) {
136*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR420;
137*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 8;
138*abb65b4bSAndroid Build Coastguard Worker }
139*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "422") == 0) {
140*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR422;
141*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 8;
142*abb65b4bSAndroid Build Coastguard Worker }
143*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "444") == 0) {
144*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR444;
145*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 8;
146*abb65b4bSAndroid Build Coastguard Worker }
147*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "420p10") == 0) {
148*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR420;
149*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 10;
150*abb65b4bSAndroid Build Coastguard Worker }
151*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "422p10") == 0) {
152*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR422;
153*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 10;
154*abb65b4bSAndroid Build Coastguard Worker }
155*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "444p10") == 0) {
156*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR444;
157*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 10;
158*abb65b4bSAndroid Build Coastguard Worker }
159*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(t_buff, "mono") == 0) {
160*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_YCBCR400;
161*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = 8;
162*abb65b4bSAndroid Build Coastguard Worker }
163*abb65b4bSAndroid Build Coastguard Worker else {
164*abb65b4bSAndroid Build Coastguard Worker y4m->color_format = OAPV_CF_UNKNOWN;
165*abb65b4bSAndroid Build Coastguard Worker y4m->bit_depth = -1;
166*abb65b4bSAndroid Build Coastguard Worker }
167*abb65b4bSAndroid Build Coastguard Worker return OAPV_OK;
168*abb65b4bSAndroid Build Coastguard Worker }
169*abb65b4bSAndroid Build Coastguard Worker
y4m_header_parser(FILE * ip_y4m,y4m_params_t * y4m)170*abb65b4bSAndroid Build Coastguard Worker int y4m_header_parser(FILE *ip_y4m, y4m_params_t *y4m)
171*abb65b4bSAndroid Build Coastguard Worker {
172*abb65b4bSAndroid Build Coastguard Worker const int head_size = 128;
173*abb65b4bSAndroid Build Coastguard Worker char buffer[128];
174*abb65b4bSAndroid Build Coastguard Worker int ret;
175*abb65b4bSAndroid Build Coastguard Worker int i;
176*abb65b4bSAndroid Build Coastguard Worker
177*abb65b4bSAndroid Build Coastguard Worker memset(buffer, 0, sizeof(char) * head_size);
178*abb65b4bSAndroid Build Coastguard Worker
179*abb65b4bSAndroid Build Coastguard Worker /*Read until newline, or 128 cols, whichever happens first.*/
180*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < (head_size - 1); i++) {
181*abb65b4bSAndroid Build Coastguard Worker
182*abb65b4bSAndroid Build Coastguard Worker if(!fread(buffer + i, 1, 1, ip_y4m))
183*abb65b4bSAndroid Build Coastguard Worker return -1;
184*abb65b4bSAndroid Build Coastguard Worker if(buffer[i] == '\n')
185*abb65b4bSAndroid Build Coastguard Worker break;
186*abb65b4bSAndroid Build Coastguard Worker }
187*abb65b4bSAndroid Build Coastguard Worker /*We skipped too much header data.*/
188*abb65b4bSAndroid Build Coastguard Worker if(i == (head_size - 1)) {
189*abb65b4bSAndroid Build Coastguard Worker logerr("Error parsing header; not a YUV2MPEG2 file?\n");
190*abb65b4bSAndroid Build Coastguard Worker return -1;
191*abb65b4bSAndroid Build Coastguard Worker }
192*abb65b4bSAndroid Build Coastguard Worker buffer[i] = '\0';
193*abb65b4bSAndroid Build Coastguard Worker if(memcmp(buffer, "YUV4MPEG", 8)) {
194*abb65b4bSAndroid Build Coastguard Worker logerr("Incomplete magic for YUV4MPEG file.\n");
195*abb65b4bSAndroid Build Coastguard Worker return -1;
196*abb65b4bSAndroid Build Coastguard Worker }
197*abb65b4bSAndroid Build Coastguard Worker if(buffer[8] != '2') {
198*abb65b4bSAndroid Build Coastguard Worker logerr("Incorrect YUV input file version; YUV4MPEG2 required.\n");
199*abb65b4bSAndroid Build Coastguard Worker }
200*abb65b4bSAndroid Build Coastguard Worker ret = y4m_parse_tags(y4m, buffer + 5);
201*abb65b4bSAndroid Build Coastguard Worker if(ret < 0) {
202*abb65b4bSAndroid Build Coastguard Worker logerr("Error parsing YUV4MPEG2 header.\n");
203*abb65b4bSAndroid Build Coastguard Worker return ret;
204*abb65b4bSAndroid Build Coastguard Worker }
205*abb65b4bSAndroid Build Coastguard Worker return 0;
206*abb65b4bSAndroid Build Coastguard Worker }
207*abb65b4bSAndroid Build Coastguard Worker
y4m_update_param(args_parser_t * args,y4m_params_t * y4m)208*abb65b4bSAndroid Build Coastguard Worker static void y4m_update_param(args_parser_t *args, y4m_params_t *y4m)
209*abb65b4bSAndroid Build Coastguard Worker {
210*abb65b4bSAndroid Build Coastguard Worker args->set_int(args, "width", y4m->w);
211*abb65b4bSAndroid Build Coastguard Worker args->set_int(args, "height", y4m->h);
212*abb65b4bSAndroid Build Coastguard Worker char tmp_fps[256];
213*abb65b4bSAndroid Build Coastguard Worker sprintf(tmp_fps, "%d/%d", y4m->fps_num, y4m->fps_den);
214*abb65b4bSAndroid Build Coastguard Worker args->set_str(args, "fps", tmp_fps);
215*abb65b4bSAndroid Build Coastguard Worker args->set_int(args, "input-depth", y4m->bit_depth);
216*abb65b4bSAndroid Build Coastguard Worker }
217*abb65b4bSAndroid Build Coastguard Worker
write_y4m_header(char * fname,oapv_imgb_t * imgb)218*abb65b4bSAndroid Build Coastguard Worker static int write_y4m_header(char *fname, oapv_imgb_t *imgb)
219*abb65b4bSAndroid Build Coastguard Worker {
220*abb65b4bSAndroid Build Coastguard Worker int color_format = OAPV_CS_GET_FORMAT(imgb->cs);
221*abb65b4bSAndroid Build Coastguard Worker int bit_depth = OAPV_CS_GET_BIT_DEPTH(imgb->cs);
222*abb65b4bSAndroid Build Coastguard Worker int len = 80;
223*abb65b4bSAndroid Build Coastguard Worker int buff_len = 0;
224*abb65b4bSAndroid Build Coastguard Worker char buf[80] = {
225*abb65b4bSAndroid Build Coastguard Worker '\0',
226*abb65b4bSAndroid Build Coastguard Worker };
227*abb65b4bSAndroid Build Coastguard Worker char c_buf[16] = {
228*abb65b4bSAndroid Build Coastguard Worker '\0',
229*abb65b4bSAndroid Build Coastguard Worker };
230*abb65b4bSAndroid Build Coastguard Worker FILE *fp;
231*abb65b4bSAndroid Build Coastguard Worker
232*abb65b4bSAndroid Build Coastguard Worker if(color_format == OAPV_CF_YCBCR420) {
233*abb65b4bSAndroid Build Coastguard Worker if(bit_depth == 8)
234*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "420mpeg2");
235*abb65b4bSAndroid Build Coastguard Worker else if(bit_depth == 10)
236*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "420p10");
237*abb65b4bSAndroid Build Coastguard Worker }
238*abb65b4bSAndroid Build Coastguard Worker else if(color_format == OAPV_CF_YCBCR422) {
239*abb65b4bSAndroid Build Coastguard Worker if(bit_depth == 8)
240*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "422");
241*abb65b4bSAndroid Build Coastguard Worker else if(bit_depth == 10)
242*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "422p10");
243*abb65b4bSAndroid Build Coastguard Worker }
244*abb65b4bSAndroid Build Coastguard Worker else if(color_format == OAPV_CF_YCBCR444) {
245*abb65b4bSAndroid Build Coastguard Worker if(bit_depth == 8)
246*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "444");
247*abb65b4bSAndroid Build Coastguard Worker else if(bit_depth == 10)
248*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "444p10");
249*abb65b4bSAndroid Build Coastguard Worker }
250*abb65b4bSAndroid Build Coastguard Worker else if(color_format == OAPV_CF_YCBCR400) {
251*abb65b4bSAndroid Build Coastguard Worker if(bit_depth == 8)
252*abb65b4bSAndroid Build Coastguard Worker strcpy(c_buf, "mono");
253*abb65b4bSAndroid Build Coastguard Worker }
254*abb65b4bSAndroid Build Coastguard Worker
255*abb65b4bSAndroid Build Coastguard Worker if(strlen(c_buf) == 0) {
256*abb65b4bSAndroid Build Coastguard Worker logerr("Color format is not suuported by y4m");
257*abb65b4bSAndroid Build Coastguard Worker return -1;
258*abb65b4bSAndroid Build Coastguard Worker }
259*abb65b4bSAndroid Build Coastguard Worker
260*abb65b4bSAndroid Build Coastguard Worker /*setting fps to 30 by default as there is no fps related parameter */
261*abb65b4bSAndroid Build Coastguard Worker buff_len = snprintf(buf, len, "YUV4MPEG2 W%d H%d F%d:%d Ip C%s\n",
262*abb65b4bSAndroid Build Coastguard Worker imgb->w[0], imgb->h[0], 30, 1, c_buf);
263*abb65b4bSAndroid Build Coastguard Worker
264*abb65b4bSAndroid Build Coastguard Worker fp = fopen(fname, "ab");
265*abb65b4bSAndroid Build Coastguard Worker if(fp == NULL) {
266*abb65b4bSAndroid Build Coastguard Worker logerr("cannot open file = %s\n", fname);
267*abb65b4bSAndroid Build Coastguard Worker return -1;
268*abb65b4bSAndroid Build Coastguard Worker }
269*abb65b4bSAndroid Build Coastguard Worker if(buff_len != fwrite(buf, 1, buff_len, fp)) {
270*abb65b4bSAndroid Build Coastguard Worker fclose(fp);
271*abb65b4bSAndroid Build Coastguard Worker return -1;
272*abb65b4bSAndroid Build Coastguard Worker }
273*abb65b4bSAndroid Build Coastguard Worker fclose(fp);
274*abb65b4bSAndroid Build Coastguard Worker return 0;
275*abb65b4bSAndroid Build Coastguard Worker }
276*abb65b4bSAndroid Build Coastguard Worker /* Frame level header or separator */
write_y4m_frame_header(char * fname)277*abb65b4bSAndroid Build Coastguard Worker static int write_y4m_frame_header(char *fname)
278*abb65b4bSAndroid Build Coastguard Worker {
279*abb65b4bSAndroid Build Coastguard Worker FILE *fp;
280*abb65b4bSAndroid Build Coastguard Worker fp = fopen(fname, "ab");
281*abb65b4bSAndroid Build Coastguard Worker if(fp == NULL) {
282*abb65b4bSAndroid Build Coastguard Worker logerr("cannot open file = %s\n", fname);
283*abb65b4bSAndroid Build Coastguard Worker return -1;
284*abb65b4bSAndroid Build Coastguard Worker }
285*abb65b4bSAndroid Build Coastguard Worker if(6 != fwrite("FRAME\n", 1, 6, fp)) {
286*abb65b4bSAndroid Build Coastguard Worker fclose(fp);
287*abb65b4bSAndroid Build Coastguard Worker return -1;
288*abb65b4bSAndroid Build Coastguard Worker }
289*abb65b4bSAndroid Build Coastguard Worker fclose(fp);
290*abb65b4bSAndroid Build Coastguard Worker return 0;
291*abb65b4bSAndroid Build Coastguard Worker }
292*abb65b4bSAndroid Build Coastguard Worker
293*abb65b4bSAndroid Build Coastguard Worker #endif /* _OAPV_APP_Y4M_H_ */