xref: /haiku/src/kits/media/MediaDefs.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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 
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 #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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
707 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
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
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*
830 media_format::MetaData() const
831 {
832 	return meta_data;
833 }
834 
835 
836 int32
837 media_format::MetaDataSize() const
838 {
839 	return meta_data_size;
840 }
841 
842 
843 void
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
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 
862 media_format::media_format()
863 {
864 	this->Clear();
865 }
866 
867 
868 media_format::media_format(const media_format& other)
869 {
870 	this->Clear();
871 	*this = other;
872 }
873 
874 
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&
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
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
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
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
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
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
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
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
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
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
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
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
1105 format_is_compatible(const media_format& a, const media_format& b)
1106 {
1107 	return a.Matches(&b);
1108 }
1109 
1110 
1111 bool
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
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
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
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
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
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
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
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
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 
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 
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