1 /* 2 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without restriction, 7 * including without limitation the rights to use, copy, modify, 8 * merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include "DVBMediaAddon.h" 26 #include "DVBCard.h" 27 #include "DVBMediaNode.h" 28 #include "config.h" 29 30 #include <string.h> 31 #include <stdio.h> 32 #include <time.h> 33 #include <Alert.h> 34 #include <Directory.h> 35 #include <Entry.h> 36 #include <Path.h> 37 38 struct device_info 39 { 40 DVBCard * card; 41 char name[200]; 42 char info[200]; 43 media_format formats[5]; 44 flavor_info flavor; 45 }; 46 47 48 extern "C" BMediaAddOn * 49 make_media_addon(image_id id) 50 { 51 return new DVBMediaAddon(id); 52 } 53 54 55 DVBMediaAddon::DVBMediaAddon(image_id id) 56 : BMediaAddOn(id) 57 { 58 ScanFolder("/dev/dvb"); 59 } 60 61 62 DVBMediaAddon::~DVBMediaAddon() 63 { 64 FreeDeviceList(); 65 } 66 67 68 status_t 69 DVBMediaAddon::InitCheck(const char ** out_failure_text) 70 { 71 debugger(""); 72 if (!fDeviceList.CountItems()) { 73 *out_failure_text = "No supported device found"; 74 return B_ERROR; 75 } 76 77 return B_OK; 78 } 79 80 81 int32 82 DVBMediaAddon::CountFlavors() 83 { 84 return fDeviceList.CountItems(); 85 } 86 87 88 status_t 89 DVBMediaAddon::GetFlavorAt(int32 n, const flavor_info ** out_info) 90 { 91 device_info *dev = (device_info *)fDeviceList.ItemAt(n); 92 if (!dev) 93 return B_ERROR; 94 *out_info = &dev->flavor; 95 return B_OK; 96 } 97 98 99 BMediaNode * 100 DVBMediaAddon::InstantiateNodeFor(const flavor_info * info, BMessage * config, status_t * out_error) 101 { 102 printf("DVB: DVBMediaAddon::InstantiateNodeFor\n"); 103 104 device_info *dev = (device_info *)fDeviceList.ItemAt(info->internal_id); 105 if (!dev || dev->flavor.internal_id != info->internal_id) { 106 *out_error = B_ERROR; 107 return NULL; 108 } 109 *out_error = B_OK; 110 111 return new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card); 112 } 113 114 115 bool 116 DVBMediaAddon::WantsAutoStart() 117 { 118 #if BUILD_FOR_HAIKU 119 // printf("DVB: DVBMediaAddon::WantsAutoStart - NO\n"); 120 return false; 121 #else 122 // printf("DVB: DVBMediaAddon::WantsAutoStart - YES\n"); 123 return true; 124 #endif 125 } 126 127 128 status_t 129 DVBMediaAddon::AutoStart(int index, BMediaNode **outNode, int32 *outInternalID, bool *outHasMore) 130 { 131 printf("DVB: DVBMediaAddon::AutoStart, index %d\n", index); 132 133 #if BUILD_FOR_HAIKU 134 return B_ERROR; 135 #else 136 137 device_info *dev = (device_info *)fDeviceList.ItemAt(index); 138 if (!dev) { 139 printf("DVB: DVBMediaAddon::AutoStart, bad index\n"); 140 return B_BAD_INDEX; 141 } 142 143 *outHasMore = fDeviceList.ItemAt(index + 1) ? true : false; 144 *outInternalID = dev->flavor.internal_id; 145 *outNode = new DVBMediaNode(this, dev->name, dev->flavor.internal_id, dev->card); 146 147 printf("DVB: DVBMediaAddon::AutoStart, success\n"); 148 149 return B_OK; 150 #endif 151 } 152 153 154 void 155 DVBMediaAddon::ScanFolder(const char *path) 156 { 157 BDirectory dir(path); 158 if (dir.InitCheck() != B_OK) 159 return; 160 161 BEntry ent; 162 163 while (dir.GetNextEntry(&ent) == B_OK) { 164 BPath path(&ent); 165 if (ent.IsDirectory()) { 166 ScanFolder(path.Path()); 167 } else { 168 DVBCard *card = new DVBCard(path.Path()); 169 if (card->InitCheck() == B_OK) 170 AddDevice(card, path.Path()); 171 else 172 delete card; 173 } 174 } 175 } 176 177 178 void 179 DVBMediaAddon::AddDevice(DVBCard *card, const char *path) 180 { 181 dvb_type_t type; 182 char name[250]; 183 char info[1000]; 184 const char *dvbtype; 185 const char *dvbnumber; 186 187 // get card name, info and type 188 if (B_OK != card->GetCardType(&type)) { 189 printf("DVBMediaAddon::AddDevice: getting DVB card type failed\n"); 190 return; 191 } 192 if (B_OK != card->GetCardInfo(name, sizeof(name), info, sizeof(info))) { 193 printf("DVBMediaAddon::AddDevice: getting DVB card info failed\n"); 194 return; 195 } 196 197 // get type 198 switch (type) { 199 case DVB_TYPE_DVB_C: dvbtype = "C"; break; 200 case DVB_TYPE_DVB_H: dvbtype = "H"; break; 201 case DVB_TYPE_DVB_S: dvbtype = "S"; break; 202 case DVB_TYPE_DVB_T: dvbtype = "T"; break; 203 default: 204 printf("DVBMediaAddon::AddDevice: unsupported DVB type %d\n", type); 205 return; 206 } 207 208 // get interface number 209 const char *p = strrchr(path, '/'); 210 dvbnumber = p ? p + 1 : ""; 211 212 // create device_info 213 device_info *dev = new device_info; 214 fDeviceList.AddItem(dev); 215 216 dev->card = card; 217 218 // setup name and info, it's important that name starts with "DVB" 219 // snprintf(dev->name, sizeof(dev->name), "DVB-%s %s (%s)", dvbtype, dvbnumber, name); 220 // strlcpy(dev->info, info, sizeof(dev->info)); 221 sprintf(dev->name, "DVB-%s %s %s", dvbtype, name, dvbnumber); 222 strcpy(dev->info, info); 223 224 // setup supported formats (the lazy way) 225 memset(dev->formats, 0, sizeof(dev->formats)); 226 dev->formats[0].type = B_MEDIA_RAW_VIDEO; 227 dev->formats[1].type = B_MEDIA_RAW_AUDIO; 228 dev->formats[2].type = B_MEDIA_ENCODED_VIDEO; 229 dev->formats[3].type = B_MEDIA_ENCODED_AUDIO; 230 dev->formats[4].type = B_MEDIA_MULTISTREAM; 231 232 // setup flavor info 233 dev->flavor.name = dev->name; 234 dev->flavor.info = dev->info; 235 dev->flavor.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT; 236 dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL; 237 dev->flavor.internal_id = fDeviceList.CountItems() - 1; 238 dev->flavor.possible_count = 1; 239 dev->flavor.in_format_count = 0; 240 dev->flavor.in_format_flags = 0; 241 dev->flavor.in_formats = 0; 242 dev->flavor.out_format_count = 5; 243 dev->flavor.out_format_flags = 0; 244 dev->flavor.out_formats = dev->formats; 245 } 246 247 248 void 249 DVBMediaAddon::FreeDeviceList() 250 { 251 device_info *dev; 252 while ((dev = (device_info *)fDeviceList.RemoveItem((int32)0))) { 253 delete dev->card; 254 delete dev; 255 } 256 } 257