1#include <support/Autolock.h> 2#include <media/MediaDefs.h> 3 4#include <stdio.h> 5#include <string.h> 6#include <unistd.h> 7 8#include <media/MediaAddOn.h> 9 10#include <Autolock.h> 11#include <Directory.h> 12#include <Entry.h> 13#include <Path.h> 14#include <String.h> 15 16 17#include "LegacyMediaAddOn.h" 18 19#include "LegacyAudioConsumer.h" 20#include "LegacyAudioProducer.h" 21 22#define LEGACY_DEVICE_PATH_BASE "/dev/audio/old" 23 24LegacyMediaAddOn::LegacyMediaAddOn( image_id imid ) 25 : BMediaAddOn( imid ) 26 , fInternalIds( 0 ) 27 , fListsLock( "LegacyMediaAddOn:ListLock" ) 28{ 29 fInitStatus = B_NO_INIT; 30 31 fMediaFormat.type = B_MEDIA_RAW_AUDIO; 32 fMediaFormat.u.raw_audio = media_raw_audio_format::wildcard; 33 34 fInitStatus = RecursiveScanForDevices(); 35 //consumer = new LegacyAudioConsumer( this, "ymf744/1", 0 ); 36 //producer = new LegacyAudioProducer( "maestro2/1" ); 37 38} 39 40 41LegacyMediaAddOn::~LegacyMediaAddOn() 42{ 43 //delete consumer; 44 //delete producer; 45 LegacyDevice *dev; 46 while ((dev = (LegacyDevice *)fConsumers.RemoveItem((int32)0))) { 47 delete dev->consumer; 48 //delete dev->producer; 49 delete dev; 50 } 51 while ((dev = (LegacyDevice *)fProducers.RemoveItem((int32)0))) { 52 //delete dev->consumer; 53 //delete dev->producer; 54 delete dev; 55 } 56 57 58} 59 60 61status_t 62LegacyMediaAddOn::InitCheck( const char **out_failure_text ) 63{ 64 return fInitStatus; 65} 66 67 68int32 69LegacyMediaAddOn::CountFlavors() 70{ 71 int32 count; 72 BAutolock al(fListsLock); 73 74 count = fConsumers.CountItems() + fProducers.CountItems(); 75 return count; 76} 77 78 79status_t 80LegacyMediaAddOn::GetFlavorAt( int32 n, const flavor_info **out_info ) 81{ 82 BAutolock al(fListsLock); 83 LegacyDevice *dev; 84 if (n < 0) 85 return EINVAL; 86 for (n = fConsumers.CountItems() - 1; n >= 0; n--) { 87 dev = (LegacyDevice *)fConsumers.ItemAt(n); 88 if (dev->flavor.internal_id != n) 89 continue; 90 *out_info = &dev->flavor; 91 return B_OK; 92 } 93 for (n = fProducers.CountItems() - 1; n >= 0; n--) { 94 dev = (LegacyDevice *)fProducers.ItemAt(n); 95 if (dev->flavor.internal_id != n) 96 continue; 97 *out_info = &dev->flavor; 98 return B_OK; 99 } 100 return B_ERROR; 101} 102 103 104BMediaNode * 105LegacyMediaAddOn::InstantiateNodeFor( const flavor_info *info, BMessage *config, status_t *out_error ) 106{ 107 BAutolock al(fListsLock); 108 LegacyDevice *dev; 109 int32 n; 110 int32 consumerCount = fConsumers.CountItems(); 111 for (n = consumerCount - 1; n >= 0; n--) { 112 dev = (LegacyDevice *)fConsumers.ItemAt(n); 113 //if (info != &dev->flavor) // XXX memcmp? 114 if (info->internal_id != dev->flavor.internal_id) 115 continue; 116 if (dev->inuse) // EBUSY! 117 return NULL; 118 dev->consumer = new LegacyAudioConsumer( this, dev->name.String(), n ); 119 if (!dev->consumer) 120 return NULL; 121 dev->inuse = true; 122 return dev->consumer; 123 } 124/* 125 for (n = fProducers.CountItems() - 1; n >= 0; n--) { 126 dev = (LegacyDevice *)fProducers.ItemAt(n); 127 if (info != &dev->flavor) // XXX memcmp? 128 continue; 129 if (dev->inuse) // EBUSY! 130 return NULL; 131 dev->producer = new LegacyAudioProducer( this, dev->name.String(), consumerCount + n ); 132 if (!dev->producer) 133 return NULL; 134 dev->inuse = true; 135 return dev->producer; 136 } 137*/ 138 return NULL; 139} 140 141status_t 142LegacyMediaAddOn::RecursiveScanForDevices(const char *path) 143{ 144 BDirectory d(path ? path : LEGACY_DEVICE_PATH_BASE); 145 if (d.InitCheck() < B_OK) 146 return d.InitCheck(); 147 BEntry ent; 148 while (d.GetNextEntry(&ent) == B_OK) { 149 struct stat st; 150 char name[B_FILE_NAME_LENGTH]; 151 ent.GetName(name); 152 if (d.GetStatFor(name, &st) < 0) 153 continue; 154 BPath p(&ent); 155 // we're only interested in folders... 156 if (S_ISDIR(st.st_mode)) { 157 RecursiveScanForDevices(p.Path()); 158 // discard error 159 continue; 160 } 161 // and (char) devices 162 if (!S_ISCHR(st.st_mode)) 163 continue; 164 165 // we want relative path 166 BString s(p.Path()); 167 s.RemoveFirst(LEGACY_DEVICE_PATH_BASE"/"); 168 169 // XXX: should check first for consumer or producer... 170 LegacyDevice *dev = new LegacyDevice; 171 dev->name = s.String(); 172 dev->flavor.name = (char *)/*WTF*/dev->name.String(); 173 dev->flavor.info = (char *)dev->name.String(); 174 dev->flavor.kinds = B_BUFFER_CONSUMER | /*B_CONTROLLABLE |*/ B_PHYSICAL_OUTPUT; 175 dev->flavor.flavor_flags = 0; //B_FLAVOR_IS_GLOBAL; 176 dev->flavor.internal_id = fInternalIds++; 177 dev->flavor.possible_count = 1; 178 dev->flavor.in_format_count = 1; 179 dev->flavor.in_format_flags = 0; 180 dev->flavor.in_formats = &fMediaFormat; 181 dev->flavor.out_format_count = 0; 182 dev->flavor.out_format_flags = 0; 183 dev->flavor.out_formats = NULL; 184 dev->inuse = false; 185 dev->consumer = NULL; 186 //dev->producer = NULL; 187 fConsumers.AddItem((void *)dev); 188 //XXX: only cons for now 189 //fProducers.AddItem(s.String()); 190 } 191 return B_OK; 192} 193 194#if 0 195 196struct flavor_info { 197 char * name; 198 char * info; 199 uint64 kinds; /* node_kind */ 200 uint32 flavor_flags; 201 int32 internal_id; /* For BMediaAddOn internal use */ 202 int32 possible_count; /* 0 for "any number" */ 203 204 int32 in_format_count; /* for BufferConsumer kinds */ 205 uint32 in_format_flags; /* set to 0 */ 206 const media_format * in_formats; 207 208 int32 out_format_count; /* for BufferProducer kinds */ 209 uint32 out_format_flags; /* set to 0 */ 210 const media_format * out_formats; 211 212 uint32 _reserved_[16]; 213 214private: 215 flavor_info & operator=(const flavor_info & other); 216}; 217#endif 218 219 220BMediaAddOn * 221make_media_addon( image_id imid ) 222{ 223 return new LegacyMediaAddOn( imid ); 224} 225