1 #include <support/Autolock.h> 2 #include <media/MediaFormats.h> 3 4 #include <stdio.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 #include "AddOn.h" 9 #include "Producer.h" 10 #include "CamRoster.h" 11 #include "CamDebug.h" 12 #include "CamDevice.h" 13 14 WebCamMediaAddOn::WebCamMediaAddOn(image_id imid) 15 : BMediaAddOn(imid), 16 fInitStatus(B_NO_INIT), 17 fRoster(NULL) 18 { 19 PRINT((CH "()" CT)); 20 /* Customize these parameters to match those of your node */ 21 fMediaFormat.type = B_MEDIA_RAW_VIDEO; 22 fMediaFormat.u.raw_video = media_raw_video_format::wildcard; 23 fMediaFormat.u.raw_video.interlace = 1; 24 fMediaFormat.u.raw_video.display.format = B_RGB32; 25 FillDefaultFlavorInfo(&fDefaultFlavorInfo); 26 27 fRoster = new CamRoster(this); 28 fRoster->Start(); 29 // if( fRoster->CountCameras() < 1 ) 30 /* fInitStatus = B_ERROR; 31 else 32 */ 33 fInitStatus = B_OK; 34 } 35 36 WebCamMediaAddOn::~WebCamMediaAddOn() 37 { 38 delete fRoster; 39 } 40 41 42 status_t 43 WebCamMediaAddOn::InitCheck(const char **out_failure_text) 44 { 45 if (fInitStatus < B_OK) { 46 *out_failure_text = "No cameras attached"; 47 return fInitStatus; 48 } 49 50 return B_OK; 51 } 52 53 int32 54 WebCamMediaAddOn::CountFlavors() 55 { 56 PRINT((CH "()" CT)); 57 int32 count; 58 if (!fRoster) 59 return B_NO_INIT; 60 if (fInitStatus < B_OK) 61 return fInitStatus; 62 63 /* This addon only supports a single flavor, as defined in the 64 * constructor */ 65 count = fRoster->CountCameras(); 66 return count;//(count > 0)?count:1;//1; 67 } 68 69 /* 70 * The pointer to the flavor received only needs to be valid between 71 * successive calls to BMediaAddOn::GetFlavorAt(). 72 */ 73 status_t 74 WebCamMediaAddOn::GetFlavorAt(int32 n, const flavor_info **out_info) 75 { 76 PRINT((CH "(%d, ) roster %p is %lx" CT, n, fRoster, fInitStatus)); 77 int32 count; 78 CamDevice* cam; 79 if (!fRoster) 80 return B_NO_INIT; 81 if (fInitStatus < B_OK) 82 return fInitStatus; 83 84 count = fRoster->CountCameras(); 85 PRINT((CH ": %d cameras" CT, count)); 86 if (n >= count)//(n != 0) 87 return B_BAD_INDEX; 88 89 fRoster->Lock(); 90 cam = fRoster->CameraAt(n); 91 *out_info = &fDefaultFlavorInfo; 92 if (cam && cam->FlavorInfo()) 93 *out_info = cam->FlavorInfo(); 94 fRoster->Unlock(); 95 PRINT((CH ": returning flavor for %d" CT, n)); 96 return B_OK; 97 } 98 99 BMediaNode * 100 WebCamMediaAddOn::InstantiateNodeFor( 101 const flavor_info *info, BMessage* /*_config*/, status_t* /*_out_error*/) 102 { 103 PRINT((CH "()" CT)); 104 VideoProducer *node; 105 CamDevice *cam=NULL; 106 107 if (fInitStatus < B_OK) 108 return NULL; 109 110 fRoster->Lock(); 111 for (int i = 0; i < fRoster->CountCameras(); i++) { 112 CamDevice *c; 113 c = fRoster->CameraAt(i); 114 PRINT((CH ": cam[%d]: %d, %s" CT, i, c->FlavorInfo()->internal_id, c->BrandName())); 115 if (c && (c->FlavorInfo()->internal_id == info->internal_id)) { 116 cam = c; 117 break; 118 } 119 } 120 fRoster->Unlock(); 121 if (!cam) 122 return NULL; 123 124 #if 0 125 fRoster->Lock(); 126 cam = fRoster->CameraAt(n); 127 *out_info = &fDefaultFlavorInfo; 128 if (cam && cam->FlavorInfo()) 129 *out_info = cam->FlavorInfo(); 130 fRoster->Unlock(); 131 #endif 132 /* At most one instance of the node should be instantiated at any given 133 * time. The locking for this restriction may be found in the VideoProducer 134 * class. */ 135 node = new VideoProducer(this, cam, cam->FlavorInfo()->name, fDefaultFlavorInfo.internal_id); 136 if (node && (node->InitCheck() < B_OK)) { 137 delete node; 138 node = NULL; 139 } 140 141 return node; 142 } 143 144 status_t 145 WebCamMediaAddOn::CameraAdded(CamDevice* device) 146 { 147 PRINT((CH "()" CT)); 148 NotifyFlavorChange(); 149 } 150 151 status_t 152 WebCamMediaAddOn::CameraRemoved(CamDevice* device) 153 { 154 PRINT((CH "()" CT)); 155 NotifyFlavorChange(); 156 } 157 158 void 159 WebCamMediaAddOn::FillDefaultFlavorInfo(flavor_info* info) 160 { 161 info->name = "USB Web Camera"; 162 info->info = "USB Web Camera"; 163 info->kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT; 164 info->flavor_flags = 0;//B_FLAVOR_IS_GLOBAL; 165 info->internal_id = atomic_add((vint32 *)&fInternalIDCounter, 1); 166 info->possible_count = 1;//0; 167 info->in_format_count = 0; 168 info->in_format_flags = 0; 169 info->in_formats = NULL; 170 info->out_format_count = 1; 171 info->out_format_flags = 0; 172 info->out_formats = &fMediaFormat; 173 } 174 175 BMediaAddOn * 176 make_media_addon(image_id imid) 177 { 178 return new WebCamMediaAddOn(imid); 179 } 180