source: roaraudio/roard/codecfilter_uniraum.c @ 5955:2ae1c52c3610

Last change on this file since 5955:2ae1c52c3610 was 5955:2ae1c52c3610, checked in by phi, 10 years ago

Implemented read-only support for RAUM files using uniraum, support using libRAUM got disabled (See #233).

File size: 20.4 KB
Line 
1//codecfilter_wave.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "roard.h"
27
28#ifdef ROAR_HAVE_LIBUNIRAUM
29
30#include <uniraum/uniraum.h>
31
32#define MAX_STREAMS 4
33
34struct codecfilter_uniraum_inst;
35
36struct codecfilter_uniraum_inst_stream {
37 size_t refc;
38 struct codecfilter_uniraum_inst * parent;
39 struct roar_stream_server * ss;
40 int stream;
41 uniraum_stream_t * uniraumstream;
42 uniraum_mapping_t * uniraummapping;
43 uniraum_data_t * dataqueue;
44};
45
46struct codecfilter_uniraum_inst {
47 size_t refc;
48 struct roar_stream_server * ss;
49 struct roar_vio_calls vio;
50 uniraum_file_t * file;
51 struct codecfilter_uniraum_inst_stream stream[MAX_STREAMS];
52 size_t streams;
53 int got_eof;
54 int is_execed;
55};
56
57static inline void __stream_ref(struct codecfilter_uniraum_inst_stream * self);
58static inline void __stream_unref(struct codecfilter_uniraum_inst_stream * self);
59static inline int __read_more_data(struct codecfilter_uniraum_inst * self, int stream);
60static inline void __stream_pushdata(struct codecfilter_uniraum_inst_stream * self);
61static inline void __stream_setup_vio(struct codecfilter_uniraum_inst_stream * self);
62
63static inline void __inst_ref(struct codecfilter_uniraum_inst * self) {
64 self->refc++;
65}
66
67static inline void __inst_unref(struct codecfilter_uniraum_inst * self) {
68 self->refc--;
69 if ( self->refc )
70  return;
71 uniraum_unref(self->file);
72 self->file = NULL;
73 roar_mm_free(self);
74}
75
76struct codecfilter_uniraum_inst_stream * __stream_get(struct codecfilter_uniraum_inst * self, int stream) {
77 size_t i;
78
79 for (i = 0; i < MAX_STREAMS; i++) {
80  if ( self->stream[i].refc && self->stream[i].stream == stream ) {
81   __stream_ref(&(self->stream[i]));
82   return &(self->stream[i]);
83  }
84 }
85
86 roar_err_set(ROAR_ERROR_NOENT);
87 return NULL;
88}
89
90struct codecfilter_uniraum_inst_stream * __stream_new(struct codecfilter_uniraum_inst * self, int stream) {
91 struct codecfilter_uniraum_inst_stream * ret;
92 size_t i;
93
94 ret = __stream_get(self, stream);
95 if ( ret != NULL ) {
96  __stream_unref(ret);
97  roar_err_set(ROAR_ERROR_EXIST);
98  return NULL;
99 }
100
101 for (i = 0; i < MAX_STREAMS; i++) {
102  ret = &(self->stream[i]);
103  if ( !ret->refc ) {
104   memset(ret, 0, sizeof(*ret));
105   ret->refc = 1;
106   ret->parent = self;
107   ret->ss = NULL;
108   ret->stream = stream;
109   ret->uniraumstream = NULL;
110   ret->uniraummapping = NULL;
111   ret->dataqueue = NULL;
112   if ( streams_new_virtual(ROAR_STREAM(self->ss)->id, &(ret->ss)) == -1 ) {
113    ret->refc = 0;
114    return NULL;
115   }
116   __stream_setup_vio(ret);
117   __stream_ref(ret);
118   self->streams++;
119   return ret;
120  }
121 }
122
123 roar_err_set(ROAR_ERROR_NOSPC);
124 return NULL;
125}
126
127static inline void __stream_ref(struct codecfilter_uniraum_inst_stream * self) {
128 self->refc++;
129}
130
131static inline void __stream_unref(struct codecfilter_uniraum_inst_stream * self) {
132 self->refc--;
133 if ( self->refc )
134  return;
135 self->parent->streams--;
136 __inst_unref(self->parent);
137 uniraum_stream_unref(self->uniraumstream);
138 uniraum_mapping_unref(self->uniraummapping);
139 roar_buffer_free(self->dataqueue);
140 roar_mm_free(self);
141}
142
143static ssize_t        __v_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
144 struct codecfilter_uniraum_inst_stream * self = vio->inst;
145 ssize_t done = 0;
146 size_t len;
147 int ret;
148
149 ROAR_DBG("__v_read(vio=%p, buf=%p, count=%llu) = ?", vio, buf, (long long unsigned int)count);
150
151 while (count) {
152  ROAR_DBG("__v_read(vio=%p, buf=?, count=?): %llu bytes left to do", vio, (long long unsigned int)count);
153  len = count;
154  if ( self->dataqueue == NULL ) {
155   len = 0;
156  } else if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) {
157   ROAR_DBG("__v_read(vio=%p, buf=%p, count=?): roar_errorstring=%s", vio, buf, roar_errorstring);
158   break;
159  }
160
161  if ( len == 0 ) {
162   __stream_pushdata(self);
163   len = count;
164   if ( self->dataqueue == NULL ) {
165    len = 0;
166   } else if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) {
167    ROAR_DBG("__v_read(vio=%p, buf=%p, count=?): roar_errorstring=%s", vio, buf, roar_errorstring);
168    break;
169   }
170   ROAR_DBG("__v_read(vio=%p, buf=?, count=?) = ?", vio);
171   if ( len == 0 ) {
172    do {
173     ret = __read_more_data(self->parent, self->stream);
174    } while (ret == 0 && self->dataqueue == NULL);
175    //__stream_pushdata(self);
176    len = count;
177    ROAR_DBG("__v_read(vio=%p, buf=?, count=?): self->dataqueue=%p, buf=%p", vio, self->dataqueue, buf);
178    if ( roar_buffer_shift_out(&(self->dataqueue), buf, &len) == -1 ) {
179     ROAR_DBG("__v_read(vio=%p, buf=?, count=?): roar_errorstring=%s", vio, roar_errorstring);
180     break;
181    }
182   }
183  }
184
185  buf   += len;
186  count -= len;
187  done  += len;
188 }
189
190 ROAR_DBG("__v_read(vio=%p, buf=%p, count=?) = %lli", vio, buf, (long long int)done);
191 return done;
192}
193
194static ssize_t        __v_write   (struct roar_vio_calls * vio, void *buf, size_t count) {
195 // TODO: add support here to write a stream.
196 roar_err_set(ROAR_ERROR_NOSYS);
197 return -1;
198}
199
200static roar_off_t     __v_lseek   (struct roar_vio_calls * vio, roar_off_t offset, int whence) {
201 roar_err_set(ROAR_ERROR_NOSYS);
202 return -1;
203}
204
205static int            __v_sync    (struct roar_vio_calls * vio) {
206 // TODO: add support here to flush the mapping of this stream and stuff.
207 roar_err_set(ROAR_ERROR_NOSYS);
208 return -1;
209}
210
211static int            __v_ctl     (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) {
212 roar_err_set(ROAR_ERROR_NOSYS);
213 return -1;
214}
215
216static int            __v_close   (struct roar_vio_calls * vio) {
217 // TODO: add support here to terminate the stream and write KICK command and sttuff.
218 __stream_unref(vio->inst);
219 roar_vio_clear_calls(vio);
220 return 0;
221}
222
223static inline void __stream_setup_vio(struct codecfilter_uniraum_inst_stream * self) {
224 struct roar_vio_calls * vio = &(self->ss->vio);
225 roar_vio_clear_calls(vio);
226 vio->inst  = self;
227 vio->read  = __v_read;
228 vio->write = __v_write;
229 vio->lseek = __v_lseek;
230 vio->sync  = __v_sync;
231 vio->ctl   = __v_ctl;
232 vio->close = __v_close;
233 __stream_ref(self);
234}
235
236
237static inline void __stream_pushdata(struct codecfilter_uniraum_inst_stream * self) {
238 uniraum_req_t * req = NULL;
239 uniraum_data_t * data;
240 int queue_filled;
241
242 ROAR_DBG("__stream_pushdata(self=%p) = ?", self);
243
244 do {
245  ROAR_DBG("__stream_pushdata(self=%p) = ?", self);
246  do {
247   ROAR_DBG("__stream_pushdata(self=%p): self->uniraummapping=%p", self, self->uniraummapping);
248   data = uniraum_mapping_dataout(self->uniraummapping);
249   queue_filled = data != NULL;
250   ROAR_DBG("__stream_pushdata(self=%p): queue_filled=%i", self, queue_filled);
251   if ( queue_filled ) {
252    if ( roar_buffer_moveintoqueue(&(self->dataqueue), &data) == -1 ) {
253     ROAR_ERR("__stream_pushdata(self=%p): lost data (can not push into queue): %s", self, roar_errorstring);
254     uniraum_data_unref(data);
255     queue_filled = 0;
256    }
257   }
258  } while (queue_filled);
259
260  req = uniraum_stream_reqout(self->uniraumstream);
261  ROAR_DBG("__stream_pushdata(self=%p): req=%p", self, req);
262  if ( req != NULL ) {
263   if ( uniraum_reqget_type(req) == ROAR_CMD_ADD_DATA ) {
264    ROAR_DBG("__stream_pushdata(self=%p): self->uniraummapping=%p, req=%p is data.", self, self->uniraummapping, req);
265    if ( uniraum_mapping_reqin(self->uniraummapping, req) == -1 ) {
266     ROAR_ERR("__stream_pushdata(self=%p): Can not push data into mapping. Bad.", self);
267    }
268   }
269   uniraum_requnref(req);
270  }
271 } while (req != NULL);
272}
273
274static inline int __handle_meta_data(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int stream) {
275 struct codecfilter_uniraum_inst_stream * streamobj;
276 int server_stream = -1;
277 const char * key;
278 const char * value;
279 int mode;
280
281 if ( stream == -1 ) {
282  server_stream = ROAR_STREAM(self->ss)->id;
283 } else {
284  streamobj = __stream_get(self, stream);
285  if ( streamobj == NULL )
286   return -1;
287  server_stream = ROAR_STREAM(streamobj->ss)->id;
288  __stream_unref(streamobj);
289 }
290
291 if ( uniraum_reqget_meta(in, &key, &value, &mode) == -1 ) {
292  roar_err_set(uniraum_error(self->file));
293  return -1;
294 }
295
296 switch (mode) {
297  case ROAR_META_MODE_SET:
298    return stream_meta_set(server_stream, roar_meta_inttype(key), key, value);
299   break;
300  case ROAR_META_MODE_ADD:
301    return stream_meta_add(server_stream, roar_meta_inttype(key), key, value);
302   break;
303  case ROAR_META_MODE_CLEAR:
304    return stream_meta_clear(server_stream);
305   break;
306  case ROAR_META_MODE_FINALIZE:
307    return stream_meta_finalize(server_stream);
308   break;
309  case ROAR_META_MODE_DELETE:
310    roar_err_set(ROAR_ERROR_NOTSUP);
311    return -1;
312   break;
313 }
314
315 roar_err_set(ROAR_ERROR_BADRQC);
316 return -1;
317}
318
319static inline int __handle_req_global(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type) {
320 ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = ?", self, in, type);
321
322 switch (type) {
323  case ROAR_CMD_NOOP:
324  case ROAR_CMD_CAPS:
325  case ROAR_CMD_RAUM_SEEKTABLE:
326    // NOOPs.
327    return 0;
328   break;
329  case ROAR_CMD_QUIT:
330    self->got_eof = 1;
331    ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = 0 // EOF mark", self, in, type);
332    return 0;
333   break;
334  case ROAR_CMD_SET_META:
335    return __handle_meta_data(self, in, -1);
336   break;
337  default:
338    ROAR_DBG("__handle_req_global(self=%p, in=%p, type=%i) = 0 // error=NSTYPE", self, in, type);
339    roar_err_set(ROAR_ERROR_NSTYPE);
340    return -1;
341   break;
342 }
343}
344
345static inline void __handle_req_stream_update_codec(struct roar_audio_info * info) {
346 switch (info->codec) {
347  case ROAR_CODEC_RAUM_VORBIS:
348    info->codec = ROAR_CODEC_OGG_VORBIS;
349   break;
350  case ROAR_CODEC_RAUM_FLAC:
351   break;
352 }
353}
354
355static inline int __handle_req_stream(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type, int stream) {
356 struct codecfilter_uniraum_inst_stream * streamobj;
357 struct roar_audio_info info;
358 int stream_dir = -1;
359 int ret = -1;
360 int err;
361
362 ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = ?", self, in, type, stream);
363
364 if ( type == ROAR_CMD_NEW_STREAM ) {
365  streamobj = __stream_new(self, stream);
366  if ( streamobj == NULL )
367   return -1;
368
369  streamobj->uniraumstream = uniraum_stream_new(in);
370  ret = streamobj->uniraumstream == NULL ? -1 : 0;
371 } else {
372  streamobj = __stream_get(self, stream);
373  if ( streamobj == NULL )
374   return -1;
375  ret = uniraum_stream_reqin(streamobj->uniraumstream, in);
376  ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i): ret=%i", self, in, type, stream, ret);
377 }
378
379 if ( ret == -1 ) {
380  err = roar_error;
381  __stream_unref(streamobj);
382  roar_err_set(err);
383  ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = -1 // error=%s", self, in, type, stream, roar_errorstring);
384  return -1;
385 }
386
387 switch (type) {
388  case ROAR_CMD_RAUM_SEEKTABLE:
389  case ROAR_CMD_ADD_DATA:
390  case ROAR_CMD_KICK:
391    // NOOPs.
392    ret = 0;
393   break;
394  case ROAR_CMD_SET_META:
395    ret = __handle_meta_data(self, in, stream);
396   break;
397  case ROAR_CMD_EXEC_STREAM:
398    self->is_execed = stream;
399    ret = 0;
400   break;
401  case ROAR_CMD_NEW_STREAM:
402    stream_dir = uniraum_stream_get_dir(streamobj->uniraumstream);
403    info = ROAR_STREAM(streamobj->ss)->info = *uniraum_stream_get_auinfo(streamobj->uniraumstream);
404    __handle_req_stream_update_codec(&(ROAR_STREAM(streamobj->ss)->info));
405    ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i): stream_dir=%i, codec=%s", self, in, type, stream, stream_dir, roar_codec2str(ROAR_STREAM(streamobj->ss)->info.codec));
406    streamobj->ss->codec_orgi = ROAR_STREAM(streamobj->ss)->info.codec;
407    streams_set_dir(ROAR_STREAM(streamobj->ss)->id, stream_dir, 1);
408    streams_set_fh(ROAR_STREAM(streamobj->ss)->id, -2);
409    streamobj->uniraummapping = uniraum_mapping_new(stream,
410                                                    UNIRAUM_IN, ROAR_VIO_DFT_RAW,
411                                                    &info);
412   break;
413  case ROAR_CMD_SET_VOL:
414  case ROAR_CMD_SET_STREAM_PARA:
415  default:
416    roar_err_set(ROAR_ERROR_NSTYPE);
417    ret = -1;
418   break;
419 }
420
421 err = roar_error;
422
423 __stream_pushdata(streamobj);
424 __stream_unref(streamobj);
425
426 roar_err_set(err);
427 ROAR_DBG("__handle_req_stream(self=%p, in=%p, type=%i, stream=%i) = %i // error=%s", self, in, type, stream, ret, roar_errorstring);
428 return ret;
429}
430
431static inline int __handle_req(struct codecfilter_uniraum_inst * self, uniraum_req_t * in, int type, int stream) {
432 ROAR_DBG("__handle_req(self=%p, in=%p, type=%i, stream=%i) = ?", self, in, type, stream);
433
434 if ( stream == -1 ) {
435  return __handle_req_global(self, in, type);
436 } else {
437  return __handle_req_stream(self, in, type, stream);
438 }
439}
440
441static inline int __read_more_data_execed(struct codecfilter_uniraum_inst * self) {
442/*
443ssize_t          uniraum_read_execed (uniraum_file_t * state,       void * buf, size_t len);
444uniraum_req_t *  uniraum_reqdata(int stream, uniraum_pos_t pos, const void * data, size_t len);
445uniraum_req_t *  uniraum_reqend_stream(int stream, uniraum_pos_t pos);
446*/
447
448 uniraum_req_t * data = NULL;
449 char buf[1024];
450 ssize_t ret;
451
452 ROAR_DBG("__read_more_data_execed(self=%p) = ?", self);
453
454 ret = uniraum_read_execed(self->file, buf, sizeof(buf));
455 if ( ret < 0 ) {
456  ROAR_DBG("__read_more_data_execed(self=%p) = -1 // EOF?", self);
457  self->got_eof = 1;
458  roar_err_set(uniraum_error(self->file));
459  return -1;
460 } else if ( ret == 0 ) {
461  self->got_eof = 1;
462 } else {
463  data = uniraum_reqdata(self->is_execed, 0, buf, ret);
464 }
465
466 if ( data == NULL ) {
467  ROAR_DBG("__read_more_data_execed(self=%p) = -1", self);
468  roar_err_set(uniraum_error(self->file));
469  return -1;
470 }
471
472 __handle_req_stream(self, data, uniraum_reqget_type(data), self->is_execed);
473 uniraum_requnref(data);
474
475 ROAR_DBG("__read_more_data_execed(self=%p) = 0", self);
476 return 0;
477}
478
479static inline int __read_more_data(struct codecfilter_uniraum_inst * self, int stream) {
480 uniraum_req_t * in;
481 int instream;
482 int intype;
483 int err;
484
485 ROAR_DBG("__read_more_data(self=%p, stream=%i) = ?", self, stream);
486
487 if ( self->got_eof ) {
488  roar_err_set(ROAR_ERROR_NONE);
489  return -1;
490 } else if ( self->is_execed != -1 ) {
491  if ( self->is_execed == stream ) {
492   __read_more_data_execed(self);
493   ROAR_DBG("__read_more_data(self=%p, stream=%i) = 0", self, stream);
494   return 0;
495  } else {
496   roar_err_set(ROAR_ERROR_BADSTATE);
497   return -1;
498  }
499 }
500
501 ROAR_DBG("__read_more_data(self=%p, stream=%i) = ?", self, stream);
502
503 do {
504  in = uniraum_reqin(self->file);
505  if ( in == NULL ) {
506   err = uniraum_error(self->file);
507   if ( err == ROAR_ERROR_AGAIN ) {
508    if ( uniraum_read(self->file) == -1 ) {
509     roar_err_set(uniraum_error(self->file));
510     ROAR_DBG("__read_more_data(self=%p, stream=%i): Can not read input data (EOF?): %s", self, stream, roar_errorstring);
511     self->got_eof = 1;
512     return -1;
513    }
514    in = uniraum_reqin(self->file);
515    if ( in == NULL ) {
516     roar_err_set(uniraum_error(self->file));
517     return -1;
518    }
519   } else {
520    roar_err_set(err);
521    return -1;
522   }
523  }
524  intype   = uniraum_reqget_type(in);
525  instream = uniraum_reqget_stream(in);
526  __handle_req(self, in, intype, instream);
527  uniraum_requnref(in);
528 } while ( self->is_execed == -1 && !self->got_eof &&
529           ((stream != -1 && stream != instream) || (stream == -1 && intype != ROAR_CMD_ADD_DATA)) );
530
531 ROAR_DBG("__read_more_data(self=%p, stream=%i) = 0", self, stream);
532 return 0;
533}
534
535static ssize_t        __s_read    (struct roar_vio_calls * vio, void *buf, size_t count) {
536 ROAR_DBG("__s_read(vio=%p, buf=%p, count=?) = ?", vio, buf);
537 return stream_vio_s_read(((struct codecfilter_uniraum_inst*)vio->inst)->ss, buf, count);
538}
539static ssize_t        __s_write   (struct roar_vio_calls * vio, void *buf, size_t count) {
540 return stream_vio_s_write(((struct codecfilter_uniraum_inst*)vio->inst)->ss, buf, count);
541}
542static roar_off_t     __s_lseek   (struct roar_vio_calls * vio, roar_off_t offset, int whence) {
543 roar_err_set(ROAR_ERROR_NOSYS);
544 return -1;
545}
546static int            __s_sync    (struct roar_vio_calls * vio) {
547 roar_err_set(ROAR_ERROR_NOSYS);
548 return -1;
549}
550static int            __s_ctl     (struct roar_vio_calls * vio, roar_vio_ctl_t cmd, void * data) {
551 return stream_vio_s_ctl(((struct codecfilter_uniraum_inst*)vio->inst)->ss, cmd, data);
552}
553static int            __s_close   (struct roar_vio_calls * vio) {
554 roar_err_set(ROAR_ERROR_NOSYS);
555 return -1;
556}
557
558static inline void __init_s_vio(struct codecfilter_uniraum_inst * self) {
559 roar_vio_clear_calls(&(self->vio));
560 self->vio.inst  = self;
561 self->vio.read  = __s_read;
562 self->vio.write = __s_write;
563 self->vio.lseek = __s_lseek;
564 self->vio.sync  = __s_sync;
565 self->vio.ctl   = __s_ctl;
566 self->vio.close = __s_close;
567}
568
569static inline int __open_file(struct codecfilter_uniraum_inst * self) {
570 int dir;
571 int flags;
572
573 ROAR_DBG("__open_file(self=%p) = ?", self);
574
575 if ( self->file != NULL ) {
576  ROAR_DBG("__open_file(self=%p) = -1 // error=ALREADY", self);
577  roar_err_set(ROAR_ERROR_ALREADY);
578  return -1;
579 }
580
581 dir = streams_get_ssdir(ROAR_STREAM(self->ss)->id);
582
583 switch (dir) {
584  case STREAM_DIR_IN:
585    flags = O_RDONLY;
586   break;
587  case STREAM_DIR_OUT:
588    flags = O_WRONLY;
589   break;
590  case STREAM_DIR_BIDIR:
591    flags = O_RDWR;
592   break;
593  default:
594    roar_err_set(ROAR_ERROR_NOTSUP);
595    return -1;
596   break;
597 }
598
599 __init_s_vio(self);
600
601 ROAR_DBG("__open_file(self=%p) = ?", self);
602
603 self->file = uniraum_openvio(&(self->vio), flags);
604 if ( self->file == NULL ) {
605  roar_err_set(uniraum_error(NULL));
606  ROAR_DBG("__open_file(self=%p): Can not open uniraum file object: %s", self, roar_errorstring);
607  return -1;
608 }
609
610 ROAR_DBG("__open_file(self=%p) = 0", self);
611 return 0;
612}
613
614int cf_uniraum_open (CODECFILTER_USERDATA_T * inst, int codec,
615                     struct roar_stream_server * info,
616                     struct roar_codecfilter   * filter) {
617 struct codecfilter_uniraum_inst * self;
618
619 self = roar_mm_malloc(sizeof(struct codecfilter_uniraum_inst));
620 if ( self == NULL )
621  return -1;
622
623 memset(self, 0, sizeof(struct codecfilter_uniraum_inst));
624 self->refc = 1;
625 self->ss   = info;
626 self->file = NULL;
627 self->got_eof = 0;
628 self->is_execed = -1;
629
630 *inst = self;
631
632 return 0;
633}
634
635int cf_uniraum_close(CODECFILTER_USERDATA_T   inst) {
636 struct codecfilter_uniraum_inst * self = inst;
637
638 __inst_unref(self);
639
640 ROAR_DBG("cf_uniraum_close(inst=%p) = 0", inst);
641 return 0;
642}
643
644int cf_uniraum_write(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
645 struct codecfilter_uniraum_inst * self = inst;
646
647 if ( self->file == NULL )
648  if ( __open_file(self) == -1 )
649   return -1;
650
651 roar_err_set(ROAR_ERROR_BADFH);
652 return -1;
653}
654
655int cf_uniraum_read (CODECFILTER_USERDATA_T   inst, char * buf, int len) {
656 struct codecfilter_uniraum_inst * self = inst;
657 ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = ?", inst, buf, len);
658
659 if ( self == NULL ) {
660  roar_err_set(ROAR_ERROR_FAULT);
661  return -1;
662 }
663
664 if ( self->file == NULL )
665  if ( __open_file(self) == -1 )
666   return -1;
667
668 if ( !self->streams )
669  __read_more_data(self, -1);
670
671 if ( self->got_eof ) {
672  ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = 0 // EOF", inst, buf, len);
673  return 0;
674 } else {
675  ROAR_DBG("cf_uniraum_read(inst=%p, buf=%p, len=%i) = -1 // errno=EAGAIN", inst, buf, len);
676  errno = EAGAIN;
677  return -1;
678 }
679}
680
681int cf_uniraum_flush(CODECFILTER_USERDATA_T   inst) {
682 struct codecfilter_uniraum_inst * self = inst;
683 int r = uniraum_write(self->file);
684
685 if ( r == -1 )
686  roar_err_set(uniraum_error(self->file));
687
688 return r;
689}
690
691int cf_uniraum_ctl  (CODECFILTER_USERDATA_T   inst, int cmd, void * data) {
692 struct codecfilter_uniraum_inst * self = inst;
693 int_least32_t type = cmd & ROAR_STREAM_CTL_TYPEMASK;
694
695 cmd -= type;
696
697 ROAR_DBG("cf_uniraum_ctl(*): cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x",
698          cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd));
699
700 switch (cmd) {
701  case ROAR_CODECFILTER_CTL2CMD(ROAR_CODECFILTER_CTL_META_UPDATE):
702    if ( type != ROAR_STREAM_CTL_TYPE_VOID )
703     return -1;
704    roar_err_set(ROAR_ERROR_NOTSUP);
705    return -1;
706   break;
707  default:
708    ROAR_DBG("cf_uniraum_ctl(*): Unknown command: cmd=0x%.8x, type=0x%.8x, pcmd=0x%.8x",
709                    cmd, type, ROAR_CODECFILTER_CTL2CMD(cmd));
710    roar_err_set(ROAR_ERROR_BADRQC);
711    return -1;
712   break;
713 }
714}
715
716
717#endif
718
719//ll
Note: See TracBrowser for help on using the repository browser.