VideoConsumer.cpp (f50d7408b5407052b1a0f743a17a360d64626ccc) VideoConsumer.cpp (dba5824b)
1// Copyright (c) 1998-99, Be Incorporated, All Rights Reserved.
2// SMS
3// VideoConsumer.cpp
4
1// Copyright (c) 1998-99, Be Incorporated, All Rights Reserved.
2// SMS
3// VideoConsumer.cpp
4
5
6#include "FileUploadClient.h"
7#include "FtpClient.h"
8#include "SftpClient.h"
9#include "VideoConsumer.h"
10
11#include <fcntl.h>
5#include <View.h>
12#include <stdio.h>
6#include <stdio.h>
7#include <fcntl.h>
8#include <Buffer.h>
13#include <unistd.h>
14#include <string.h>
9#include <unistd.h>
10#include <string.h>
15
16#include <Application.h>
17#include <Buffer.h>
18#include <BufferGroup.h>
19#include <Catalog.h>
20#include <Locale.h>
21#include <MediaRoster.h>
22#include <NodeInfo.h>
23#include <scheduler.h>
11#include <NodeInfo.h>
12#include <scheduler.h>
24#include <StringView.h>
25#include <TimeSource.h>
13#include <TimeSource.h>
26#include
14#include <StringView.h>
15#include <MediaRoster.h>
16#include <Application.h>
17#include <BufferGroup.h>
27
18
19#include "FtpClient.h"
20#include "VideoConsumer.h"
28
21
29#undef B_TRANSLATION_CONTEXT
30#define B_TRANSLATION_CONTEXT "VideoConsumer.cpp"
31
32#define M1 ((double)1000000.0)
33#define JITTER 20000
34
35#define FUNCTION printf
36#define ERROR printf
37#define PROGRESS printf
38#define LOOP printf
39
22#define M1 ((double)1000000.0)
23#define JITTER 20000
24
25#define FUNCTION printf
26#define ERROR printf
27#define PROGRESS printf
28#define LOOP printf
29
30static status_t SetFileType(BFile * file, int32 translator, uint32 type);
40
31
41static status_t SetFileType(BFile* file, int32 translator, uint32 type);
32const media_raw_video_format vid_format = { 29.97,1,0,239,B_VIDEO_TOP_LEFT_RIGHT,1,1,{B_RGB16,320,240,320*4,0,0}};
42
33
43const media_raw_video_format vid_format = {29.97, 1, 0, 239,
44 B_VIDEO_TOP_LEFT_RIGHT, 1, 1, {B_RGB16, 320, 240, 320 * 4, 0, 0}};
34//---------------------------------------------------------------
45
35
46
47VideoConsumer::VideoConsumer(const char* name, BView* view,
48 BStringView* statusLine,
49 BMediaAddOn* addon, const uint32 internalId)
50 : BMediaNode(name),
36VideoConsumer::VideoConsumer(
37 const char * name,
38 BView *view,
39 BStringView * statusLine,
40 BMediaAddOn *addon,
41 const uint32 internal_id) :
42
43 BMediaNode(name),
51 BMediaEventLooper(),
52 BBufferConsumer(B_MEDIA_RAW_VIDEO),
44 BMediaEventLooper(),
45 BBufferConsumer(B_MEDIA_RAW_VIDEO),
53 fStatusLine(statusLine),
54 fInternalID(internalId),
55 fAddOn(addon),
56 fConnectionActive(false),
57 fMyLatency(20000),
58 fWindow(NULL),
59 fView(view),
60 fOurBuffers(false),
61 fBuffers(NULL),
62 fTimeToFtp(false),
63 fFtpComplete(true),
64 fRate(1000000),
65 fImageFormat(0),
66 fTranslator(0),
67 fUploadClient(0),
68 fPassiveFtp(true)
46 mView(view),
47 mWindow(NULL),
48 mStatusLine(statusLine),
49 mInternalID(internal_id),
50 mAddOn(addon),
51 mTimeToFtp(false),
52 mFtpComplete(true),
53 mRate(1000000),
54 mImageFormat(0),
55 mTranslator(0),
56 mPassiveFtp(true),
57 mConnectionActive(false),
58 mMyLatency(20000),
59 mBuffers(NULL),
60 mOurBuffers(false)
69{
70 FUNCTION("VideoConsumer::VideoConsumer\n");
71
72 AddNodeKind(B_PHYSICAL_OUTPUT);
73 SetEventLatency(0);
61{
62 FUNCTION("VideoConsumer::VideoConsumer\n");
63
64 AddNodeKind(B_PHYSICAL_OUTPUT);
65 SetEventLatency(0);
74 fWindow = fView->Window();
75
76 for (uint32 j = 0; j < 3; j++) {
77 fBitmap[j] = NULL;
78 fBufferMap[j] = 0;
66 mWindow = mView->Window();
67
68 for (uint32 j = 0; j < 3; j++)
69 {
70 mBitmap[j] = NULL;
71 mBufferMap[j] = 0;
79 }
72 }
73
74 strcpy(mFileNameText, "");
75 strcpy(mServerText, "");
76 strcpy(mLoginText, "");
77 strcpy(mPasswordText, "");
78 strcpy(mDirectoryText, "");
80
79
81 strcpy(fFileNameText, "");
82 strcpy(fServerText, "");
83 strcpy(fLoginText, "");
84 strcpy(fPasswordText, "");
85 strcpy(fDirectoryText, "");
86
87 SetPriority(B_DISPLAY_PRIORITY);
88}
89
80 SetPriority(B_DISPLAY_PRIORITY);
81}
82
83//---------------------------------------------------------------
90
91VideoConsumer::~VideoConsumer()
92{
93 FUNCTION("VideoConsumer::~VideoConsumer\n");
84
85VideoConsumer::~VideoConsumer()
86{
87 FUNCTION("VideoConsumer::~VideoConsumer\n");
94
88 status_t status;
89
95 Quit();
96
90 Quit();
91
97 if (fWindow) {
98 printf(B_TRANSLATE("Locking the window\n"));
99 if (fWindow->Lock()) {
100 printf(B_TRANSLATE("Closing the window\n"));
101 fWindow->Close();
102 fWindow = 0;
92 if (mWindow)
93 {
94 printf("Locking the window\n");
95 if (mWindow->Lock())
96 {
97 printf("Closing the window\n");
98 mWindow->Close();
99 mWindow = 0;
103 }
104 }
105
106 // clean up ftp thread
107 // wait up to 30 seconds if ftp is in progress
108 int32 count = 0;
100 }
101 }
102
103 // clean up ftp thread
104 // wait up to 30 seconds if ftp is in progress
105 int32 count = 0;
109 while (!fFtpComplete && count < 30) {
106 while (!mFtpComplete && (count < 30))
107 {
110 snooze(1000000);
111 count++;
112 }
108 snooze(1000000);
109 count++;
110 }
113
114 if (count == 30)
115 kill_thread(fFtpThread);
116
111
112 if(count == 30)
113 kill_thread(mFtpThread);
114
117 DeleteBuffers();
115 DeleteBuffers();
118
116
117
119}
120
121/********************************
122 From BMediaNode
123********************************/
124
118}
119
120/********************************
121 From BMediaNode
122********************************/
123
124//---------------------------------------------------------------
125
125
126BMediaAddOn*
127VideoConsumer::AddOn(int32* cookie) const
126BMediaAddOn *
127VideoConsumer::AddOn(long *cookie) const
128{
129 FUNCTION("VideoConsumer::AddOn\n");
130 // do the right thing if we're ever used with an add-on
128{
129 FUNCTION("VideoConsumer::AddOn\n");
130 // do the right thing if we're ever used with an add-on
131 *cookie = fInternalID;
132 return fAddOn;
131 *cookie = mInternalID;
132 return mAddOn;
133}
134
133}
134
135//---------------------------------------------------------------
135
136// This implementation is required to get around a bug in
137// the ppc compiler.
138
136
137// This implementation is required to get around a bug in
138// the ppc compiler.
139
139void
140VideoConsumer::Start(bigtime_t performanceTime)
140void
141VideoConsumer::Start(bigtime_t performance_time)
141{
142{
142 BMediaEventLooper::Start(performanceTime);
143 BMediaEventLooper::Start(performance_time);
143}
144
144}
145
145
146void
147VideoConsumer::Stop(bigtime_t performanceTime, bool immediate)
146void
147VideoConsumer::Stop(bigtime_t performance_time, bool immediate)
148{
148{
149 BMediaEventLooper::Stop(performanceTime, immediate);
149 BMediaEventLooper::Stop(performance_time, immediate);
150}
151
150}
151
152
153void
154VideoConsumer::Seek(bigtime_t mediaTime, bigtime_t performanceTime)
152void
153VideoConsumer::Seek(bigtime_t media_time, bigtime_t performance_time)
155{
154{
156 BMediaEventLooper::Seek(mediaTime, performanceTime);
155 BMediaEventLooper::Seek(media_time, performance_time);
157}
158
156}
157
159
160void
161VideoConsumer::TimeWarp(bigtime_t atRealTime, bigtime_t toPerformanceTime)
158void
159VideoConsumer::TimeWarp(bigtime_t at_real_time, bigtime_t to_performance_time)
162{
160{
163 BMediaEventLooper::TimeWarp(atRealTime, toPerformanceTime);
161 BMediaEventLooper::TimeWarp(at_real_time, to_performance_time);
164}
165
162}
163
166
167status_t
168VideoConsumer::DeleteHook(BMediaNode* node)
164status_t
165VideoConsumer::DeleteHook(BMediaNode *node)
169{
170 return BMediaEventLooper::DeleteHook(node);
171}
172
166{
167 return BMediaEventLooper::DeleteHook(node);
168}
169
170//---------------------------------------------------------------
173
174void
175VideoConsumer::NodeRegistered()
176{
177 FUNCTION("VideoConsumer::NodeRegistered\n");
171
172void
173VideoConsumer::NodeRegistered()
174{
175 FUNCTION("VideoConsumer::NodeRegistered\n");
178 fIn.destination.port = ControlPort();
179 fIn.destination.id = 0;
180 fIn.source = media_source::null;
181 fIn.format.type = B_MEDIA_RAW_VIDEO;
182 fIn.format.u.raw_video = vid_format;
176 mIn.destination.port = ControlPort();
177 mIn.destination.id = 0;
178 mIn.source = media_source::null;
179 mIn.format.type = B_MEDIA_RAW_VIDEO;
180 mIn.format.u.raw_video = vid_format;
183
184 Run();
185}
186
181
182 Run();
183}
184
185//---------------------------------------------------------------
187
188status_t
186
187status_t
189VideoConsumer::RequestCompleted(const media_request_info& info)
188VideoConsumer::RequestCompleted(const media_request_info & info)
190{
191 FUNCTION("VideoConsumer::RequestCompleted\n");
189{
190 FUNCTION("VideoConsumer::RequestCompleted\n");
192 switch (info.what) {
191 switch(info.what)
192 {
193 case media_request_info::B_SET_OUTPUT_BUFFERS_FOR:
193 case media_request_info::B_SET_OUTPUT_BUFFERS_FOR:
194 if (info.status != B_OK)
194 {
195 if (info.status != B_OK)
195 ERROR("VideoConsumer::RequestCompleted: Not using our buffers!\n");
196 ERROR("VideoConsumer::RequestCompleted: Not using our buffers!\n");
197 }
196 break;
198 break;
197
198 default:
199 ERROR("VideoConsumer::RequestCompleted: Invalid argument\n");
200 break;
201 }
202 return B_OK;
203}
204
199 }
200 return B_OK;
201}
202
203//---------------------------------------------------------------
205
206status_t
204
205status_t
207VideoConsumer::HandleMessage(int32 message, const void* data, size_t size)
206VideoConsumer::HandleMessage(int32 message, const void * data, size_t size)
208{
209 //FUNCTION("VideoConsumer::HandleMessage\n");
207{
208 //FUNCTION("VideoConsumer::HandleMessage\n");
210 ftp_msg_info* info = (ftp_msg_info*)data;
209 ftp_msg_info *info = (ftp_msg_info *)data;
211 status_t status = B_OK;
210 status_t status = B_OK;
212
213 switch (message) {
211
212 switch (message)
213 {
214 case FTP_INFO:
215 PROGRESS("VideoConsumer::HandleMessage - FTP_INFO message\n");
214 case FTP_INFO:
215 PROGRESS("VideoConsumer::HandleMessage - FTP_INFO message\n");
216 fRate = info->rate;
217 fImageFormat = info->imageFormat;
218 fTranslator = info->translator;
219 fPassiveFtp = info->passiveFtp;
220 fUploadClient = info->uploadClient;
221 strcpy(fFileNameText, info->fileNameText);
222 strcpy(fServerText, info->serverText);
223 strcpy(fLoginText, info->loginText);
224 strcpy(fPasswordText, info->passwordText);
225 strcpy(fDirectoryText, info->directoryText);
216 mRate = info->rate;
217 mImageFormat = info->imageFormat;
218 mTranslator = info->translator;
219 mPassiveFtp = info->passiveFtp;
220 strcpy(mFileNameText, info->fileNameText);
221 strcpy(mServerText, info->serverText);
222 strcpy(mLoginText, info->loginText);
223 strcpy(mPasswordText, info->passwordText);
224 strcpy(mDirectoryText, info->directoryText);
226 // remove old user events
225 // remove old user events
227 EventQueue()->FlushEvents(TimeSource()->Now(), BTimedEventQueue::B_ALWAYS,
228 true, BTimedEventQueue::B_USER_EVENT);
229 if (fRate != B_INFINITE_TIMEOUT) {
230 // if rate is not "Never," push an event
231 // to restart captures 5 seconds from now
232 media_timed_event event(TimeSource()->Now() + 5000000,
233 BTimedEventQueue::B_USER_EVENT);
226 EventQueue()->FlushEvents(TimeSource()->Now(), BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_USER_EVENT);
227 if (mRate != B_INFINITE_TIMEOUT) {
228 // if rate is not "Never," push an event to restart captures 5 seconds from now
229 media_timed_event event(TimeSource()->Now() + 5000000, BTimedEventQueue::B_USER_EVENT);
234 EventQueue()->AddEvent(event);
235 }
236 break;
237 }
230 EventQueue()->AddEvent(event);
231 }
232 break;
233 }
238
234
239 return status;
240}
241
235 return status;
236}
237
238//---------------------------------------------------------------
242
243void
239
240void
244VideoConsumer::BufferReceived(BBuffer* buffer)
241VideoConsumer::BufferReceived(BBuffer * buffer)
245{
242{
246 LOOP("VideoConsumer::Buffer #%" B_PRId32 " received, start_time %" B_PRIdBIGTIME
247 "\n", buffer->ID(), buffer->Header()->start_time);
243 LOOP("VideoConsumer::Buffer #%d received\n", buffer->ID());
248
244
249 if (RunState() == B_STOPPED) {
245 if (RunState() == B_STOPPED)
246 {
250 buffer->Recycle();
251 return;
252 }
253
254 media_timed_event event(buffer->Header()->start_time, BTimedEventQueue::B_HANDLE_BUFFER,
247 buffer->Recycle();
248 return;
249 }
250
251 media_timed_event event(buffer->Header()->start_time, BTimedEventQueue::B_HANDLE_BUFFER,
255 buffer, BTimedEventQueue::B_RECYCLE_BUFFER);
252 buffer, BTimedEventQueue::B_RECYCLE_BUFFER);
256 EventQueue()->AddEvent(event);
257}
258
259
253 EventQueue()->AddEvent(event);
254}
255
256
257//---------------------------------------------------------------
258
260void
259void
261VideoConsumer::ProducerDataStatus(const media_destination& forWhom, int32 status,
262 bigtime_t atMediaTime)
260VideoConsumer::ProducerDataStatus(
261 const media_destination &for_whom,
262 int32 status,
263 bigtime_t at_media_time)
263{
264 FUNCTION("VideoConsumer::ProducerDataStatus\n");
265
264{
265 FUNCTION("VideoConsumer::ProducerDataStatus\n");
266
266 if (forWhom != fIn.destination)
267 if (for_whom != mIn.destination)
267 return;
268}
269
268 return;
269}
270
271//---------------------------------------------------------------
270
271status_t
272
273status_t
272VideoConsumer::CreateBuffers(const media_format& withFormat)
274VideoConsumer::CreateBuffers(
275 const media_format & with_format)
273{
274 FUNCTION("VideoConsumer::CreateBuffers\n");
276{
277 FUNCTION("VideoConsumer::CreateBuffers\n");
278
279 // delete any old buffers
280 DeleteBuffers();
275
281
276 DeleteBuffers();
277 // delete any old buffers
278
279 status_t status = B_OK;
280
281 // create a buffer group
282 status_t status = B_OK;
283
284 // create a buffer group
282 uint32 xSize = withFormat.u.raw_video.display.line_width;
283 uint32 ySize = withFormat.u.raw_video.display.line_count;
284 color_space colorspace = withFormat.u.raw_video.display.format;
285 PROGRESS("VideoConsumer::CreateBuffers - Colorspace = %d\n", colorspace);
285 uint32 mXSize = with_format.u.raw_video.display.line_width;
286 uint32 mYSize = with_format.u.raw_video.display.line_count;
287 uint32 mRowBytes = with_format.u.raw_video.display.bytes_per_row;
288 color_space mColorspace = with_format.u.raw_video.display.format;
289 PROGRESS("VideoConsumer::CreateBuffers - Colorspace = %d\n", mColorspace);
286
290
287 fBuffers = new BBufferGroup();
288 status = fBuffers->InitCheck();
289 if (status != B_OK) {
291 mBuffers = new BBufferGroup();
292 status = mBuffers->InitCheck();
293 if (B_OK != status)
294 {
290 ERROR("VideoConsumer::CreateBuffers - ERROR CREATING BUFFER GROUP\n");
291 return status;
292 }
293 // and attach the bitmaps to the buffer group
295 ERROR("VideoConsumer::CreateBuffers - ERROR CREATING BUFFER GROUP\n");
296 return status;
297 }
298 // and attach the bitmaps to the buffer group
294 for (uint32 j = 0; j < 3; j++) {
295 fBitmap[j] = new BBitmap(BRect(0, 0, (xSize - 1), (ySize - 1)), colorspace,
296 false, true);
297 if (fBitmap[j]->IsValid()) {
299 for (uint32 j=0; j < 3; j++)
300 {
301 mBitmap[j] = new BBitmap(BRect(0, 0, (mXSize-1), (mYSize - 1)), mColorspace, false, true);
302 if (mBitmap[j]->IsValid())
303 {
298 buffer_clone_info info;
304 buffer_clone_info info;
299 if ((info.area = area_for(fBitmap[j]->Bits())) == B_ERROR)
300 ERROR("VideoConsumer::CreateBuffers - ERROR IN AREA_FOR\n");
305 if ((info.area = area_for(mBitmap[j]->Bits())) == B_ERROR)
306 ERROR("VideoConsumer::CreateBuffers - ERROR IN AREA_FOR\n");;
301 info.offset = 0;
307 info.offset = 0;
302 info.size = (size_t)fBitmap[j]->BitsLength();
308 info.size = (size_t)mBitmap[j]->BitsLength();
303 info.flags = j;
304 info.buffer = 0;
305
309 info.flags = j;
310 info.buffer = 0;
311
306 if ((status = fBuffers->AddBuffer(info)) != B_OK) {
312 if ((status = mBuffers->AddBuffer(info)) != B_OK)
313 {
307 ERROR("VideoConsumer::CreateBuffers - ERROR ADDING BUFFER TO GROUP\n");
308 return status;
314 ERROR("VideoConsumer::CreateBuffers - ERROR ADDING BUFFER TO GROUP\n");
315 return status;
309 }
310 else
311 PROGRESS("VideoConsumer::CreateBuffers - SUCCESSFUL ADD BUFFER TO GROUP\n");
312 } else {
313 ERROR("VideoConsumer::CreateBuffers - ERROR CREATING VIDEO RING "
314 "BUFFER: %08" B_PRIx32 "\n", status);
315 return B_ERROR;
316 } else PROGRESS("VideoConsumer::CreateBuffers - SUCCESSFUL ADD BUFFER TO GROUP\n");
316 }
317 }
318 else
319 {
320 ERROR("VideoConsumer::CreateBuffers - ERROR CREATING VIDEO RING BUFFER: %08x\n", status);
321 return B_ERROR;
322 }
317 }
323 }
318
319 BBuffer* buffList[3];
320 for (int j = 0; j < 3; j++)
321 buffList[j] = NULL;
322
323 if ((status = fBuffers->GetBufferList(3, buffList)) == B_OK)
324
325 BBuffer ** buffList = new BBuffer * [3];
326 for (int j = 0; j < 3; j++) buffList[j] = 0;
327
328 if ((status = mBuffers->GetBufferList(3, buffList)) == B_OK)
324 for (int j = 0; j < 3; j++)
329 for (int j = 0; j < 3; j++)
325 if (buffList[j] != NULL) {
326 fBufferMap[j] = buffList[j];
327 PROGRESS(" j = %d buffer = %p\n", j, fBufferMap[j]);
328 } else {
330 if (buffList[j] != NULL)
331 {
332 mBufferMap[j] = (uint32) buffList[j];
333 PROGRESS(" j = %d buffer = %08x\n", j, mBufferMap[j]);
334 }
335 else
336 {
329 ERROR("VideoConsumer::CreateBuffers ERROR MAPPING RING BUFFER\n");
330 return B_ERROR;
331 }
332 else
333 ERROR("VideoConsumer::CreateBuffers ERROR IN GET BUFFER LIST\n");
337 ERROR("VideoConsumer::CreateBuffers ERROR MAPPING RING BUFFER\n");
338 return B_ERROR;
339 }
340 else
341 ERROR("VideoConsumer::CreateBuffers ERROR IN GET BUFFER LIST\n");
334
335 fFtpBitmap = new BBitmap(BRect(0, 0, xSize - 1, ySize - 1), B_RGB32, false, false);
336
342
337 FUNCTION("VideoConsumer::CreateBuffers - EXIT\n");
338 return status;
339}
340
343 FUNCTION("VideoConsumer::CreateBuffers - EXIT\n");
344 return status;
345}
346
347//---------------------------------------------------------------
341
342void
343VideoConsumer::DeleteBuffers()
344{
345 FUNCTION("VideoConsumer::DeleteBuffers\n");
348
349void
350VideoConsumer::DeleteBuffers()
351{
352 FUNCTION("VideoConsumer::DeleteBuffers\n");
346
347 if (fBuffers) {
348 delete fBuffers;
349 fBuffers = NULL;
350
353 status_t status;
354
355 if (mBuffers)
356 {
357 delete mBuffers;
358 mBuffers = NULL;
359
351 for (uint32 j = 0; j < 3; j++)
360 for (uint32 j = 0; j < 3; j++)
352 if (fBitmap[j]->IsValid()) {
353 delete fBitmap[j];
354 fBitmap[j] = NULL;
361 if (mBitmap[j]->IsValid())
362 {
363 delete mBitmap[j];
364 mBitmap[j] = NULL;
355 }
356 }
357 FUNCTION("VideoConsumer::DeleteBuffers - EXIT\n");
358}
359
365 }
366 }
367 FUNCTION("VideoConsumer::DeleteBuffers - EXIT\n");
368}
369
370//---------------------------------------------------------------
360
361status_t
371
372status_t
362VideoConsumer::Connected(const media_source& producer, const media_destination& where,
363 const media_format& withFormat, media_input* outInput)
373VideoConsumer::Connected(
374 const media_source & producer,
375 const media_destination & where,
376 const media_format & with_format,
377 media_input * out_input)
364{
365 FUNCTION("VideoConsumer::Connected\n");
378{
379 FUNCTION("VideoConsumer::Connected\n");
380
381 mIn.source = producer;
382 mIn.format = with_format;
383 mIn.node = Node();
384 sprintf(mIn.name, "Video Consumer");
385 *out_input = mIn;
366
386
367 fIn.source = producer;
368 fIn.format = withFormat;
369 fIn.node = Node();
370 sprintf(fIn.name, "Video Consumer");
371 *outInput = fIn;
372
373 uint32 userData = 0;
374 int32 changeTag = 1;
375 if (CreateBuffers(withFormat) == B_OK)
376 BBufferConsumer::SetOutputBuffersFor(producer, fDestination,
377 fBuffers, (void *)&userData, &changeTag, true);
378 else {
387 uint32 user_data = 0;
388 int32 change_tag = 1;
389 if (CreateBuffers(with_format) == B_OK)
390 BBufferConsumer::SetOutputBuffersFor(producer, mDestination,
391 mBuffers, (void *)&user_data, &change_tag, true);
392 else
393 {
379 ERROR("VideoConsumer::Connected - COULDN'T CREATE BUFFERS\n");
380 return B_ERROR;
381 }
382
394 ERROR("VideoConsumer::Connected - COULDN'T CREATE BUFFERS\n");
395 return B_ERROR;
396 }
397
383 fConnectionActive = true;
384
398 mFtpBitmap = new BBitmap(BRect(0, 0, 320-1, 240-1), B_RGB32, false, false);
399 mConnectionActive = true;
400
385 FUNCTION("VideoConsumer::Connected - EXIT\n");
386 return B_OK;
387}
388
401 FUNCTION("VideoConsumer::Connected - EXIT\n");
402 return B_OK;
403}
404
405//---------------------------------------------------------------
389
390void
406
407void
391VideoConsumer::Disconnected(const media_source& producer, const media_destination& where)
408VideoConsumer::Disconnected(
409 const media_source & producer,
410 const media_destination & where)
392{
393 FUNCTION("VideoConsumer::Disconnected\n");
394
411{
412 FUNCTION("VideoConsumer::Disconnected\n");
413
395 if (where == fIn.destination && producer == fIn.source) {
414 if (where == mIn.destination && producer == mIn.source)
415 {
396 // disconnect the connection
416 // disconnect the connection
397 fIn.source = media_source::null;
398 delete fFtpBitmap;
399 fConnectionActive = false;
417 mIn.source = media_source::null;
418 delete mFtpBitmap;
419 mConnectionActive = false;
400 }
401
402}
403
420 }
421
422}
423
424//---------------------------------------------------------------
404
405status_t
425
426status_t
406VideoConsumer::AcceptFormat(const media_destination& dest, media_format* format)
427VideoConsumer::AcceptFormat(
428 const media_destination & dest,
429 media_format * format)
407{
408 FUNCTION("VideoConsumer::AcceptFormat\n");
430{
431 FUNCTION("VideoConsumer::AcceptFormat\n");
409
410 if (dest != fIn.destination) {
432
433 if (dest != mIn.destination)
434 {
411 ERROR("VideoConsumer::AcceptFormat - BAD DESTINATION\n");
435 ERROR("VideoConsumer::AcceptFormat - BAD DESTINATION\n");
412 return B_MEDIA_BAD_DESTINATION;
436 return B_MEDIA_BAD_DESTINATION;
413 }
437 }
414
438
415 if (format->type == B_MEDIA_NO_TYPE)
416 format->type = B_MEDIA_RAW_VIDEO;
439 if (format->type == B_MEDIA_NO_TYPE)
440 format->type = B_MEDIA_RAW_VIDEO;
417
418 if (format->type != B_MEDIA_RAW_VIDEO) {
441
442 if (format->type != B_MEDIA_RAW_VIDEO)
443 {
419 ERROR("VideoConsumer::AcceptFormat - BAD FORMAT\n");
420 return B_MEDIA_BAD_FORMAT;
421 }
422
444 ERROR("VideoConsumer::AcceptFormat - BAD FORMAT\n");
445 return B_MEDIA_BAD_FORMAT;
446 }
447
423 if (format->u.raw_video.display.format != B_RGB32
424 && format->u.raw_video.display.format != B_RGB16
425 && format->u.raw_video.display.format != B_RGB15
426 && format->u.raw_video.display.format != B_GRAY8
427 &&
428 format->u.raw_video.display.format != media_raw_video_format::wildcard.display.format) {
448 if (format->u.raw_video.display.format != B_RGB32 &&
449 format->u.raw_video.display.format != B_RGB16 &&
450 format->u.raw_video.display.format != B_RGB15 &&
451 format->u.raw_video.display.format != B_GRAY8 &&
452 format->u.raw_video.display.format != media_raw_video_format::wildcard.display.format)
453 {
429 ERROR("AcceptFormat - not a format we know about!\n");
430 return B_MEDIA_BAD_FORMAT;
431 }
454 ERROR("AcceptFormat - not a format we know about!\n");
455 return B_MEDIA_BAD_FORMAT;
456 }
432
433 if (format->u.raw_video.display.format == media_raw_video_format::wildcard.display.format) {
457
458 if (format->u.raw_video.display.format == media_raw_video_format::wildcard.display.format)
459 {
434 format->u.raw_video.display.format = B_RGB16;
435 }
436
460 format->u.raw_video.display.format = B_RGB16;
461 }
462
437 char formatString[256];
438 string_for_format(*format, formatString, 256);
439 FUNCTION("VideoConsumer::AcceptFormat: %s\n", formatString);
463 char format_string[256];
464 string_for_format(*format, format_string, 256);
465 FUNCTION("VideoConsumer::AcceptFormat: %s\n", format_string);
440
441 return B_OK;
442}
443
466
467 return B_OK;
468}
469
470//---------------------------------------------------------------
444
445status_t
471
472status_t
446VideoConsumer::GetNextInput(int32* cookie, media_input* outInput)
473VideoConsumer::GetNextInput(
474 int32 * cookie,
475 media_input * out_input)
447{
448 FUNCTION("VideoConsumer::GetNextInput\n");
449
450 // custom build a destination for this connection
451 // put connection number in id
452
476{
477 FUNCTION("VideoConsumer::GetNextInput\n");
478
479 // custom build a destination for this connection
480 // put connection number in id
481
453 if (*cookie < 1) {
454 fIn.node = Node();
455 fIn.destination.id = *cookie;
456 sprintf(fIn.name, "Video Consumer");
457 *outInput = fIn;
482 if (*cookie < 1)
483 {
484 mIn.node = Node();
485 mIn.destination.id = *cookie;
486 sprintf(mIn.name, "Video Consumer");
487 *out_input = mIn;
458 (*cookie)++;
459 return B_OK;
488 (*cookie)++;
489 return B_OK;
460 } else {
490 }
491 else
492 {
461 ERROR("VideoConsumer::GetNextInput - - BAD INDEX\n");
462 return B_MEDIA_BAD_DESTINATION;
463 }
464}
465
493 ERROR("VideoConsumer::GetNextInput - - BAD INDEX\n");
494 return B_MEDIA_BAD_DESTINATION;
495 }
496}
497
498//---------------------------------------------------------------
466
467void
468VideoConsumer::DisposeInputCookie(int32 /*cookie*/)
469{
470}
471
499
500void
501VideoConsumer::DisposeInputCookie(int32 /*cookie*/)
502{
503}
504
505//---------------------------------------------------------------
472
473status_t
506
507status_t
474VideoConsumer::GetLatencyFor(const media_destination& forWhom, bigtime_t* outLatency,
475 media_node_id* out_timesource)
508VideoConsumer::GetLatencyFor(
509 const media_destination &for_whom,
510 bigtime_t * out_latency,
511 media_node_id * out_timesource)
476{
477 FUNCTION("VideoConsumer::GetLatencyFor\n");
512{
513 FUNCTION("VideoConsumer::GetLatencyFor\n");
478
479 if (forWhom != fIn.destination)
514
515 if (for_whom != mIn.destination)
480 return B_MEDIA_BAD_DESTINATION;
516 return B_MEDIA_BAD_DESTINATION;
481
482 *outLatency = fMyLatency;
517
518 *out_latency = mMyLatency;
483 *out_timesource = TimeSource()->ID();
484 return B_OK;
485}
486
487
519 *out_timesource = TimeSource()->ID();
520 return B_OK;
521}
522
523
524//---------------------------------------------------------------
525
488status_t
526status_t
489VideoConsumer::FormatChanged(const media_source& producer, const media_destination& consumer,
490 int32 fromChangeCount, const media_format& format)
527VideoConsumer::FormatChanged(
528 const media_source & producer,
529 const media_destination & consumer,
530 int32 from_change_count,
531 const media_format &format)
491{
492 FUNCTION("VideoConsumer::FormatChanged\n");
532{
533 FUNCTION("VideoConsumer::FormatChanged\n");
493
494 if (consumer != fIn.destination)
534
535 if (consumer != mIn.destination)
495 return B_MEDIA_BAD_DESTINATION;
496
536 return B_MEDIA_BAD_DESTINATION;
537
497 if (producer != fIn.source)
538 if (producer != mIn.source)
498 return B_MEDIA_BAD_SOURCE;
499
539 return B_MEDIA_BAD_SOURCE;
540
500 fIn.format = format;
501
541 mIn.format = format;
542
502 return CreateBuffers(format);
503}
504
543 return CreateBuffers(format);
544}
545
546//---------------------------------------------------------------
505
506void
547
548void
507VideoConsumer::HandleEvent(const media_timed_event* event, bigtime_t lateness,
549VideoConsumer::HandleEvent(
550 const media_timed_event *event,
551 bigtime_t lateness,
508 bool realTimeEvent)
552 bool realTimeEvent)
553
509{
510 LOOP("VideoConsumer::HandleEvent\n");
554{
555 LOOP("VideoConsumer::HandleEvent\n");
511
512 BBuffer* buffer;
513
514 switch (event->type) {
556
557 BBuffer *buffer;
558
559 switch (event->type)
560 {
515 case BTimedEventQueue::B_START:
516 PROGRESS("VideoConsumer::HandleEvent - START\n");
517 break;
561 case BTimedEventQueue::B_START:
562 PROGRESS("VideoConsumer::HandleEvent - START\n");
563 break;
518
519 case BTimedEventQueue::B_STOP:
520 PROGRESS("VideoConsumer::HandleEvent - STOP\n");
564 case BTimedEventQueue::B_STOP:
565 PROGRESS("VideoConsumer::HandleEvent - STOP\n");
521 EventQueue()->FlushEvents(event->event_time, BTimedEventQueue::B_ALWAYS,
522 true, BTimedEventQueue::B_HANDLE_BUFFER);
566 EventQueue()->FlushEvents(event->event_time, BTimedEventQueue::B_ALWAYS, true, BTimedEventQueue::B_HANDLE_BUFFER);
523 break;
567 break;
524
525 case BTimedEventQueue::B_USER_EVENT:
526 PROGRESS("VideoConsumer::HandleEvent - USER EVENT\n");
568 case BTimedEventQueue::B_USER_EVENT:
569 PROGRESS("VideoConsumer::HandleEvent - USER EVENT\n");
527 if (RunState() == B_STARTED) {
528 fTimeToFtp = true;
529 PROGRESS("Pushing user event for %.4f, time now %.4f\n",
530 (event->event_time + fRate) / M1, event->event_time/M1);
531 media_timed_event newEvent(event->event_time + fRate,
532 BTimedEventQueue::B_USER_EVENT);
570 if (RunState() == B_STARTED)
571 {
572 mTimeToFtp = true;
573 PROGRESS("Pushing user event for %.4f, time now %.4f\n", (event->event_time + mRate)/M1, event->event_time/M1);
574 media_timed_event newEvent(event->event_time + mRate, BTimedEventQueue::B_USER_EVENT);
533 EventQueue()->AddEvent(newEvent);
534 }
575 EventQueue()->AddEvent(newEvent);
576 }
535 break;
536
577 break;
537 case BTimedEventQueue::B_HANDLE_BUFFER:
578 case BTimedEventQueue::B_HANDLE_BUFFER:
538 {
539 LOOP("VideoConsumer::HandleEvent - HANDLE BUFFER\n");
579 LOOP("VideoConsumer::HandleEvent - HANDLE BUFFER\n");
540 buffer = (BBuffer *)event->pointer;
541 if (RunState() == B_STARTED && fConnectionActive) {
580 buffer = (BBuffer *) event->pointer;
581 if (RunState() == B_STARTED && mConnectionActive)
582 {
542 // see if this is one of our buffers
543 uint32 index = 0;
583 // see if this is one of our buffers
584 uint32 index = 0;
544 fOurBuffers = true;
545 while (index < 3)
546 if (buffer == fBufferMap[index])
585 mOurBuffers = true;
586 while(index < 3)
587 if ((uint32)buffer == mBufferMap[index])
547 break;
548 else
549 index++;
588 break;
589 else
590 index++;
550
551 if (index == 3) {
591
592 if (index == 3)
593 {
552 // no, buffers belong to consumer
594 // no, buffers belong to consumer
553 fOurBuffers = false;
595 mOurBuffers = false;
554 index = 0;
555 }
596 index = 0;
597 }
556
557 if (fFtpComplete && fTimeToFtp) {
598
599 if (mFtpComplete && mTimeToFtp)
600 {
558 PROGRESS("VidConsumer::HandleEvent - SPAWNING FTP THREAD\n");
601 PROGRESS("VidConsumer::HandleEvent - SPAWNING FTP THREAD\n");
559 fTimeToFtp = false;
560 fFtpComplete = false;
561 memcpy(fFtpBitmap->Bits(), buffer->Data(), fFtpBitmap->BitsLength());
562 fFtpThread = spawn_thread(FtpRun, "Video Window Ftp", B_NORMAL_PRIORITY, this);
563 resume_thread(fFtpThread);
602 mTimeToFtp = false;
603 mFtpComplete = false;
604 memcpy(mFtpBitmap->Bits(), buffer->Data(),mFtpBitmap->BitsLength());
605 mFtpThread = spawn_thread(FtpRun, "Video Window Ftp", B_NORMAL_PRIORITY, this);
606 resume_thread(mFtpThread);
564 }
565
607 }
608
566 if ((RunMode() == B_OFFLINE)
567 || ((TimeSource()->Now() > (buffer->Header()->start_time - JITTER))
568 && (TimeSource()->Now() < (buffer->Header()->start_time + JITTER)))) {
569 if (!fOurBuffers)
609 if ( (RunMode() == B_OFFLINE) ||
610 ((TimeSource()->Now() > (buffer->Header()->start_time - JITTER)) &&
611 (TimeSource()->Now() < (buffer->Header()->start_time + JITTER))) )
612 {
613 if (!mOurBuffers)
570 // not our buffers, so we need to copy
614 // not our buffers, so we need to copy
571 memcpy(fBitmap[index]->Bits(), buffer->Data(), fBitmap[index]->BitsLength());
572
573 if (fWindow->Lock()) {
615 memcpy(mBitmap[index]->Bits(), buffer->Data(),mBitmap[index]->BitsLength());
616
617 if (mWindow->Lock())
618 {
574 uint32 flags;
619 uint32 flags;
575 if ((fBitmap[index]->ColorSpace() == B_GRAY8) &&
576 !bitmaps_support_space(fBitmap[index]->ColorSpace(), &flags)) {
620 if ((mBitmap[index]->ColorSpace() == B_GRAY8) &&
621 !bitmaps_support_space(mBitmap[index]->ColorSpace(), &flags))
622 {
577 // handle mapping of GRAY8 until app server knows how
623 // handle mapping of GRAY8 until app server knows how
578 uint32* start = (uint32*)fBitmap[index]->Bits();
579 int32 size = fBitmap[index]->BitsLength();
580 uint32* end = start + size / 4;
581 for (uint32* p = start; p < end; p++)
582 *p = (*p >> 3) & 0x1f1f1f1f;
624 uint32 *start = (uint32 *)mBitmap[index]->Bits();
625 int32 size = mBitmap[index]->BitsLength();
626 uint32 *end = start + size/4;
627 for (uint32 *p = start; p < end; p++)
628 *p = (*p >> 3) & 0x1f1f1f1f;
583 }
629 }
584
585 fView->DrawBitmap(fBitmap[index], fView->Bounds());
586 fWindow->Unlock();
630
631 mView->DrawBitmap(mBitmap[index]);
632 mWindow->Unlock();
587 }
588 }
589 else
590 PROGRESS("VidConsumer::HandleEvent - DROPPED FRAME\n");
591 buffer->Recycle();
592 }
593 else
594 buffer->Recycle();
595 break;
633 }
634 }
635 else
636 PROGRESS("VidConsumer::HandleEvent - DROPPED FRAME\n");
637 buffer->Recycle();
638 }
639 else
640 buffer->Recycle();
641 break;
596 }
597
598 default:
599 ERROR("VideoConsumer::HandleEvent - BAD EVENT\n");
600 break;
642 default:
643 ERROR("VideoConsumer::HandleEvent - BAD EVENT\n");
644 break;
601 }
645 }
602}
603
646}
647
648//---------------------------------------------------------------
604
605status_t
649
650status_t
606VideoConsumer::FtpRun(void* data)
651VideoConsumer::FtpRun(void * data)
607{
608 FUNCTION("VideoConsumer::FtpRun\n");
652{
653 FUNCTION("VideoConsumer::FtpRun\n");
609
654
610 ((VideoConsumer *)data)->FtpThread();
611
612 return 0;
613}
614
655 ((VideoConsumer *)data)->FtpThread();
656
657 return 0;
658}
659
660//---------------------------------------------------------------
615
661
662
616void
617VideoConsumer::FtpThread()
618{
663void
664VideoConsumer::FtpThread()
665{
619 char fullPath[B_PATH_NAME_LENGTH];
620 FUNCTION("VideoConsumer::FtpThread\n");
666 FUNCTION("VideoConsumer::FtpThread\n");
621 if (fUploadClient == 2) {
622 // 64 + 64 = 128 max
623 snprintf(fullPath, B_PATH_NAME_LENGTH, "%s/%s", fDirectoryText, fFileNameText);
624 LocalSave(fullPath, fFtpBitmap);
625 } else if (LocalSave(fFileNameText, fFtpBitmap) == B_OK)
626 FtpSave(fFileNameText);
627
667
668 if (LocalSave(mFileNameText, mFtpBitmap) == B_OK)
669 FtpSave(mFileNameText);
670
628#if 0
629 // save a small version, too
671#if 0
672 // save a small version, too
630 BBitmap* b = new BBitmap(BRect(0,0,159,119), B_RGB32, true, false);
631 BView* v = new BView(BRect(0,0,159,119), "SmallView 1", 0, B_WILL_DRAW);
673 BBitmap * b = new BBitmap(BRect(0,0,159,119), B_RGB32, true, false);
674 BView * v = new BView(BRect(0,0,159,119), "SmallView 1", 0, B_WILL_DRAW);
632 b->AddChild(v);
633
634 b->Lock();
675 b->AddChild(v);
676
677 b->Lock();
635 v->DrawBitmap(fFtpBitmap, v->Frame());
678 v->DrawBitmap(mFtpBitmap, v->Frame());
636 v->Sync();
679 v->Sync();
637 b->Unlock();
680 b->Unlock();
638
681
639 if (LocalSave("small.jpg", b) == B_OK)
682 if (LocalSave("small.jpg", b) == B_OK)
640 FtpSave("small.jpg");
683 FtpSave("small.jpg");
641
684
642 delete b;
643#endif
685 delete b;
686#endif
644
645 fFtpComplete = true;
687
688 mFtpComplete = true;
646}
647
689}
690
691//---------------------------------------------------------------
648
649void
692
693void
650VideoConsumer::UpdateFtpStatus(const char* status)
694VideoConsumer::UpdateFtpStatus(char *status)
651{
652 printf("FTP STATUS: %s\n",status);
695{
696 printf("FTP STATUS: %s\n",status);
653 if (fView->Window()->Lock()) {
654 fStatusLine->SetText(status);
655 fView->Window()->Unlock();
697 if (mView->Window()->Lock())
698 {
699 mStatusLine->SetText(status);
700 mView->Window()->Unlock();
656 }
657}
658
701 }
702}
703
704//---------------------------------------------------------------
659
660status_t
705
706status_t
661VideoConsumer::LocalSave(char* filename, BBitmap* bitmap)
707VideoConsumer::LocalSave(char *filename, BBitmap *bitmap)
662{
708{
663 BFile* output;
709 BFile *output;
710
711 UpdateFtpStatus("Capturing Image ...");
664
712
665 UpdateFtpStatus(B_TRANSLATE("Capturing Image" B_UTF8_ELLIPSIS));
666
667 /* save a local copy of the image in the requested format */
713 /* save a local copy of the image in the requested format */
668 output = new BFile();
669 if (output->SetTo(filename, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE) == B_NO_ERROR) {
714 output =new BFile();
715 if (output->SetTo(filename, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE) == B_NO_ERROR)
716 {
670 BBitmapStream input(bitmap);
717 BBitmapStream input(bitmap);
671 status_t err = BTranslatorRoster::Default()->Translate(&input, NULL, NULL,
672 output, fImageFormat);
673 if (err == B_OK) {
674 err = SetFileType(output, fTranslator, fImageFormat);
718 status_t err = BTranslatorRoster::Default()->Translate(&input, NULL, NULL, output, mImageFormat);
719 if (err == B_OK)
720 {
721 err = SetFileType(output, mTranslator, mImageFormat);
675 if (err != B_OK)
722 if (err != B_OK)
676 UpdateFtpStatus(B_TRANSLATE("Error setting type of output file"));
723 UpdateFtpStatus("Error setting type of output file");
677 }
678 else
724 }
725 else
679 UpdateFtpStatus(B_TRANSLATE("Error writing output file"));
680
681 input.DetachBitmap(&bitmap);
682 output->Unset();
683 delete output;
684 return B_OK;
685 } else {
686 UpdateFtpStatus(B_TRANSLATE("Error creating output file"));
687 return B_ERROR;
726 {
727 UpdateFtpStatus("Error writing output file");
728 }
729 input.DetachBitmap(&bitmap);
730 output->Unset();
731 delete output;
732 return B_OK;
688 }
733 }
734 else
735 {
736 UpdateFtpStatus("Error creating output file");
737 return B_ERROR;
738 }
689}
690
739}
740
741//---------------------------------------------------------------
691
692status_t
742
743status_t
693VideoConsumer::FtpSave(char* filename)
744VideoConsumer::FtpSave(char *filename)
694{
745{
695 FileUploadClient *ftp;
746 FtpClient ftp;
696
747
697 //XXX: make that cleaner
698 switch (fUploadClient) {
699 case 0:
700 ftp = new FtpClient;
701 break;
702 case 1:
703 ftp = new SftpClient;
704 break;
705 case 2:
706 return B_OK;
707 default:
708 fprintf(stderr, B_TRANSLATE("invalid upload client %ld\n"),
709 fUploadClient);
710 return EINVAL;
711 }
712
713 ftp->SetPassive(fPassiveFtp);
714 // ftp the local file to our web site
715
716 UpdateFtpStatus(B_TRANSLATE("Logging in" B_UTF8_ELLIPSIS));
717 if (ftp->Connect((string)fServerText, (string)fLoginText,
718 (string)fPasswordText)) {
719 // connect to server
720 UpdateFtpStatus(B_TRANSLATE("Connected" B_UTF8_ELLIPSIS));
721
722 if (ftp->ChangeDir((string)fDirectoryText)) {
723 // cd to the desired directory
724 UpdateFtpStatus(B_TRANSLATE("Upload" B_UTF8_ELLIPSIS));
725
726 if (ftp->PutFile((string)filename, (string)"temp")) {
727 // send the file to the server
728
729 ftp->Chmod((string)"temp", (string)"644");
730 // make it world readable
731
732 UpdateFtpStatus(B_TRANSLATE("Renaming" B_UTF8_ELLIPSIS));
733
734 if (ftp->MoveFile((string)"temp", (string)filename)) {
735 // change to the desired name
748 /* ftp the local file to our web site */
749 ftp.setPassive(mPassiveFtp);
750
751 UpdateFtpStatus("Logging in ...");
752 if (ftp.connect((string)mServerText, (string)mLoginText, (string)mPasswordText)) // connect to server
753 {
754 UpdateFtpStatus("Connected ...");
755 if (ftp.cd((string)mDirectoryText))
756 { // cd to the desired directory
757 UpdateFtpStatus("Transmitting ...");
758 if (ftp.putFile((string)filename, (string)"temp")) // send the file to the server
759 {
760 UpdateFtpStatus("Renaming ...");
761 if (ftp.moveFile((string)"temp",(string)filename)) // change to the desired name
762 {
736 uint32 time = real_time_clock();
737 char s[80];
763 uint32 time = real_time_clock();
764 char s[80];
738 strcpy(s, B_TRANSLATE("Last Capture: "));
739 strcat(s, ctime((const time_t*)&time));
740 s[strlen(s) - 1] = 0;
765 strcpy(s,"Last Capture: ");
766 strcat(s,ctime((const long *)&time));
767 s[strlen(s)-1] = 0;
741 UpdateFtpStatus(s);
768 UpdateFtpStatus(s);
742 delete ftp;
743 return B_OK;
769 return B_OK;
744 } else
745 UpdateFtpStatus(B_TRANSLATE("Rename failed"));
746 } else
747 UpdateFtpStatus(B_TRANSLATE("File upload failed"));
748 } else
749 UpdateFtpStatus(B_TRANSLATE("Couldn't find requested directory on "
750 "server"));
751 }
752 else
753 UpdateFtpStatus(B_TRANSLATE("Server login failed"));
754
755 delete ftp;
770 } else UpdateFtpStatus("Rename failed");
771 } else UpdateFtpStatus("File transmission failed");
772 } else UpdateFtpStatus("Couldn't find requested directory on server");
773 } else UpdateFtpStatus("Server login failed");
756 return B_ERROR;
757}
758
774 return B_ERROR;
775}
776
777//---------------------------------------------------------------
759
760status_t
778
779status_t
761SetFileType(BFile* file, int32 translator, uint32 type)
762{
763 translation_format* formats;
764 int32 count;
780SetFileType(BFile * file, int32 translator, uint32 type)
781{
782 translation_format * formats;
783 int32 count;
784
785 status_t err = BTranslatorRoster::Default()->GetOutputFormats(translator, (const translation_format **) &formats, &count);
786 if (err < B_OK) return err;
787 const char * mime = NULL;
788 for (int ix=0; ix<count; ix++)
789 {
790 if (formats[ix].type == type)
791 {
792 mime = formats[ix].MIME;
793 break;
794 }
795 }
796 if (mime == NULL)
797 { /* this should not happen, but being defensive might be prudent */
798 return B_ERROR;
799 }
765
800
766 status_t err = BTranslatorRoster::Default()->GetOutputFormats(translator,
767 (const translation_format **)&formats, &count);
768 if (err < B_OK)
769 return err;
801 /* use BNodeInfo to set the file type */
802 BNodeInfo ninfo(file);
803 return ninfo.SetType(mime);
804}
770
805
771 const char* mime = NULL;
772 for (int ix = 0; ix < count; ix++) {
773 if (formats[ix].type == type) {
774 mime = formats[ix].MIME;
775 break;
776 }
777 }
806//---------------------------------------------------------------
778
807
779 if (mime == NULL) {
780 /* this should not happen, but being defensive might be prudent */
781 return B_ERROR;
782 }
783
808
784 /* use BNodeInfo to set the file type */
785 BNodeInfo ninfo(file);
786 return ninfo.SetType(mime);
787}