put example files to dedicated dir
[monster.git] / media_source_dv.c
blob1b690fb40a3f347e553ec17faf6f186a6b4b3bd1
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Media source implementation that reads DV frames from raw DV files.
5 * This file is part of monster
7 * Copyright (C) 2006,2007 Nedko Arnaudov <nedko@arnaudov.name>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 *****************************************************************************/
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <string.h>
32 #define DISABLE_DEBUG_OUTPUT
34 #include "log.h"
35 #include "media_source.h"
36 #include "media_source_dv.h"
37 #include "types.h"
38 #include "dv.h"
39 #include "conf.h"
41 struct media_source_dv
43 struct media_source virtual;
44 int file_handle;
45 unsigned int format;
46 unsigned int frame_size;
47 void * frame_buffer_ptr;
48 int error;
49 bool eof;
50 int initial_repeat;
51 int initial_counter;
54 #define media_source_ptr ((struct media_source_dv *)virtual_ptr)
56 void media_source_dv_destroy(struct media_source * virtual_ptr)
58 DEBUG_OUT("media_source_dv_destroy");
59 close(media_source_ptr->file_handle);
60 free(media_source_ptr->frame_buffer_ptr);
61 free(media_source_ptr);
64 int media_source_dv_format_query(struct media_source * virtual_ptr, unsigned int * format_ptr)
66 DEBUG_OUT("media_source_dv_format_query");
67 *format_ptr = media_source_ptr->format;
68 return 0;
71 int media_source_dv_get_frame_data(struct media_source * virtual_ptr, void ** buffer_ptr_ptr)
73 DEBUG_OUT("media_source_dv_get_frame_data");
75 if (media_source_ptr->error < 0)
77 return media_source_ptr->error;
80 *buffer_ptr_ptr = media_source_ptr->frame_buffer_ptr;
82 return media_source_ptr->eof ? 1 : 0;
85 void
86 media_source_dv_next_frame(struct media_source * virtual_ptr)
88 ssize_t ssret;
90 DEBUG_OUT("media_source_dv_next_frame");
92 if (media_source_ptr->error < 0)
94 return;
97 if (media_source_ptr->initial_counter == 0)
99 media_source_ptr->initial_counter++;
100 // memset(media_source_ptr->frame_buffer_ptr, 0, media_source_ptr->frame_size);
101 // return;
103 else if (media_source_ptr->initial_counter < media_source_ptr->initial_repeat)
105 media_source_ptr->initial_counter++;
106 return;
109 ssret = read(media_source_ptr->file_handle, media_source_ptr->frame_buffer_ptr, media_source_ptr->frame_size);
110 if (ssret != media_source_ptr->frame_size)
112 if (ssret == -1)
114 ERROR_OUT("cannot read the raw DV file (%d)", errno);
115 media_source_ptr->error = -1;
117 else if (ssret != 0)
119 ERROR_OUT("only %u bytes read from the raw DV file instead of %u", (unsigned int)ssret, media_source_ptr->frame_size);
120 media_source_ptr->error = -1;
122 else
124 DEBUG_OUT("no more data");
125 media_source_ptr->eof = true;
130 #undef media_source_ptr
133 media_source_dv(
134 const char * filename,
135 struct media_source ** media_source_ptr_ptr)
137 struct media_source_dv * media_source_ptr;
138 int file_handle;
139 struct stat st;
140 byte data[4];
141 int ret;
142 unsigned int format;
143 unsigned int frame_size;
144 ssize_t ssret;
145 unsigned int calibration_frames;
147 DEBUG_OUT("media_source_dv");
149 ret = conf_file_get_uint("/conf/video/calibration_frames", &calibration_frames);
150 if (ret != 0)
152 ERROR_OUT("failed to read from configuration how many calibration frames to use");
153 ret = -1;
154 goto exit;
157 file_handle = open(filename, O_LARGEFILE);
158 if (file_handle == -1)
160 ERROR_OUT("cannot open \"%s\" (%d)", filename, errno);
161 ret = -1;
162 goto exit;
165 if (fstat(file_handle, &st) == -1)
167 ERROR_OUT("cannot fstat \"%s\" (%d)", filename, errno);
168 ret = -1;
169 goto exit_close_handle;
172 if (st.st_size < 4)
174 ERROR_OUT("\"%s\" is too small", filename);
175 ret = -1;
176 goto exit_close_handle;
179 /* read header */
180 ssret = read(file_handle, data, 4);
181 if (ssret != 4)
183 if (ssret == -1)
185 ERROR_OUT("cannot read \"%s\" (%d)", filename, errno);
187 else
189 ERROR_OUT("only %u bytes read from \"%s\" instead of 4", (unsigned int)ssret, filename);
191 ret = -1;
192 goto exit_close_handle;
195 if ((data[0] >> 5) != 0 || /* first dif block should be header section */
196 (data[3] & 0x40) != 0) /* this bit must be for DV files */
198 ERROR_OUT("\"%s\" is not in raw DV format (header check)", filename);
199 ret = -1;
200 goto exit_close_handle;
203 if ((data[3] & 0x80) != 0)
205 DEBUG_OUT("625/50 (PAL)");
206 format = MEDIA_FORMAT_DV_PAL;
207 frame_size = DV_FRAME_SIZE_PAL;
208 NOTICE_OUT("Video: Using %u calibration frames (%f seconds)", calibration_frames, (float)calibration_frames/25.0);
210 else
212 DEBUG_OUT("525/60 (NTSC)");
213 format = MEDIA_FORMAT_DV_NTSC;
214 frame_size = DV_FRAME_SIZE_NTSC;
215 NOTICE_OUT("Video: Using %u calibration frames (%f seconds)", calibration_frames, (float)calibration_frames/29.97);
218 if (st.st_size % frame_size != 0)
220 ERROR_OUT("\"%s\" is not in raw DV format (size check)", filename);
221 ret = -1;
222 goto exit_close_handle;
225 /* rewind */
226 if (lseek(file_handle, 0, SEEK_SET) != 0)
228 ERROR_OUT("\"%s\" rewind failed", filename);
229 ret = -1;
230 goto exit_close_handle;
233 media_source_ptr = (struct media_source_dv *)malloc(sizeof(struct media_source_dv));
234 if (media_source_ptr == NULL)
236 ERROR_OUT("malloc() failed.");
237 ret = -1;
238 goto exit_close_handle;
241 media_source_ptr->frame_buffer_ptr = malloc(frame_size);
242 if (media_source_ptr->frame_buffer_ptr == NULL)
244 ERROR_OUT("malloc() failed.");
245 ret = -1;
246 goto exit_free_ms;
249 media_source_ptr->virtual.destroy = media_source_dv_destroy;
250 media_source_ptr->virtual.format_query = media_source_dv_format_query;
251 media_source_ptr->virtual.get_frame_data = media_source_dv_get_frame_data;
252 media_source_ptr->virtual.next_frame = media_source_dv_next_frame;
254 media_source_ptr->file_handle = file_handle;
255 media_source_ptr->format = format;
256 media_source_ptr->frame_size = frame_size;
258 media_source_ptr->error = 0;
259 media_source_ptr->eof = false;
260 media_source_ptr->initial_counter = 0;
261 media_source_ptr->initial_repeat = calibration_frames;
262 media_source_dv_next_frame(&media_source_ptr->virtual);
264 if (media_source_ptr->error < 0)
266 ret = media_source_ptr->error;
267 goto exit_free_frame_data;
270 *media_source_ptr_ptr = &media_source_ptr->virtual;
272 ret = 0;
273 goto exit;
275 exit_free_frame_data:
276 free(media_source_ptr->frame_buffer_ptr);
278 exit_free_ms:
279 free(media_source_ptr);
281 exit_close_handle:
282 close(file_handle);
284 exit:
285 return ret;