1 /* 2 * FireWire DV media addon for Haiku 3 * 4 * Copyright (c) 2008, JiSheng Zhang (jszhang3@mail.ustc.edu.cn) 5 * Distributed under the terms of the MIT License. 6 * 7 * Based on DVB media addon 8 * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de> 9 */ 10 11 #include "FireWireDVAddOn.h" 12 #include "FireWireCard.h" 13 #include "FireWireDVNode.h" 14 15 #include <stdio.h> 16 #include <string.h> 17 #include <time.h> 18 19 #include <Alert.h> 20 #include <Directory.h> 21 #include <Entry.h> 22 #include <Path.h> 23 24 #include "debug.h" 25 26 struct device_info 27 { 28 FireWireCard* card; 29 char name[16]; 30 media_format in_formats[1]; 31 media_format out_formats[1]; 32 flavor_info flavor; 33 }; 34 35 extern "C" BMediaAddOn* 36 make_media_addon(image_id id) 37 { 38 CALLED(); 39 return new FireWireDVAddOn(id); 40 } 41 42 43 FireWireDVAddOn::FireWireDVAddOn(image_id id) 44 : BMediaAddOn(id) 45 { 46 CALLED(); 47 ScanFolder("/dev/bus/fw"); 48 } 49 50 51 FireWireDVAddOn::~FireWireDVAddOn() 52 { 53 CALLED(); 54 FreeDeviceList(); 55 } 56 57 58 status_t 59 FireWireDVAddOn::InitCheck(const char** out_failure_text) 60 { 61 CALLED(); 62 if (!fDeviceList.CountItems()) { 63 *out_failure_text = "No supported device found"; 64 return B_ERROR; 65 } 66 return B_OK; 67 } 68 69 70 int32 71 FireWireDVAddOn::CountFlavors() 72 { 73 CALLED(); 74 return fDeviceList.CountItems(); 75 } 76 77 78 status_t 79 FireWireDVAddOn::GetFlavorAt(int32 n, const flavor_info** out_info) 80 { 81 CALLED(); 82 device_info* dev = fDeviceList.ItemAt(n); 83 if (!dev) 84 return B_ERROR; 85 *out_info = &dev->flavor; 86 return B_OK; 87 } 88 89 90 BMediaNode * 91 FireWireDVAddOn::InstantiateNodeFor(const flavor_info* info, BMessage* config, 92 status_t* out_error) 93 { 94 CALLED(); 95 device_info* dev = fDeviceList.ItemAt(info->internal_id); 96 if (!dev || dev->flavor.internal_id != info->internal_id) { 97 *out_error = B_ERROR; 98 return NULL; 99 } 100 *out_error = B_OK; 101 102 return new FireWireDVNode(this, dev->name, dev->flavor.internal_id, 103 dev->card); 104 } 105 106 107 bool 108 FireWireDVAddOn::WantsAutoStart() 109 { 110 CALLED(); 111 return false; 112 } 113 114 115 status_t 116 FireWireDVAddOn::AutoStart(int index, BMediaNode** outNode, 117 int32* outInternalID, bool* outHasMore) 118 { 119 CALLED(); 120 return B_ERROR; 121 } 122 123 124 void 125 FireWireDVAddOn::ScanFolder(const char* path) 126 { 127 CALLED(); 128 BDirectory dir(path); 129 if (dir.InitCheck() != B_OK) 130 return; 131 132 BEntry ent; 133 134 while (dir.GetNextEntry(&ent) == B_OK) { 135 BPath path(&ent); 136 if (!ent.IsDirectory() && !ent.IsSymLink()) { 137 FireWireCard *card = new FireWireCard(path.Path()); 138 if (card->InitCheck() == B_OK) 139 AddDevice(card, path.Path()); 140 else 141 delete card; 142 } 143 } 144 } 145 146 147 void 148 FireWireDVAddOn::AddDevice(FireWireCard* card, const char* path) 149 { 150 const char* fwnumber; 151 152 // get card name, info and type 153 154 // get interface number 155 const char *p = strrchr(path, '/'); 156 fwnumber = p ? p + 1 : ""; 157 158 // create device_info 159 device_info *dev = new device_info; 160 fDeviceList.AddItem(dev); 161 162 dev->card = card; 163 164 sprintf(dev->name, "FireWire-%s", fwnumber); 165 166 // setup supported formats (the lazy way) 167 memset(dev->in_formats, 0, sizeof(dev->in_formats)); 168 memset(dev->out_formats, 0, sizeof(dev->out_formats)); 169 dev->in_formats[0].type = B_MEDIA_ENCODED_VIDEO; 170 dev->out_formats[0].type = B_MEDIA_ENCODED_VIDEO; 171 172 // setup flavor info 173 dev->flavor.name = dev->name; 174 dev->flavor.info = (char *)"The FireWireDVNode outputs to fw_raw drivers."; 175 dev->flavor.kinds = B_BUFFER_CONSUMER | B_BUFFER_PRODUCER 176 | B_CONTROLLABLE | B_PHYSICAL_OUTPUT | B_PHYSICAL_INPUT; 177 dev->flavor.flavor_flags = B_FLAVOR_IS_GLOBAL; 178 dev->flavor.internal_id = fDeviceList.CountItems() - 1; 179 dev->flavor.possible_count = 1; 180 dev->flavor.in_format_count = 1; 181 dev->flavor.in_format_flags = 0; 182 dev->flavor.in_formats = dev->in_formats; 183 dev->flavor.out_format_count = 1; 184 dev->flavor.out_format_flags = 0; 185 dev->flavor.out_formats = dev->out_formats; 186 } 187 188 189 void 190 FireWireDVAddOn::FreeDeviceList() 191 { 192 device_info* dev; 193 while ((dev = fDeviceList.RemoveItemAt(0L))) { 194 delete dev->card; 195 delete dev; 196 } 197 } 198 199