1 /*
2 * Copyright 2015, Dario Casalinuovo
3 * Copyright 2004, 2006, Jérôme Duval.
4 * Copyright 2003-2004, Andrew Bachmann.
5 * Copyright 2002-2004, 2006 Marcus Overhagen.
6 * Copyright 2002, Eric Jaessler.
7 * All rights reserved. Distributed under the terms of the MIT license.
8 */
9
10
11 #include <MediaDefs.h>
12
13 #include <Application.h>
14 #include <Bitmap.h>
15 #include <Catalog.h>
16 #include <IconUtils.h>
17 #include <LaunchRoster.h>
18 #include <Locale.h>
19 #include <MediaNode.h>
20 #include <MediaRoster.h>
21 #include <Node.h>
22 #include <Notification.h>
23 #include <Roster.h>
24
25 #include <inttypes.h>
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "AddOnManager.h"
30 #include "DataExchange.h"
31 #include "MediaDebug.h"
32 #include "MediaMisc.h"
33 #include "MediaRosterEx.h"
34
35
36 #define META_DATA_MAX_SIZE (16 << 20)
37 #define META_DATA_AREA_MIN_SIZE 32000
38
39 #undef B_TRANSLATION_CONTEXT
40 #define B_TRANSLATION_CONTEXT "MediaDefs"
41
42
43 // #pragma mark - media_destination
44
45
media_destination(port_id port,int32 id)46 media_destination::media_destination(port_id port, int32 id)
47 :
48 port(port),
49 id(id)
50 {
51 }
52
53
media_destination(const media_destination & clone)54 media_destination::media_destination(const media_destination& clone)
55 :
56 port(clone.port),
57 id(clone.id)
58 {
59 }
60
61
62 media_destination&
operator =(const media_destination & clone)63 media_destination::operator=(const media_destination& clone)
64 {
65 port = clone.port;
66 id = clone.id;
67 return *this;
68 }
69
70
media_destination()71 media_destination::media_destination()
72 :
73 port(-1),
74 id(-1)
75 {
76 }
77
78
~media_destination()79 media_destination::~media_destination()
80 {
81 }
82
83
84 media_destination media_destination::null(-1, -1);
85
86
87 // #pragma mark - media_source
88
89
media_source(port_id port,int32 id)90 media_source::media_source(port_id port,
91 int32 id)
92 :
93 port(port),
94 id(id)
95 {
96 }
97
98
media_source(const media_source & clone)99 media_source::media_source(const media_source& clone)
100 :
101 port(clone.port),
102 id(clone.id)
103 {
104 }
105
106
107 media_source&
operator =(const media_source & clone)108 media_source::operator=(const media_source& clone)
109 {
110 port = clone.port;
111 id = clone.id;
112 return *this;
113 }
114
115
media_source()116 media_source::media_source()
117 :
118 port(-1),
119 id(-1)
120 {
121 }
122
123
~media_source()124 media_source::~media_source()
125 {
126 }
127
128
129 media_source media_source::null(-1, -1);
130
131
132 // #pragma mark -
133
134
135 bool
operator ==(const media_destination & a,const media_destination & b)136 operator==(const media_destination& a, const media_destination& b)
137 {
138 return a.port == b.port && a.id == b.id;
139 }
140
141
142 bool
operator !=(const media_destination & a,const media_destination & b)143 operator!=(const media_destination& a, const media_destination& b)
144 {
145 return a.port != b.port || a.id != b.id;
146 }
147
148
149 bool
operator <(const media_destination & a,const media_destination & b)150 operator<(const media_destination& a, const media_destination& b)
151 {
152 UNIMPLEMENTED();
153 return false;
154 }
155
156
157 bool
operator ==(const media_source & a,const media_source & b)158 operator==(const media_source& a, const media_source& b)
159 {
160 return a.port == b.port && a.id == b.id;
161 }
162
163
164 bool
operator !=(const media_source & a,const media_source & b)165 operator!=(const media_source& a, const media_source& b)
166 {
167 return a.port != b.port || a.id != b.id;
168 }
169
170
171 bool
operator <(const media_source & a,const media_source & b)172 operator<(const media_source& a, const media_source& b)
173 {
174 UNIMPLEMENTED();
175 return false;
176 }
177
178
179 bool
operator ==(const media_node & a,const media_node & b)180 operator==(const media_node& a, const media_node& b)
181 {
182 return a.node == b.node && a.port == b.port && a.kind == b.kind;
183 }
184
185
186 bool
operator !=(const media_node & a,const media_node & b)187 operator!=(const media_node& a, const media_node& b)
188 {
189 return a.node != b.node || a.port != b.port || a.kind != b.kind;
190 }
191
192
193 bool
operator <(const media_node & a,const media_node & b)194 operator<(const media_node& a, const media_node& b)
195 {
196 UNIMPLEMENTED();
197 return false;
198 }
199
200
201 // #pragma mark -
202
203
204 #if __GNUC__ == 2
205 const media_multi_audio_format media_raw_audio_format::wildcard
206 = media_multi_audio_format();
207
208 const media_multi_audio_format media_multi_audio_format::wildcard
209 = media_multi_audio_format();
210 #else
211 const media_multi_audio_format media_raw_audio_format::wildcard = {};
212
213 const media_multi_audio_format media_multi_audio_format::wildcard = {};
214 #endif
215
216 const media_encoded_audio_format media_encoded_audio_format::wildcard = {};
217
218 const media_video_display_info media_video_display_info::wildcard = {};
219
220 const media_raw_video_format media_raw_video_format::wildcard = {};
221
222 const media_encoded_video_format media_encoded_video_format::wildcard = {};
223
224 const media_multistream_format media_multistream_format::wildcard = {};
225
226
227 // #pragma mark - media_format::Matches() support
228
229
230 static bool
raw_audio_format_matches(const media_raw_audio_format & a,const media_raw_audio_format & b)231 raw_audio_format_matches(const media_raw_audio_format& a,
232 const media_raw_audio_format& b)
233 {
234 if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
235 return false;
236 if (a.channel_count != 0 && b.channel_count != 0
237 && a.channel_count != b.channel_count) {
238 return false;
239 }
240 if (a.format != 0 && b.format != 0 && a.format != b.format)
241 return false;
242 if (a.byte_order != 0 && b.byte_order != 0 && a.byte_order != b.byte_order)
243 return false;
244 if (a.buffer_size != 0 && b.buffer_size != 0
245 && a.buffer_size != b.buffer_size) {
246 return false;
247 }
248 if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
249 return false;
250 return true;
251 }
252
253
254 static bool
multi_audio_info_matches(const media_multi_audio_info & a,const media_multi_audio_info & b)255 multi_audio_info_matches(const media_multi_audio_info& a,
256 const media_multi_audio_info& b)
257 {
258 if (a.channel_mask != 0 && b.channel_mask != 0
259 && a.channel_mask != b.channel_mask) {
260 return false;
261 }
262 if (a.valid_bits != 0 && b.valid_bits != 0 && a.valid_bits != b.valid_bits)
263 return false;
264 if (a.matrix_mask != 0 && b.matrix_mask != 0
265 && a.matrix_mask != b.matrix_mask) {
266 return false;
267 }
268 return true;
269 }
270
271
272 static bool
multi_audio_format_matches(const media_multi_audio_format & a,const media_multi_audio_format & b)273 multi_audio_format_matches(const media_multi_audio_format& a,
274 const media_multi_audio_format& b)
275 {
276 return raw_audio_format_matches(a, b) && multi_audio_info_matches(a, b);
277 }
278
279
280 static bool
raw_video_format_matches(const media_raw_video_format & a,const media_raw_video_format & b)281 raw_video_format_matches(const media_raw_video_format& a,
282 const media_raw_video_format& b)
283 {
284 if (a.field_rate != 0 && b.field_rate != 0
285 && a.field_rate != b.field_rate) {
286 return false;
287 }
288 if (a.interlace != 0 && b.interlace != 0
289 && a.interlace != b.interlace) {
290 return false;
291 }
292 if (a.first_active != 0 && b.first_active != 0
293 && a.first_active != b.first_active) {
294 return false;
295 }
296 if (a.last_active != 0 && b.last_active != 0
297 && a.last_active != b.last_active) {
298 return false;
299 }
300 if (a.orientation != 0 && b.orientation != 0
301 && a.orientation != b.orientation) {
302 return false;
303 }
304 if (a.pixel_width_aspect != 0 && b.pixel_width_aspect != 0
305 && a.pixel_width_aspect != b.pixel_width_aspect) {
306 return false;
307 }
308 if (a.pixel_height_aspect != 0 && b.pixel_height_aspect != 0
309 && a.pixel_height_aspect != b.pixel_height_aspect) {
310 return false;
311 }
312 if (a.display.format != 0 && b.display.format != 0
313 && a.display.format != b.display.format) {
314 return false;
315 }
316 if (a.display.line_width != 0 && b.display.line_width != 0
317 && a.display.line_width != b.display.line_width) {
318 return false;
319 }
320 if (a.display.line_count != 0 && b.display.line_count != 0
321 && a.display.line_count != b.display.line_count) {
322 return false;
323 }
324 if (a.display.bytes_per_row != 0 && b.display.bytes_per_row != 0
325 && a.display.bytes_per_row != b.display.bytes_per_row) {
326 return false;
327 }
328 if (a.display.pixel_offset != 0 && b.display.pixel_offset != 0
329 && a.display.pixel_offset != b.display.pixel_offset) {
330 return false;
331 }
332 if (a.display.line_offset != 0 && b.display.line_offset != 0
333 && a.display.line_offset != b.display.line_offset) {
334 return false;
335 }
336 if (a.display.flags != 0 && b.display.flags != 0
337 && a.display.flags != b.display.flags) {
338 return false;
339 }
340
341 return true;
342 }
343
344
345 static bool
multistream_format_matches(const media_multistream_format & a,const media_multistream_format & b)346 multistream_format_matches(const media_multistream_format& a,
347 const media_multistream_format& b)
348 {
349 if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0
350 && a.avg_bit_rate != b.avg_bit_rate) {
351 return false;
352 }
353 if (a.max_bit_rate != 0 && b.max_bit_rate != 0
354 && a.max_bit_rate != b.max_bit_rate) {
355 return false;
356 }
357 if (a.avg_chunk_size != 0 && b.avg_chunk_size != 0
358 && a.avg_chunk_size != b.avg_chunk_size) {
359 return false;
360 }
361 if (a.max_chunk_size != 0 && b.max_chunk_size != 0
362 && a.max_chunk_size != b.max_chunk_size) {
363 return false;
364 }
365 if (a.flags != 0 && b.flags != 0 && a.flags != b.flags)
366 return false;
367 if (a.format != 0 && b.format != 0 && a.format != b.format)
368 return false;
369
370 if (a.format == 0 && b.format == 0) {
371 // TODO: How do we compare two formats with no type?
372 return true;
373 }
374
375 switch ((a.format != 0) ? a.format : b.format) {
376 default:
377 return true; // TODO: really?
378
379 case media_multistream_format::B_VID:
380 if (a.u.vid.frame_rate != 0 && b.u.vid.frame_rate != 0
381 && a.u.vid.frame_rate != b.u.vid.frame_rate) {
382 return false;
383 }
384 if (a.u.vid.width != 0 && b.u.vid.width != 0
385 && a.u.vid.width != b.u.vid.width) {
386 return false;
387 }
388 if (a.u.vid.height != 0 && b.u.vid.height != 0
389 && a.u.vid.height != b.u.vid.height) {
390 return false;
391 }
392 if (a.u.vid.space != 0 && b.u.vid.space != 0
393 && a.u.vid.space != b.u.vid.space) {
394 return false;
395 }
396 if (a.u.vid.sampling_rate != 0 && b.u.vid.sampling_rate != 0
397 && a.u.vid.sampling_rate != b.u.vid.sampling_rate) {
398 return false;
399 }
400 if (a.u.vid.sample_format != 0 && b.u.vid.sample_format != 0
401 && a.u.vid.sample_format != b.u.vid.sample_format) {
402 return false;
403 }
404 if (a.u.vid.byte_order != 0 && b.u.vid.byte_order != 0
405 && a.u.vid.byte_order != b.u.vid.byte_order) {
406 return false;
407 }
408 if (a.u.vid.channel_count != 0 && b.u.vid.channel_count != 0
409 && a.u.vid.channel_count != b.u.vid.channel_count) {
410 return false;
411 }
412 return true;
413
414 case media_multistream_format::B_AVI:
415 if (a.u.avi.us_per_frame != 0 && b.u.avi.us_per_frame != 0
416 && a.u.avi.us_per_frame != b.u.avi.us_per_frame) {
417 return false;
418 }
419 if (a.u.avi.width != 0 && b.u.avi.width != 0
420 && a.u.avi.width != b.u.avi.width) {
421 return false;
422 }
423 if (a.u.avi.height != 0 && b.u.avi.height != 0
424 && a.u.avi.height != b.u.avi.height) {
425 return false;
426 }
427 if (a.u.avi.type_count != 0 && b.u.avi.type_count != 0
428 && a.u.avi.type_count != b.u.avi.type_count) {
429 return false;
430 }
431 if (a.u.avi.types[0] != 0 && b.u.avi.types[0] != 0
432 && a.u.avi.types[0] != b.u.avi.types[0]) {
433 return false;
434 }
435 if (a.u.avi.types[1] != 0 && b.u.avi.types[1] != 0
436 && a.u.avi.types[1] != b.u.avi.types[1]) {
437 return false;
438 }
439 if (a.u.avi.types[2] != 0 && b.u.avi.types[2] != 0
440 && a.u.avi.types[2] != b.u.avi.types[2]) {
441 return false;
442 }
443 if (a.u.avi.types[3] != 0 && b.u.avi.types[3] != 0
444 && a.u.avi.types[3] != b.u.avi.types[3]) {
445 return false;
446 }
447 if (a.u.avi.types[4] != 0 && b.u.avi.types[4] != 0
448 && a.u.avi.types[4] != b.u.avi.types[4]) {
449 return false;
450 }
451 return true;
452 }
453 }
454
455
456 static bool
encoded_audio_format_matches(const media_encoded_audio_format & a,const media_encoded_audio_format & b)457 encoded_audio_format_matches(const media_encoded_audio_format& a,
458 const media_encoded_audio_format& b)
459 {
460 if (!raw_audio_format_matches(a.output, b.output))
461 return false;
462 if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
463 return false;
464 if (a.bit_rate != 0 && b.bit_rate != 0 && a.bit_rate != b.bit_rate)
465 return false;
466 if (a.frame_size != 0 && b.frame_size != 0 && a.frame_size != b.frame_size)
467 return false;
468 if (!multi_audio_info_matches(a.multi_info, b.multi_info))
469 return false;
470
471 if (a.encoding == 0 && b.encoding == 0)
472 return true; // can't compare
473
474 switch((a.encoding != 0) ? a.encoding : b.encoding) {
475 case media_encoded_audio_format::B_ANY:
476 default:
477 return true;
478 }
479 }
480
481
482 static bool
encoded_video_format_matches(const media_encoded_video_format & a,const media_encoded_video_format & b)483 encoded_video_format_matches(const media_encoded_video_format& a,
484 const media_encoded_video_format& b)
485 {
486 if (!raw_video_format_matches(a.output, b.output))
487 return false;
488 if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
489 return false;
490
491 if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0
492 && a.avg_bit_rate != b.avg_bit_rate) {
493 return false;
494 }
495 if (a.max_bit_rate != 0 && b.max_bit_rate != 0
496 && a.max_bit_rate != b.max_bit_rate) {
497 return false;
498 }
499 if (a.frame_size != 0 && b.frame_size != 0
500 && a.frame_size != b.frame_size) {
501 return false;
502 }
503 if (a.forward_history != 0 && b.forward_history != 0
504 && a.forward_history != b.forward_history) {
505 return false;
506 }
507 if (a.backward_history != 0 && b.backward_history != 0
508 && a.backward_history != b.backward_history) {
509 return false;
510 }
511
512 if (a.encoding == 0 && b.encoding == 0)
513 return true; // can't compare
514
515 switch((a.encoding != 0) ? a.encoding : b.encoding) {
516 case media_encoded_video_format::B_ANY:
517 default:
518 return true;
519 }
520 }
521
522
523 // #pragma mark - media_format::SpecializeTo() support
524
525
526 static void
raw_audio_format_specialize(media_raw_audio_format * format,const media_raw_audio_format * other)527 raw_audio_format_specialize(media_raw_audio_format* format,
528 const media_raw_audio_format* other)
529 {
530 if (format->frame_rate == 0)
531 format->frame_rate = other->frame_rate;
532 if (format->channel_count == 0)
533 format->channel_count = other->channel_count;
534 if (format->format == 0)
535 format->format = other->format;
536 if (format->byte_order == 0)
537 format->byte_order = other->byte_order;
538 if (format->buffer_size == 0)
539 format->buffer_size = other->buffer_size;
540 if (format->frame_rate == 0)
541 format->frame_rate = other->frame_rate;
542 }
543
544
545 static void
multi_audio_info_specialize(media_multi_audio_info * format,const media_multi_audio_info * other)546 multi_audio_info_specialize(media_multi_audio_info* format,
547 const media_multi_audio_info* other)
548 {
549 if (format->channel_mask == 0)
550 format->channel_mask = other->channel_mask;
551 if (format->valid_bits == 0)
552 format->valid_bits = other->valid_bits;
553 if (format->matrix_mask == 0)
554 format->matrix_mask = other->matrix_mask;
555 }
556
557
558 static void
multi_audio_format_specialize(media_multi_audio_format * format,const media_multi_audio_format * other)559 multi_audio_format_specialize(media_multi_audio_format* format,
560 const media_multi_audio_format* other)
561 {
562 raw_audio_format_specialize(format, other);
563 multi_audio_info_specialize(format, other);
564 }
565
566
567 static void
raw_video_format_specialize(media_raw_video_format * format,const media_raw_video_format * other)568 raw_video_format_specialize(media_raw_video_format* format,
569 const media_raw_video_format* other)
570 {
571 if (format->field_rate == 0)
572 format->field_rate = other->field_rate;
573 if (format->interlace == 0)
574 format->interlace = other->interlace;
575 if (format->first_active == 0)
576 format->first_active = other->first_active;
577 if (format->last_active == 0)
578 format->last_active = other->last_active;
579 if (format->orientation == 0)
580 format->orientation = other->orientation;
581 if (format->pixel_width_aspect == 0)
582 format->pixel_width_aspect = other->pixel_width_aspect;
583 if (format->pixel_height_aspect == 0)
584 format->pixel_height_aspect = other->pixel_height_aspect;
585 if (format->display.format == 0)
586 format->display.format = other->display.format;
587 if (format->display.line_width == 0)
588 format->display.line_width = other->display.line_width;
589 if (format->display.line_count == 0)
590 format->display.line_count = other->display.line_count;
591 if (format->display.bytes_per_row == 0)
592 format->display.bytes_per_row = other->display.bytes_per_row;
593 if (format->display.pixel_offset == 0)
594 format->display.pixel_offset = other->display.pixel_offset;
595 if (format->display.line_offset == 0)
596 format->display.line_offset = other->display.line_offset;
597 if (format->display.flags == 0)
598 format->display.flags = other->display.flags;
599 }
600
601
602 static void
multistream_format_specialize(media_multistream_format * format,const media_multistream_format * other)603 multistream_format_specialize(media_multistream_format* format,
604 const media_multistream_format* other)
605 {
606 if (format->avg_bit_rate == 0)
607 format->avg_bit_rate = other->avg_bit_rate;
608 if (format->max_bit_rate == 0)
609 format->max_bit_rate = other->max_bit_rate;
610 if (format->avg_chunk_size == 0)
611 format->avg_chunk_size = other->avg_chunk_size;
612 if (format->max_chunk_size == 0)
613 format->max_chunk_size = other->max_chunk_size;
614 if (format->flags == 0)
615 format->flags = other->flags;
616 if (format->format == 0)
617 format->format = other->format;
618
619 switch (format->format) {
620 case media_multistream_format::B_VID:
621 if (format->u.vid.frame_rate == 0)
622 format->u.vid.frame_rate = other->u.vid.frame_rate;
623 if (format->u.vid.width == 0)
624 format->u.vid.width = other->u.vid.width;
625 if (format->u.vid.height == 0)
626 format->u.vid.height = other->u.vid.height;
627 if (format->u.vid.space == 0)
628 format->u.vid.space = other->u.vid.space;
629 if (format->u.vid.sampling_rate == 0)
630 format->u.vid.sampling_rate = other->u.vid.sampling_rate;
631 if (format->u.vid.sample_format == 0)
632 format->u.vid.sample_format = other->u.vid.sample_format;
633 if (format->u.vid.byte_order == 0)
634 format->u.vid.byte_order = other->u.vid.byte_order;
635 if (format->u.vid.channel_count == 0)
636 format->u.vid.channel_count = other->u.vid.channel_count;
637 break;
638
639 case media_multistream_format::B_AVI:
640 if (format->u.avi.us_per_frame == 0)
641 format->u.avi.us_per_frame = other->u.avi.us_per_frame;
642 if (format->u.avi.width == 0)
643 format->u.avi.width = other->u.avi.width;
644 if (format->u.avi.height == 0)
645 format->u.avi.height = other->u.avi.height;
646 if (format->u.avi.type_count == 0)
647 format->u.avi.type_count = other->u.avi.type_count;
648 if (format->u.avi.types[0] == 0)
649 format->u.avi.types[0] = other->u.avi.types[0];
650 if (format->u.avi.types[1] == 0)
651 format->u.avi.types[1] = other->u.avi.types[1];
652 if (format->u.avi.types[2] == 0)
653 format->u.avi.types[2] = other->u.avi.types[2];
654 if (format->u.avi.types[3] == 0)
655 format->u.avi.types[3] = other->u.avi.types[3];
656 if (format->u.avi.types[4] == 0)
657 format->u.avi.types[4] = other->u.avi.types[4];
658 break;
659
660 default:
661 ERROR("media_format::SpecializeTo can't specialize "
662 "media_multistream_format of format %" B_PRId32 "\n",
663 format->format);
664 }
665 }
666
667
668 static void
encoded_audio_format_specialize(media_encoded_audio_format * format,const media_encoded_audio_format * other)669 encoded_audio_format_specialize(media_encoded_audio_format* format,
670 const media_encoded_audio_format* other)
671 {
672 raw_audio_format_specialize(&format->output, &other->output);
673 if (format->encoding == 0)
674 format->encoding = other->encoding;
675 if (format->bit_rate == 0)
676 format->bit_rate = other->bit_rate;
677 if (format->frame_size == 0)
678 format->frame_size = other->frame_size;
679 multi_audio_info_specialize(&format->multi_info, &other->multi_info);
680 }
681
682
683 static void
encoded_video_format_specialize(media_encoded_video_format * format,const media_encoded_video_format * other)684 encoded_video_format_specialize(media_encoded_video_format* format,
685 const media_encoded_video_format* other)
686 {
687 raw_video_format_specialize(&format->output, &other->output);
688 if (format->avg_bit_rate == 0)
689 format->avg_bit_rate = other->avg_bit_rate;
690 if (format->max_bit_rate == 0)
691 format->max_bit_rate = other->max_bit_rate;
692 if (format->encoding == 0)
693 format->encoding = other->encoding;
694 if (format->frame_size == 0)
695 format->frame_size = other->frame_size;
696 if (format->forward_history == 0)
697 format->forward_history = other->forward_history;
698 if (format->backward_history == 0)
699 format->backward_history = other->backward_history;
700 }
701
702
703 // #pragma mark - media_format
704
705
706 bool
Matches(const media_format * other) const707 media_format::Matches(const media_format* other) const
708 {
709 CALLED();
710
711 if (type == 0 && other->type == 0) {
712 // TODO: How do we compare two formats with no type?
713 return true;
714 }
715
716 if (type != 0 && other->type != 0 && type != other->type)
717 return false;
718
719 switch ((type != 0) ? type : other->type) {
720 case B_MEDIA_RAW_AUDIO:
721 return multi_audio_format_matches(u.raw_audio, other->u.raw_audio);
722
723 case B_MEDIA_RAW_VIDEO:
724 return raw_video_format_matches(u.raw_video, other->u.raw_video);
725
726 case B_MEDIA_MULTISTREAM:
727 return multistream_format_matches(u.multistream,
728 other->u.multistream);
729
730 case B_MEDIA_ENCODED_AUDIO:
731 return encoded_audio_format_matches(u.encoded_audio,
732 other->u.encoded_audio);
733
734 case B_MEDIA_ENCODED_VIDEO:
735 return encoded_video_format_matches(u.encoded_video,
736 other->u.encoded_video);
737
738 default:
739 return true; // TODO: really?
740 }
741 }
742
743
744 void
SpecializeTo(const media_format * otherFormat)745 media_format::SpecializeTo(const media_format* otherFormat)
746 {
747 CALLED();
748
749 if (type == 0 && otherFormat->type == 0) {
750 ERROR("media_format::SpecializeTo can't specialize wildcard to other "
751 "wildcard format\n");
752 return;
753 }
754
755 if (type == 0)
756 type = otherFormat->type;
757
758 switch (type) {
759 case B_MEDIA_RAW_AUDIO:
760 multi_audio_format_specialize(&u.raw_audio,
761 &otherFormat->u.raw_audio);
762 return;
763
764 case B_MEDIA_RAW_VIDEO:
765 raw_video_format_specialize(&u.raw_video,
766 &otherFormat->u.raw_video);
767 return;
768
769 case B_MEDIA_MULTISTREAM:
770 multistream_format_specialize(&u.multistream,
771 &otherFormat->u.multistream);
772 return;
773
774 case B_MEDIA_ENCODED_AUDIO:
775 encoded_audio_format_specialize(&u.encoded_audio,
776 &otherFormat->u.encoded_audio);
777 return;
778
779 case B_MEDIA_ENCODED_VIDEO:
780 encoded_video_format_specialize(&u.encoded_video,
781 &otherFormat->u.encoded_video);
782 return;
783
784 default:
785 ERROR("media_format::SpecializeTo can't specialize format "
786 "type %d\n", type);
787 }
788 }
789
790
791 status_t
SetMetaData(const void * data,size_t size)792 media_format::SetMetaData(const void* data, size_t size)
793 {
794 if (!data || size > META_DATA_MAX_SIZE)
795 return B_BAD_VALUE;
796
797 void* new_addr;
798 area_id new_area;
799 if (size < META_DATA_AREA_MIN_SIZE) {
800 new_area = B_BAD_VALUE;
801 new_addr = malloc(size);
802 if (!new_addr)
803 return B_NO_MEMORY;
804 } else {
805 new_area = create_area("meta_data_area", &new_addr, B_ANY_ADDRESS,
806 ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
807 if (new_area < 0)
808 return (status_t)new_area;
809 }
810
811 if (meta_data_area > 0)
812 delete_area(meta_data_area);
813 else
814 free(meta_data);
815
816 meta_data = new_addr;
817 meta_data_size = size;
818 meta_data_area = new_area;
819
820 memcpy(meta_data, data, size);
821
822 if (meta_data_area > 0)
823 set_area_protection(meta_data_area, B_READ_AREA);
824
825 return B_OK;
826 }
827
828
829 const void*
MetaData() const830 media_format::MetaData() const
831 {
832 return meta_data;
833 }
834
835
836 int32
MetaDataSize() const837 media_format::MetaDataSize() const
838 {
839 return meta_data_size;
840 }
841
842
843 void
Unflatten(const char * flatBuffer)844 media_format::Unflatten(const char *flatBuffer)
845 {
846 // TODO: we should not!!! make flat copies of media_format
847 memcpy(this, flatBuffer, sizeof(*this));
848 meta_data = NULL;
849 meta_data_area = B_BAD_VALUE;
850 }
851
852
853 void
Clear()854 media_format::Clear()
855 {
856 memset(this, 0x00, sizeof(*this));
857 meta_data = NULL;
858 meta_data_area = B_BAD_VALUE;
859 }
860
861
media_format()862 media_format::media_format()
863 {
864 this->Clear();
865 }
866
867
media_format(const media_format & other)868 media_format::media_format(const media_format& other)
869 {
870 this->Clear();
871 *this = other;
872 }
873
874
~media_format()875 media_format::~media_format()
876 {
877 if (meta_data_area > 0)
878 delete_area(meta_data_area);
879 else
880 free(meta_data);
881 }
882
883
884 // final
885 media_format&
operator =(const media_format & clone)886 media_format::operator=(const media_format& clone)
887 {
888 // get rid of this format's meta data
889 this->~media_format();
890 // danger: using only ~media_format() would call the constructor
891
892 // make a binary copy
893 memcpy(this, &clone, sizeof(*this));
894 // some binary copies are invalid:
895 meta_data = NULL;
896 meta_data_area = B_BAD_VALUE;
897
898 // clone or copy the meta data
899 if (clone.meta_data) {
900 if (clone.meta_data_area != B_BAD_VALUE) {
901 meta_data_area = clone_area("meta_data_clone_area", &meta_data,
902 B_ANY_ADDRESS, B_READ_AREA, clone.meta_data_area);
903 if (meta_data_area < 0) {
904 // whoops, we just lost our meta data
905 meta_data = NULL;
906 meta_data_size = 0;
907 }
908 } else {
909 meta_data = malloc(meta_data_size);
910 if (meta_data) {
911 memcpy(meta_data, clone.meta_data, meta_data_size);
912 } else {
913 // whoops, we just lost our meta data
914 meta_data_size = 0;
915 }
916 }
917 }
918 return *this;
919 }
920
921
922 // #pragma mark -
923
924
925 bool
operator ==(const media_raw_audio_format & a,const media_raw_audio_format & b)926 operator==(const media_raw_audio_format& a, const media_raw_audio_format& b)
927 {
928 return a.frame_rate == b.frame_rate
929 && a.channel_count == b.channel_count
930 && a.format == b.format
931 && a.byte_order == b.byte_order
932 && a.buffer_size == b.buffer_size;
933 }
934
935
936 bool
operator ==(const media_multi_audio_info & a,const media_multi_audio_info & b)937 operator==(const media_multi_audio_info& a, const media_multi_audio_info& b)
938 {
939 return a.channel_mask == b.channel_mask
940 && a.valid_bits == b.valid_bits
941 && a.matrix_mask == b.matrix_mask;
942 }
943
944
945 bool
operator ==(const media_multi_audio_format & a,const media_multi_audio_format & b)946 operator==(const media_multi_audio_format& a,
947 const media_multi_audio_format& b)
948 {
949 return (media_raw_audio_format)a == (media_raw_audio_format)b
950 && (media_multi_audio_info)a == (media_multi_audio_info)b;
951 }
952
953
954 bool
operator ==(const media_encoded_audio_format & a,const media_encoded_audio_format & b)955 operator==(const media_encoded_audio_format& a,
956 const media_encoded_audio_format& b)
957 {
958 return a.output == b.output
959 && a.encoding == b.encoding
960 && a.bit_rate == b.bit_rate
961 && a.frame_size == b.frame_size
962 && a.multi_info == b.multi_info;
963 }
964
965
966 bool
operator ==(const media_video_display_info & a,const media_video_display_info & b)967 operator==(const media_video_display_info& a,
968 const media_video_display_info& b)
969 {
970 return a.format == b.format
971 && a.line_width == b.line_width
972 && a.line_count == b.line_count
973 && a.bytes_per_row == b.bytes_per_row
974 && a.pixel_offset == b.pixel_offset
975 && a.line_offset == b.line_offset
976 && a.flags == b.flags;
977 }
978
979
980 bool
operator ==(const media_raw_video_format & a,const media_raw_video_format & b)981 operator==(const media_raw_video_format& a, const media_raw_video_format& b)
982 {
983 return a.field_rate == b.field_rate
984 && a.interlace == b.interlace
985 && a.first_active == b.first_active
986 && a.last_active == b.last_active
987 && a.orientation == b.orientation
988 && a.pixel_width_aspect == b.pixel_width_aspect
989 && a.pixel_height_aspect == b.pixel_height_aspect
990 && a.display == b.display;
991 }
992
993
994 bool
operator ==(const media_encoded_video_format & a,const media_encoded_video_format & b)995 operator==(const media_encoded_video_format& a,
996 const media_encoded_video_format& b)
997 {
998 return a.output == b.output
999 && a.avg_bit_rate == b.avg_bit_rate
1000 && a.max_bit_rate == b.max_bit_rate
1001 && a.encoding == b.encoding
1002 && a.frame_size == b.frame_size
1003 && a.forward_history == b.forward_history
1004 && a.backward_history == b.backward_history;
1005 }
1006
1007
1008 bool
operator ==(const media_multistream_format::vid_info & a,const media_multistream_format::vid_info & b)1009 operator==(const media_multistream_format::vid_info& a,
1010 const media_multistream_format::vid_info& b)
1011 {
1012 return a.frame_rate == b.frame_rate
1013 && a.width == b.width
1014 && a.height == b.height
1015 && a.space == b.space
1016 && a.sampling_rate == b.sampling_rate
1017 && a.sample_format == b.sample_format
1018 && a.byte_order == b.byte_order
1019 && a.channel_count == b.channel_count;
1020 }
1021
1022
1023 bool
operator ==(const media_multistream_format::avi_info & a,const media_multistream_format::avi_info & b)1024 operator==(const media_multistream_format::avi_info& a,
1025 const media_multistream_format::avi_info& b)
1026 {
1027 return a.us_per_frame == b.us_per_frame
1028 && a.width == b.width
1029 && a.height == b.height
1030 && a.type_count == b.type_count
1031 && a.types[0] == b.types[0]
1032 && a.types[1] == b.types[1]
1033 && a.types[2] == b.types[2]
1034 && a.types[3] == b.types[3]
1035 && a.types[4] == b.types[4];
1036 }
1037
1038
1039 bool
operator ==(const media_multistream_format & a,const media_multistream_format & b)1040 operator==(const media_multistream_format& a,
1041 const media_multistream_format& b)
1042 {
1043 if (a.avg_bit_rate != b.avg_bit_rate
1044 || a.max_bit_rate != b.max_bit_rate
1045 || a.avg_chunk_size != b.avg_chunk_size
1046 || a.max_chunk_size != b.max_chunk_size
1047 || a.format != b.format
1048 || a.flags != b.flags) {
1049 return false;
1050 }
1051
1052 switch (a.format) {
1053 case media_multistream_format::B_VID:
1054 return a.u.vid == b.u.vid;
1055
1056 case media_multistream_format::B_AVI:
1057 return a.u.avi == b.u.avi;
1058
1059 default:
1060 return true; // TODO: really?
1061 }
1062 }
1063
1064
1065 bool
operator ==(const media_format & a,const media_format & b)1066 operator==(const media_format& a, const media_format& b)
1067 {
1068 if (a.type != b.type
1069 || a.user_data_type != b.user_data_type
1070 // TODO: compare user_data[48] ?
1071 || a.require_flags != b.require_flags
1072 || a.deny_flags != b.deny_flags) {
1073 return false;
1074 }
1075
1076 switch (a.type) {
1077 case B_MEDIA_RAW_AUDIO:
1078 return a.u.raw_audio == b.u.raw_audio;
1079
1080 case B_MEDIA_RAW_VIDEO:
1081 return a.u.raw_video == b.u.raw_video;
1082
1083 case B_MEDIA_MULTISTREAM:
1084 return a.u.multistream == b.u.multistream;
1085
1086 case B_MEDIA_ENCODED_AUDIO:
1087 return a.u.encoded_audio == b.u.encoded_audio;
1088
1089 case B_MEDIA_ENCODED_VIDEO:
1090 return a.u.encoded_video == b.u.encoded_video;
1091
1092 default:
1093 return true; // TODO: really?
1094 }
1095 }
1096
1097
1098 // #pragma mark -
1099
1100
1101 /*! return \c true if a and b are compatible (accounting for wildcards)
1102 a is the format you want to feed to something accepting b
1103 */
1104 bool
format_is_compatible(const media_format & a,const media_format & b)1105 format_is_compatible(const media_format& a, const media_format& b)
1106 {
1107 return a.Matches(&b);
1108 }
1109
1110
1111 bool
string_for_format(const media_format & f,char * buf,size_t size)1112 string_for_format(const media_format& f, char* buf, size_t size)
1113 {
1114 char encoding[10]; /* maybe Be wanted to use some 4CCs ? */
1115 const char* videoOrientation = "0"; /* I'd use "NC", R5 uses 0. */
1116
1117 if (buf == NULL)
1118 return false;
1119 switch (f.type) {
1120 case B_MEDIA_RAW_AUDIO:
1121 snprintf(buf, size,
1122 "raw_audio;%g;%" B_PRIu32 ";0x%" B_PRIx32 ";%" B_PRIu32 ";0x%"
1123 B_PRIxSIZE ";0x%#" B_PRIx32 ";%d;0x%04x",
1124 f.u.raw_audio.frame_rate,
1125 f.u.raw_audio.channel_count,
1126 f.u.raw_audio.format,
1127 f.u.raw_audio.byte_order,
1128 f.u.raw_audio.buffer_size,
1129 f.u.raw_audio.channel_mask,
1130 f.u.raw_audio.valid_bits,
1131 f.u.raw_audio.matrix_mask);
1132 return true;
1133 case B_MEDIA_RAW_VIDEO:
1134 if (f.u.raw_video.orientation == B_VIDEO_TOP_LEFT_RIGHT)
1135 videoOrientation = "TopLR";
1136 else if (f.u.raw_video.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
1137 videoOrientation = "BotLR";
1138 snprintf(buf, size, "raw_video;%g;0x%x;%" B_PRIu32 ";%" B_PRIu32 ";%"
1139 B_PRIu32 ";%" B_PRIu32 ";%s;%d;%d",
1140 f.u.raw_video.field_rate,
1141 f.u.raw_video.display.format,
1142 f.u.raw_video.interlace,
1143 f.u.raw_video.display.line_width,
1144 f.u.raw_video.display.line_count,
1145 f.u.raw_video.first_active,
1146 videoOrientation,
1147 f.u.raw_video.pixel_width_aspect,
1148 f.u.raw_video.pixel_height_aspect);
1149 return true;
1150 case B_MEDIA_ENCODED_AUDIO:
1151 snprintf(encoding, 10, "%d", f.u.encoded_audio.encoding);
1152 snprintf(buf, size,
1153 "caudio;%s;%g;%ld;(%g;%" B_PRIu32 ";0x%" B_PRIx32 ";%" B_PRIu32
1154 ";0x%" B_PRIxSIZE ";0x%08" B_PRIx32 ";%d;0x%04x)",
1155 encoding,
1156 f.u.encoded_audio.bit_rate,
1157 f.u.encoded_audio.frame_size,
1158 f.u.encoded_audio.output.frame_rate,
1159 f.u.encoded_audio.output.channel_count,
1160 f.u.encoded_audio.output.format,
1161 f.u.encoded_audio.output.byte_order,
1162 f.u.encoded_audio.output.buffer_size,
1163 f.u.encoded_audio.multi_info.channel_mask,
1164 f.u.encoded_audio.multi_info.valid_bits,
1165 f.u.encoded_audio.multi_info.matrix_mask);
1166 return true;
1167 case B_MEDIA_ENCODED_VIDEO:
1168 snprintf(encoding, 10, "%d", f.u.encoded_video.encoding);
1169 if (f.u.encoded_video.output.orientation == B_VIDEO_TOP_LEFT_RIGHT)
1170 videoOrientation = "TopLR";
1171 else if (f.u.encoded_video.output.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
1172 videoOrientation = "BotLR";
1173 snprintf(buf, size,
1174 "cvideo;%s;%g;%g;%" B_PRIuSIZE ";(%g;0x%x;%" B_PRIu32 ";%" B_PRIu32
1175 ";%" B_PRIu32 ";%" B_PRIu32 ";%s;%d;%d)",
1176 encoding,
1177 f.u.encoded_video.avg_bit_rate,
1178 f.u.encoded_video.max_bit_rate,
1179 f.u.encoded_video.frame_size,
1180 f.u.encoded_video.output.field_rate,
1181 f.u.encoded_video.output.display.format,
1182 f.u.encoded_video.output.interlace,
1183 f.u.encoded_video.output.display.line_width,
1184 f.u.encoded_video.output.display.line_count,
1185 f.u.encoded_video.output.first_active,
1186 videoOrientation,
1187 f.u.encoded_video.output.pixel_width_aspect,
1188 f.u.encoded_video.output.pixel_height_aspect);
1189 return true;
1190 default:
1191 snprintf(buf, size, "%d-", f.type);
1192 unsigned char* p = (unsigned char*)&(f.u);
1193 size -= strlen(buf);
1194 buf += strlen(buf);
1195 for (int i = 0; (size > 2) && (i < 96); i++) {
1196 snprintf(buf, 3, "%2.2x", *(p + i));
1197 buf+=2;
1198 size-=2;
1199 }
1200 return true; // ?
1201 }
1202 return false;
1203 }
1204
1205
1206 // #pragma mark -
1207
1208
1209 bool
operator ==(const media_file_format_id & a,const media_file_format_id & b)1210 operator==(const media_file_format_id& a, const media_file_format_id& b)
1211 {
1212 return a.node == b.node && a.device == b.device
1213 && a.internal_id == b.internal_id;
1214 }
1215
1216
1217 bool
operator <(const media_file_format_id & a,const media_file_format_id & b)1218 operator<(const media_file_format_id& a, const media_file_format_id& b)
1219 {
1220 return a.internal_id < b.internal_id;
1221 }
1222
1223
1224 // #pragma mark -
1225
1226
1227 //! Use this function to iterate through available file format writers.
1228 status_t
get_next_file_format(int32 * cookie,media_file_format * mff)1229 get_next_file_format(int32* cookie, media_file_format* mff)
1230 {
1231 if (cookie == NULL || mff == NULL)
1232 return B_BAD_VALUE;
1233
1234 status_t ret = AddOnManager::GetInstance()->GetFileFormat(mff, *cookie);
1235 if (ret != B_OK)
1236 return ret;
1237
1238 *cookie = *cookie + 1;
1239
1240 return B_OK;
1241 }
1242
1243
1244 // #pragma mark -
1245
1246
1247 // final & verified
1248 const char* B_MEDIA_SERVER_SIGNATURE = "application/x-vnd.Be.media-server";
1249 const char* B_MEDIA_ADDON_SERVER_SIGNATURE = "application/x-vnd.Be.addon-host";
1250
1251 const type_code B_CODEC_TYPE_INFO = 0x040807b2;
1252
1253
1254 // #pragma mark -
1255
1256
1257 // shutdown_media_server() and launch_media_server()
1258 // are provided by libbe.so in BeOS R5
1259
1260 #define MEDIA_SERVICE_NOTIFICATION_ID "MediaServiceNotificationID"
1261
1262
1263 void
notify_system(float progress,const char * message)1264 notify_system(float progress, const char* message)
1265 {
1266 BNotification notification(B_PROGRESS_NOTIFICATION);
1267 notification.SetMessageID(MEDIA_SERVICE_NOTIFICATION_ID);
1268 notification.SetProgress(progress);
1269 notification.SetGroup(B_TRANSLATE("Media Service"));
1270 notification.SetContent(message);
1271
1272 app_info info;
1273 be_app->GetAppInfo(&info);
1274 BBitmap icon(BRect(0, 0, 32, 32), B_RGBA32);
1275 BNode node(&info.ref);
1276 BIconUtils::GetVectorIcon(&node, "BEOS:ICON", &icon);
1277 notification.SetIcon(&icon);
1278
1279 notification.Send();
1280 }
1281
1282
1283 void
progress_shutdown(int stage,bool (* progress)(int stage,const char * message,void * cookie),void * cookie)1284 progress_shutdown(int stage,
1285 bool (*progress)(int stage, const char* message, void* cookie),
1286 void* cookie)
1287 {
1288 // parameter "message" is no longer used. It is kept for compatibility with
1289 // BeOS as this is used as a shutdown_media_server callback.
1290
1291 TRACE("stage: %i\n", stage);
1292 const char* string = "Unknown stage";
1293 switch (stage) {
1294 case 10:
1295 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS);
1296 break;
1297 case 20:
1298 string = B_TRANSLATE("Waiting for media_server to quit.");
1299 break;
1300 case 40:
1301 string = B_TRANSLATE("Telling media_addon_server to quit.");
1302 break;
1303 case 50:
1304 string = B_TRANSLATE("Waiting for media_addon_server to quit.");
1305 break;
1306 case 70:
1307 string = B_TRANSLATE("Cleaning up.");
1308 break;
1309 case 100:
1310 string = B_TRANSLATE("Done shutting down.");
1311 break;
1312 }
1313
1314 if (progress == NULL)
1315 notify_system(stage / 100.0f, string);
1316 else
1317 progress(stage, string, cookie);
1318 }
1319
1320
1321 status_t
shutdown_media_server(bigtime_t timeout,bool (* progress)(int stage,const char * message,void * cookie),void * cookie)1322 shutdown_media_server(bigtime_t timeout,
1323 bool (*progress)(int stage, const char* message, void* cookie),
1324 void* cookie)
1325 {
1326 BLaunchRoster launchRoster;
1327 launchRoster.StopTarget(B_MEDIA_SERVER_SIGNATURE);
1328
1329 BMessage msg(B_QUIT_REQUESTED);
1330 status_t err = B_MEDIA_SYSTEM_FAILURE;
1331 bool shutdown = false;
1332
1333 BMediaRoster* roster = BMediaRoster::Roster(&err);
1334 if (roster == NULL || err != B_OK)
1335 return err;
1336
1337 if (progress == NULL && roster->Lock()) {
1338 MediaRosterEx(roster)->EnableLaunchNotification(true, true);
1339 roster->Unlock();
1340 }
1341
1342 if ((err = msg.AddBool("be:_user_request", true)) != B_OK)
1343 return err;
1344
1345 team_id mediaServer = be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE);
1346 team_id addOnServer = be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE);
1347
1348 if (mediaServer != B_ERROR) {
1349 BMessage reply;
1350 BMessenger messenger(B_MEDIA_SERVER_SIGNATURE, mediaServer);
1351 progress_shutdown(10, progress, cookie);
1352
1353 err = messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1354 reply.FindBool("_shutdown", &shutdown);
1355 if (err == B_TIMED_OUT || shutdown == false) {
1356 if (messenger.IsValid())
1357 kill_team(mediaServer);
1358 } else if (err != B_OK)
1359 return err;
1360
1361 progress_shutdown(20, progress, cookie);
1362
1363 int32 rv;
1364 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1365 return rv;
1366 }
1367
1368 if (addOnServer != B_ERROR) {
1369 shutdown = false;
1370 BMessage reply;
1371 BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE, addOnServer);
1372 progress_shutdown(40, progress, cookie);
1373
1374 // The media_server usually shutdown the media_addon_server,
1375 // if not let's do something.
1376 if (messenger.IsValid()) {
1377 err = messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1378 reply.FindBool("_shutdown", &shutdown);
1379 if (err == B_TIMED_OUT || shutdown == false) {
1380 if (messenger.IsValid())
1381 kill_team(addOnServer);
1382 } else if (err != B_OK)
1383 return err;
1384
1385 progress_shutdown(50, progress, cookie);
1386
1387 int32 rv;
1388 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1389 return rv;
1390 }
1391 }
1392
1393 progress_shutdown(100, progress, cookie);
1394 return B_OK;
1395 }
1396
1397
1398 void
progress_startup(int stage,bool (* progress)(int stage,const char * message,void * cookie),void * cookie)1399 progress_startup(int stage,
1400 bool (*progress)(int stage, const char* message, void* cookie),
1401 void* cookie)
1402 {
1403 // parameter "message" is no longer used. It is kept for compatibility with
1404 // BeOS as this is used as a shutdown_media_server callback.
1405
1406 TRACE("stage: %i\n", stage);
1407 const char* string = "Unknown stage";
1408 switch (stage) {
1409 case 10:
1410 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS);
1411 break;
1412 case 20:
1413 string = B_TRANSLATE("Stopping media_addon_server.");
1414 break;
1415 case 50:
1416 string = B_TRANSLATE("Starting media_services.");
1417 break;
1418 case 90:
1419 string = B_TRANSLATE("Error occurred starting media services.");
1420 break;
1421 case 100:
1422 string = B_TRANSLATE("Ready for use.");
1423 break;
1424 }
1425
1426 if (progress == NULL)
1427 notify_system(stage / 100.0f, string);
1428 else
1429 progress(stage, string, cookie);
1430 }
1431
1432
1433 status_t
launch_media_server(bigtime_t timeout,bool (* progress)(int stage,const char * message,void * cookie),void * cookie,uint32 flags)1434 launch_media_server(bigtime_t timeout,
1435 bool (*progress)(int stage, const char* message, void* cookie),
1436 void* cookie, uint32 flags)
1437 {
1438 if (BMediaRoster::IsRunning())
1439 return B_ALREADY_RUNNING;
1440
1441 status_t err = B_MEDIA_SYSTEM_FAILURE;
1442 BMediaRoster* roster = BMediaRoster::Roster(&err);
1443 if (roster == NULL || err != B_OK)
1444 return err;
1445
1446 if (progress == NULL && roster->Lock()) {
1447 MediaRosterEx(roster)->EnableLaunchNotification(true, true);
1448 roster->Unlock();
1449 }
1450
1451 // The media_server crashed
1452 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1453 progress_startup(10, progress, cookie);
1454 kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1455 }
1456
1457 // The media_addon_server crashed
1458 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1459 progress_startup(20, progress, cookie);
1460 kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE));
1461 }
1462
1463 progress_startup(50, progress, cookie);
1464
1465 err = BLaunchRoster().Start(B_MEDIA_SERVER_SIGNATURE);
1466
1467 if (err != B_OK)
1468 progress_startup(90, progress, cookie);
1469 else if (progress != NULL) {
1470 progress_startup(100, progress, cookie);
1471 err = B_OK;
1472 }
1473
1474 return err;
1475 }
1476
1477
1478 // #pragma mark - media_encode_info
1479
1480
media_encode_info()1481 media_encode_info::media_encode_info()
1482 {
1483 flags = 0;
1484 used_data_size = 0;
1485 start_time = 0;
1486 time_to_encode = INT64_MAX;
1487 file_format_data = NULL;
1488 file_format_data_size = 0;
1489 codec_data = NULL;
1490 codec_data_size = 0;
1491 }
1492
1493
media_decode_info()1494 media_decode_info::media_decode_info()
1495 {
1496 time_to_decode = INT64_MAX;
1497 file_format_data = NULL;
1498 file_format_data_size = 0;
1499 codec_data = NULL;
1500 codec_data_size = 0;
1501 }
1502
1503
1504