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