source: roaraudio/roard/meta.c @ 1238:3c0eaf049201

Last change on this file since 1238:3c0eaf049201 was 1238:3c0eaf049201, checked in by phi, 15 years ago

done a lot to support meta data updates on encoding vorbis streams with meta flag set :), need cleanup.

File size: 5.5 KB
Line 
1//meta.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "roard.h"
26
27int stream_meta_set   (int id, int type, char * name, char * val) {
28 int i;
29 struct roar_stream_server * s = g_streams[id];
30
31 if ( s == NULL )
32  return -1;
33
34 for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++)
35  if ( s->meta[i].type == type ) {
36   s->meta[i].type = ROAR_META_TYPE_NONE;
37   if ( s->meta[i].value )
38    free(s->meta[i].value);
39   s->meta[i].value = NULL;
40  }
41
42 return stream_meta_add(id, type, name, val);
43}
44
45int stream_meta_add   (int id, int type, char * name, char * val) {
46 int i;
47 char * c;
48 struct roar_stream_server * s = g_streams[id];
49
50 if ( s == NULL )
51  return -1;
52
53 for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) {
54  if ( s->meta[i].type == ROAR_META_TYPE_NONE ) {
55   s->meta[i].type = type;
56
57   if ( name == NULL ) {
58    s->meta[i].key[0] = 0;
59   } else {
60    strncpy(s->meta[i].key, name, ROAR_META_MAX_NAMELEN);
61   }
62
63   if ( (c = malloc(strlen(val)+1)) == NULL ) {
64    s->meta[i].type = ROAR_META_TYPE_NONE;
65    s->meta[i].key[0] = 0;
66    return -1;
67   }
68
69   strcpy(c, val);
70   s->meta[i].value = c;
71
72   ROAR_DBG("stream_meta_add(id=%i, type=%i, name='%s', val='%s') = 0", id, type, name, val);
73
74   return 0;
75  }
76 }
77
78 return -1;
79}
80
81int stream_meta_get   (int id, int type, char * name, char * val, size_t len) {
82 int i, vallen;
83 struct roar_stream_server * s = g_streams[id];
84
85 if ( s == NULL )
86  return -1;
87
88 for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) {
89  if ( s->meta[i].type == type ) {
90   if ( name != NULL )
91    if ( strncmp(s->meta[i].key, name, ROAR_META_MAX_NAMELEN) != 0 )
92     continue;
93
94   if ( s->meta[i].value == NULL )
95    return -1;
96
97   if ( (vallen = strlen(s->meta[i].value)) > (len - 1) ) {
98    ROAR_DBG("stream_meta_get(*): val too small: need %i have %i", vallen, len);
99    return -1;
100   }
101
102   strncpy(val, s->meta[i].value, vallen);
103   val[vallen] = 0;
104
105   return 0;
106  }
107 }
108
109 return -1;
110}
111
112int stream_meta_list  (int id, int * types, size_t len) {
113 int i, j;
114 int have = 0;
115 int found;
116 struct roar_stream_server * s = g_streams[id];
117
118 if ( s == NULL )
119  return -1;
120
121 if ( len < ROAR_META_MAX_PER_STREAM ) // TODO: find a way we do not need this
122  return -1;
123
124 types[0] = -1;
125
126 for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) {
127  found = 0;
128  for (j = 0; j < have; j++)
129   if ( types[j] == s->meta[i].type ) {
130    found = 1;
131    break;
132   }
133
134  if ( !found )
135   types[have++] = s->meta[i].type;
136 }
137
138 return have;
139}
140
141int stream_meta_clear (int id) {
142 int i;
143 struct roar_stream_server * s = NULL;
144
145 if ( id < 0 || id > ROAR_STREAMS_MAX ) {
146  ROAR_ERR("stream_meta_clear(id=%i): Can not clear meta data on stream: invalid stream ID", id);
147  return -1;
148 }
149
150 s = g_streams[id];
151
152 if ( s == NULL )
153  return -1;
154
155 for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) {
156  s->meta[i].type   = ROAR_META_TYPE_NONE;
157  if ( s->meta[i].value )
158   free(s->meta[i].value);
159  s->meta[i].value  = NULL;
160  s->meta[i].key[0] = 0;
161 }
162
163 return 0;
164}
165
166int stream_meta_finalize(int id) {
167 register int dir;
168 register int co, ci, i;
169 struct roar_stream_server * s;
170
171 if ( streams_get_flag(id, ROAR_FLAG_META) != 1 ) // ignore non meta streams
172  return 0;
173
174 dir = ROAR_STREAM(g_streams[id])->dir;
175
176 if ( dir != ROAR_DIR_PLAY   && dir != ROAR_DIR_META &&  // ignore on non input streams
177      dir != ROAR_DIR_FILTER && dir != ROAR_DIR_BIDIR )
178  return 0;
179
180 ROAR_DBG("stream_meta_finalize(id=%i) = ?", id);
181
182 for (co = 0; co < ROAR_STREAMS_MAX; co++) {
183  if ( g_streams[co] == NULL )
184   continue;
185
186  dir = ROAR_STREAM(g_streams[co])->dir;
187
188  if ( dir != ROAR_DIR_MONITOR && dir != ROAR_DIR_FILTER &&
189       dir != ROAR_DIR_META    && dir != ROAR_DIR_BIDIR  &&
190       dir != ROAR_DIR_OUTPUT                             )
191   continue;
192
193  if ( streams_get_flag(co, ROAR_FLAG_META) != 1 )
194   continue;
195
196  ROAR_DBG("stream_meta_finalize(id=%i): found output stream: id=%i", id, co);
197  stream_meta_clear(co);
198
199  for (ci = 0; ci < ROAR_STREAMS_MAX; ci++) {
200   if ( g_streams[ci] == NULL )
201    continue;
202
203   dir = ROAR_STREAM(g_streams[ci])->dir;
204
205   if ( dir != ROAR_DIR_PLAY   && dir != ROAR_DIR_META &&
206        dir != ROAR_DIR_FILTER && dir != ROAR_DIR_BIDIR )
207    continue;
208
209   if ( streams_get_flag(ci, ROAR_FLAG_META) != 1 )
210    continue;
211
212   ROAR_DBG("stream_meta_finalize(id=%i): found input stream: id=%i", id, ci);
213
214   // ok, next we copy the date of ci to co:
215   s = g_streams[ci];
216
217   for (i = 0; i < ROAR_META_MAX_PER_STREAM; i++) {
218    if ( s->meta[i].type == ROAR_META_TYPE_NONE )
219     continue;
220
221    ROAR_DBG("stream_meta_finalize(id=%i): found meta data, copy: %i->%i", id, ci, co);
222    stream_meta_add(co, s->meta[i].type, s->meta[i].key, s->meta[i].value); // ignore errors
223   }
224  }
225
226  // ask the codec filter to update meta data:
227  streams_ctl(co, ROAR_CODECFILTER_CTL_META_UPDATE, NULL); // ignore errors...
228 }
229
230 return 0;
231}
232
233//ll
Note: See TracBrowser for help on using the repository browser.