tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / media / MediaDefs.cpp
blobcd6e95a698dfd6592ebc6951f70a1436c4396513
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 */
11 #include <MediaDefs.h>
13 #include <Application.h>
14 #include <Bitmap.h>
15 #include <Catalog.h>
16 #include <IconUtils.h>
17 #include <Locale.h>
18 #include <MediaNode.h>
19 #include <MediaRoster.h>
20 #include <Node.h>
21 #include <Notification.h>
22 #include <Roster.h>
24 #include <inttypes.h>
25 #include <stdio.h>
26 #include <string.h>
28 #include "AddOnManager.h"
29 #include "DataExchange.h"
30 #include "debug.h"
31 #include "MediaMisc.h"
34 #define META_DATA_MAX_SIZE (16 << 20)
35 #define META_DATA_AREA_MIN_SIZE 32000
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "MediaDefs"
41 // #pragma mark - media_destination
44 media_destination::media_destination(port_id port, int32 id)
46 port(port),
47 id(id)
52 media_destination::media_destination(const media_destination& clone)
54 port(clone.port),
55 id(clone.id)
60 media_destination&
61 media_destination::operator=(const media_destination& clone)
63 port = clone.port;
64 id = clone.id;
65 return *this;
69 media_destination::media_destination()
71 port(-1),
72 id(-1)
77 media_destination::~media_destination()
82 media_destination media_destination::null(-1, -1);
85 // #pragma mark - media_source
88 media_source::media_source(port_id port,
89 int32 id)
91 port(port),
92 id(id)
97 media_source::media_source(const media_source& clone)
99 port(clone.port),
100 id(clone.id)
105 media_source&
106 media_source::operator=(const media_source& clone)
108 port = clone.port;
109 id = clone.id;
110 return *this;
114 media_source::media_source()
116 port(-1),
117 id(-1)
122 media_source::~media_source()
127 media_source media_source::null(-1, -1);
130 // #pragma mark -
133 bool
134 operator==(const media_destination& a, const media_destination& b)
136 return a.port == b.port && a.id == b.id;
140 bool
141 operator!=(const media_destination& a, const media_destination& b)
143 return a.port != b.port || a.id != b.id;
147 bool
148 operator<(const media_destination& a, const media_destination& b)
150 UNIMPLEMENTED();
151 return false;
155 bool
156 operator==(const media_source& a, const media_source& b)
158 return a.port == b.port && a.id == b.id;
162 bool
163 operator!=(const media_source& a, const media_source& b)
165 return a.port != b.port || a.id != b.id;
169 bool
170 operator<(const media_source& a, const media_source& b)
172 UNIMPLEMENTED();
173 return false;
177 bool
178 operator==(const media_node& a, const media_node& b)
180 return a.node == b.node && a.port == b.port && a.kind == b.kind;
184 bool
185 operator!=(const media_node& a, const media_node& b)
187 return a.node != b.node || a.port != b.port || a.kind != b.kind;
191 bool
192 operator<(const media_node& a, const media_node& b)
194 UNIMPLEMENTED();
195 return false;
199 // #pragma mark -
202 media_multi_audio_format media_raw_audio_format::wildcard;
204 media_multi_audio_format media_multi_audio_format::wildcard;
206 media_encoded_audio_format media_encoded_audio_format::wildcard = {{0}};
208 media_video_display_info media_video_display_info::wildcard = {(color_space)0};
210 media_raw_video_format media_raw_video_format::wildcard = {0};
212 media_encoded_video_format media_encoded_video_format::wildcard = {{0}};
214 media_multistream_format media_multistream_format::wildcard = {0};
217 // #pragma mark - media_format::Matches() support
220 static bool
221 raw_audio_format_matches(const media_raw_audio_format& a,
222 const media_raw_audio_format& b)
224 if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
225 return false;
226 if (a.channel_count != 0 && b.channel_count != 0
227 && a.channel_count != b.channel_count) {
228 return false;
230 if (a.format != 0 && b.format != 0 && a.format != b.format)
231 return false;
232 if (a.byte_order != 0 && b.byte_order != 0 && a.byte_order != b.byte_order)
233 return false;
234 if (a.buffer_size != 0 && b.buffer_size != 0
235 && a.buffer_size != b.buffer_size) {
236 return false;
238 if (a.frame_rate != 0 && b.frame_rate != 0 && a.frame_rate != b.frame_rate)
239 return false;
240 return true;
244 static bool
245 multi_audio_info_matches(const media_multi_audio_info& a,
246 const media_multi_audio_info& b)
248 if (a.channel_mask != 0 && b.channel_mask != 0
249 && a.channel_mask != b.channel_mask) {
250 return false;
252 if (a.valid_bits != 0 && b.valid_bits != 0 && a.valid_bits != b.valid_bits)
253 return false;
254 if (a.matrix_mask != 0 && b.matrix_mask != 0
255 && a.matrix_mask != b.matrix_mask) {
256 return false;
258 return true;
262 static bool
263 multi_audio_format_matches(const media_multi_audio_format& a,
264 const media_multi_audio_format& b)
266 return raw_audio_format_matches(a, b) && multi_audio_info_matches(a, b);
270 static bool
271 raw_video_format_matches(const media_raw_video_format& a,
272 const media_raw_video_format& b)
274 if (a.field_rate != 0 && b.field_rate != 0
275 && a.field_rate != b.field_rate) {
276 return false;
278 if (a.interlace != 0 && b.interlace != 0
279 && a.interlace != b.interlace) {
280 return false;
282 if (a.first_active != 0 && b.first_active != 0
283 && a.first_active != b.first_active) {
284 return false;
286 if (a.last_active != 0 && b.last_active != 0
287 && a.last_active != b.last_active) {
288 return false;
290 if (a.orientation != 0 && b.orientation != 0
291 && a.orientation != b.orientation) {
292 return false;
294 if (a.pixel_width_aspect != 0 && b.pixel_width_aspect != 0
295 && a.pixel_width_aspect != b.pixel_width_aspect) {
296 return false;
298 if (a.pixel_height_aspect != 0 && b.pixel_height_aspect != 0
299 && a.pixel_height_aspect != b.pixel_height_aspect) {
300 return false;
302 if (a.display.format != 0 && b.display.format != 0
303 && a.display.format != b.display.format) {
304 return false;
306 if (a.display.line_width != 0 && b.display.line_width != 0
307 && a.display.line_width != b.display.line_width) {
308 return false;
310 if (a.display.line_count != 0 && b.display.line_count != 0
311 && a.display.line_count != b.display.line_count) {
312 return false;
314 if (a.display.bytes_per_row != 0 && b.display.bytes_per_row != 0
315 && a.display.bytes_per_row != b.display.bytes_per_row) {
316 return false;
318 if (a.display.pixel_offset != 0 && b.display.pixel_offset != 0
319 && a.display.pixel_offset != b.display.pixel_offset) {
320 return false;
322 if (a.display.line_offset != 0 && b.display.line_offset != 0
323 && a.display.line_offset != b.display.line_offset) {
324 return false;
326 if (a.display.flags != 0 && b.display.flags != 0
327 && a.display.flags != b.display.flags) {
328 return false;
331 return true;
335 static bool
336 multistream_format_matches(const media_multistream_format& a,
337 const media_multistream_format& b)
339 if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0
340 && a.avg_bit_rate != b.avg_bit_rate) {
341 return false;
343 if (a.max_bit_rate != 0 && b.max_bit_rate != 0
344 && a.max_bit_rate != b.max_bit_rate) {
345 return false;
347 if (a.avg_chunk_size != 0 && b.avg_chunk_size != 0
348 && a.avg_chunk_size != b.avg_chunk_size) {
349 return false;
351 if (a.max_chunk_size != 0 && b.max_chunk_size != 0
352 && a.max_chunk_size != b.max_chunk_size) {
353 return false;
355 if (a.flags != 0 && b.flags != 0 && a.flags != b.flags)
356 return false;
357 if (a.format != 0 && b.format != 0 && a.format != b.format)
358 return false;
360 if (a.format == 0 && b.format == 0) {
361 // TODO: How do we compare two formats with no type?
362 return true;
365 switch ((a.format != 0) ? a.format : b.format) {
366 default:
367 return true; // TODO: really?
369 case media_multistream_format::B_VID:
370 if (a.u.vid.frame_rate != 0 && b.u.vid.frame_rate != 0
371 && a.u.vid.frame_rate != b.u.vid.frame_rate) {
372 return false;
374 if (a.u.vid.width != 0 && b.u.vid.width != 0
375 && a.u.vid.width != b.u.vid.width) {
376 return false;
378 if (a.u.vid.height != 0 && b.u.vid.height != 0
379 && a.u.vid.height != b.u.vid.height) {
380 return false;
382 if (a.u.vid.space != 0 && b.u.vid.space != 0
383 && a.u.vid.space != b.u.vid.space) {
384 return false;
386 if (a.u.vid.sampling_rate != 0 && b.u.vid.sampling_rate != 0
387 && a.u.vid.sampling_rate != b.u.vid.sampling_rate) {
388 return false;
390 if (a.u.vid.sample_format != 0 && b.u.vid.sample_format != 0
391 && a.u.vid.sample_format != b.u.vid.sample_format) {
392 return false;
394 if (a.u.vid.byte_order != 0 && b.u.vid.byte_order != 0
395 && a.u.vid.byte_order != b.u.vid.byte_order) {
396 return false;
398 if (a.u.vid.channel_count != 0 && b.u.vid.channel_count != 0
399 && a.u.vid.channel_count != b.u.vid.channel_count) {
400 return false;
402 return true;
404 case media_multistream_format::B_AVI:
405 if (a.u.avi.us_per_frame != 0 && b.u.avi.us_per_frame != 0
406 && a.u.avi.us_per_frame != b.u.avi.us_per_frame) {
407 return false;
409 if (a.u.avi.width != 0 && b.u.avi.width != 0
410 && a.u.avi.width != b.u.avi.width) {
411 return false;
413 if (a.u.avi.height != 0 && b.u.avi.height != 0
414 && a.u.avi.height != b.u.avi.height) {
415 return false;
417 if (a.u.avi.type_count != 0 && b.u.avi.type_count != 0
418 && a.u.avi.type_count != b.u.avi.type_count) {
419 return false;
421 if (a.u.avi.types[0] != 0 && b.u.avi.types[0] != 0
422 && a.u.avi.types[0] != b.u.avi.types[0]) {
423 return false;
425 if (a.u.avi.types[1] != 0 && b.u.avi.types[1] != 0
426 && a.u.avi.types[1] != b.u.avi.types[1]) {
427 return false;
429 if (a.u.avi.types[2] != 0 && b.u.avi.types[2] != 0
430 && a.u.avi.types[2] != b.u.avi.types[2]) {
431 return false;
433 if (a.u.avi.types[3] != 0 && b.u.avi.types[3] != 0
434 && a.u.avi.types[3] != b.u.avi.types[3]) {
435 return false;
437 if (a.u.avi.types[4] != 0 && b.u.avi.types[4] != 0
438 && a.u.avi.types[4] != b.u.avi.types[4]) {
439 return false;
441 return true;
446 static bool
447 encoded_audio_format_matches(const media_encoded_audio_format& a,
448 const media_encoded_audio_format& b)
450 if (!raw_audio_format_matches(a.output, b.output))
451 return false;
452 if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
453 return false;
454 if (a.bit_rate != 0 && b.bit_rate != 0 && a.bit_rate != b.bit_rate)
455 return false;
456 if (a.frame_size != 0 && b.frame_size != 0 && a.frame_size != b.frame_size)
457 return false;
458 if (!multi_audio_info_matches(a.multi_info, b.multi_info))
459 return false;
461 if (a.encoding == 0 && b.encoding == 0)
462 return true; // can't compare
464 switch((a.encoding != 0) ? a.encoding : b.encoding) {
465 case media_encoded_audio_format::B_ANY:
466 default:
467 return true;
472 static bool
473 encoded_video_format_matches(const media_encoded_video_format& a,
474 const media_encoded_video_format& b)
476 if (!raw_video_format_matches(a.output, b.output))
477 return false;
478 if (a.encoding != 0 && b.encoding != 0 && a.encoding != b.encoding)
479 return false;
481 if (a.avg_bit_rate != 0 && b.avg_bit_rate != 0
482 && a.avg_bit_rate != b.avg_bit_rate) {
483 return false;
485 if (a.max_bit_rate != 0 && b.max_bit_rate != 0
486 && a.max_bit_rate != b.max_bit_rate) {
487 return false;
489 if (a.frame_size != 0 && b.frame_size != 0
490 && a.frame_size != b.frame_size) {
491 return false;
493 if (a.forward_history != 0 && b.forward_history != 0
494 && a.forward_history != b.forward_history) {
495 return false;
497 if (a.backward_history != 0 && b.backward_history != 0
498 && a.backward_history != b.backward_history) {
499 return false;
502 if (a.encoding == 0 && b.encoding == 0)
503 return true; // can't compare
505 switch((a.encoding != 0) ? a.encoding : b.encoding) {
506 case media_encoded_video_format::B_ANY:
507 default:
508 return true;
513 // #pragma mark - media_format::SpecializeTo() support
516 static void
517 raw_audio_format_specialize(media_raw_audio_format* format,
518 const media_raw_audio_format* other)
520 if (format->frame_rate == 0)
521 format->frame_rate = other->frame_rate;
522 if (format->channel_count == 0)
523 format->channel_count = other->channel_count;
524 if (format->format == 0)
525 format->format = other->format;
526 if (format->byte_order == 0)
527 format->byte_order = other->byte_order;
528 if (format->buffer_size == 0)
529 format->buffer_size = other->buffer_size;
530 if (format->frame_rate == 0)
531 format->frame_rate = other->frame_rate;
535 static void
536 multi_audio_info_specialize(media_multi_audio_info* format,
537 const media_multi_audio_info* other)
539 if (format->channel_mask == 0)
540 format->channel_mask = other->channel_mask;
541 if (format->valid_bits == 0)
542 format->valid_bits = other->valid_bits;
543 if (format->matrix_mask == 0)
544 format->matrix_mask = other->matrix_mask;
548 static void
549 multi_audio_format_specialize(media_multi_audio_format* format,
550 const media_multi_audio_format* other)
552 raw_audio_format_specialize(format, other);
553 multi_audio_info_specialize(format, other);
557 static void
558 raw_video_format_specialize(media_raw_video_format* format,
559 const media_raw_video_format* other)
561 if (format->field_rate == 0)
562 format->field_rate = other->field_rate;
563 if (format->interlace == 0)
564 format->interlace = other->interlace;
565 if (format->first_active == 0)
566 format->first_active = other->first_active;
567 if (format->last_active == 0)
568 format->last_active = other->last_active;
569 if (format->orientation == 0)
570 format->orientation = other->orientation;
571 if (format->pixel_width_aspect == 0)
572 format->pixel_width_aspect = other->pixel_width_aspect;
573 if (format->pixel_height_aspect == 0)
574 format->pixel_height_aspect = other->pixel_height_aspect;
575 if (format->display.format == 0)
576 format->display.format = other->display.format;
577 if (format->display.line_width == 0)
578 format->display.line_width = other->display.line_width;
579 if (format->display.line_count == 0)
580 format->display.line_count = other->display.line_count;
581 if (format->display.bytes_per_row == 0)
582 format->display.bytes_per_row = other->display.bytes_per_row;
583 if (format->display.pixel_offset == 0)
584 format->display.pixel_offset = other->display.pixel_offset;
585 if (format->display.line_offset == 0)
586 format->display.line_offset = other->display.line_offset;
587 if (format->display.flags == 0)
588 format->display.flags = other->display.flags;
592 static void
593 multistream_format_specialize(media_multistream_format* format,
594 const media_multistream_format* other)
596 if (format->avg_bit_rate == 0)
597 format->avg_bit_rate = other->avg_bit_rate;
598 if (format->max_bit_rate == 0)
599 format->max_bit_rate = other->max_bit_rate;
600 if (format->avg_chunk_size == 0)
601 format->avg_chunk_size = other->avg_chunk_size;
602 if (format->max_chunk_size == 0)
603 format->max_chunk_size = other->max_chunk_size;
604 if (format->flags == 0)
605 format->flags = other->flags;
606 if (format->format == 0)
607 format->format = other->format;
609 switch (format->format) {
610 case media_multistream_format::B_VID:
611 if (format->u.vid.frame_rate == 0)
612 format->u.vid.frame_rate = other->u.vid.frame_rate;
613 if (format->u.vid.width == 0)
614 format->u.vid.width = other->u.vid.width;
615 if (format->u.vid.height == 0)
616 format->u.vid.height = other->u.vid.height;
617 if (format->u.vid.space == 0)
618 format->u.vid.space = other->u.vid.space;
619 if (format->u.vid.sampling_rate == 0)
620 format->u.vid.sampling_rate = other->u.vid.sampling_rate;
621 if (format->u.vid.sample_format == 0)
622 format->u.vid.sample_format = other->u.vid.sample_format;
623 if (format->u.vid.byte_order == 0)
624 format->u.vid.byte_order = other->u.vid.byte_order;
625 if (format->u.vid.channel_count == 0)
626 format->u.vid.channel_count = other->u.vid.channel_count;
627 break;
629 case media_multistream_format::B_AVI:
630 if (format->u.avi.us_per_frame == 0)
631 format->u.avi.us_per_frame = other->u.avi.us_per_frame;
632 if (format->u.avi.width == 0)
633 format->u.avi.width = other->u.avi.width;
634 if (format->u.avi.height == 0)
635 format->u.avi.height = other->u.avi.height;
636 if (format->u.avi.type_count == 0)
637 format->u.avi.type_count = other->u.avi.type_count;
638 if (format->u.avi.types[0] == 0)
639 format->u.avi.types[0] = other->u.avi.types[0];
640 if (format->u.avi.types[1] == 0)
641 format->u.avi.types[1] = other->u.avi.types[1];
642 if (format->u.avi.types[2] == 0)
643 format->u.avi.types[2] = other->u.avi.types[2];
644 if (format->u.avi.types[3] == 0)
645 format->u.avi.types[3] = other->u.avi.types[3];
646 if (format->u.avi.types[4] == 0)
647 format->u.avi.types[4] = other->u.avi.types[4];
648 break;
650 default:
651 ERROR("media_format::SpecializeTo can't specialize "
652 "media_multistream_format of format %" B_PRId32 "\n",
653 format->format);
658 static void
659 encoded_audio_format_specialize(media_encoded_audio_format* format,
660 const media_encoded_audio_format* other)
662 raw_audio_format_specialize(&format->output, &other->output);
663 if (format->encoding == 0)
664 format->encoding = other->encoding;
665 if (format->bit_rate == 0)
666 format->bit_rate = other->bit_rate;
667 if (format->frame_size == 0)
668 format->frame_size = other->frame_size;
669 multi_audio_info_specialize(&format->multi_info, &other->multi_info);
673 static void
674 encoded_video_format_specialize(media_encoded_video_format* format,
675 const media_encoded_video_format* other)
677 raw_video_format_specialize(&format->output, &other->output);
678 if (format->avg_bit_rate == 0)
679 format->avg_bit_rate = other->avg_bit_rate;
680 if (format->max_bit_rate == 0)
681 format->max_bit_rate = other->max_bit_rate;
682 if (format->encoding == 0)
683 format->encoding = other->encoding;
684 if (format->frame_size == 0)
685 format->frame_size = other->frame_size;
686 if (format->forward_history == 0)
687 format->forward_history = other->forward_history;
688 if (format->backward_history == 0)
689 format->backward_history = other->backward_history;
693 // #pragma mark - media_format
696 bool
697 media_format::Matches(const media_format* other) const
699 CALLED();
701 if (type == 0 && other->type == 0) {
702 // TODO: How do we compare two formats with no type?
703 return true;
706 if (type != 0 && other->type != 0 && type != other->type)
707 return false;
709 switch ((type != 0) ? type : other->type) {
710 case B_MEDIA_RAW_AUDIO:
711 return multi_audio_format_matches(u.raw_audio, other->u.raw_audio);
713 case B_MEDIA_RAW_VIDEO:
714 return raw_video_format_matches(u.raw_video, other->u.raw_video);
716 case B_MEDIA_MULTISTREAM:
717 return multistream_format_matches(u.multistream,
718 other->u.multistream);
720 case B_MEDIA_ENCODED_AUDIO:
721 return encoded_audio_format_matches(u.encoded_audio,
722 other->u.encoded_audio);
724 case B_MEDIA_ENCODED_VIDEO:
725 return encoded_video_format_matches(u.encoded_video,
726 other->u.encoded_video);
728 default:
729 return true; // TODO: really?
734 void
735 media_format::SpecializeTo(const media_format* otherFormat)
737 CALLED();
739 if (type == 0 && otherFormat->type == 0) {
740 ERROR("media_format::SpecializeTo can't specialize wildcard to other "
741 "wildcard format\n");
742 return;
745 if (type == 0)
746 type = otherFormat->type;
748 switch (type) {
749 case B_MEDIA_RAW_AUDIO:
750 multi_audio_format_specialize(&u.raw_audio,
751 &otherFormat->u.raw_audio);
752 return;
754 case B_MEDIA_RAW_VIDEO:
755 raw_video_format_specialize(&u.raw_video,
756 &otherFormat->u.raw_video);
757 return;
759 case B_MEDIA_MULTISTREAM:
760 multistream_format_specialize(&u.multistream,
761 &otherFormat->u.multistream);
762 return;
764 case B_MEDIA_ENCODED_AUDIO:
765 encoded_audio_format_specialize(&u.encoded_audio,
766 &otherFormat->u.encoded_audio);
767 return;
769 case B_MEDIA_ENCODED_VIDEO:
770 encoded_video_format_specialize(&u.encoded_video,
771 &otherFormat->u.encoded_video);
772 return;
774 default:
775 ERROR("media_format::SpecializeTo can't specialize format "
776 "type %d\n", type);
781 status_t
782 media_format::SetMetaData(const void* data, size_t size)
784 if (!data || size < 0 || size > META_DATA_MAX_SIZE)
785 return B_BAD_VALUE;
787 void* new_addr;
788 area_id new_area;
789 if (size < META_DATA_AREA_MIN_SIZE) {
790 new_area = B_BAD_VALUE;
791 new_addr = malloc(size);
792 if (!new_addr)
793 return B_NO_MEMORY;
794 } else {
795 new_area = create_area("meta_data_area", &new_addr, B_ANY_ADDRESS,
796 ROUND_UP_TO_PAGE(size), B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
797 if (new_area < 0)
798 return (status_t)new_area;
801 if (meta_data_area > 0)
802 delete_area(meta_data_area);
803 else
804 free(meta_data);
806 meta_data = new_addr;
807 meta_data_size = size;
808 meta_data_area = new_area;
810 memcpy(meta_data, data, size);
812 if (meta_data_area > 0)
813 set_area_protection(meta_data_area, B_READ_AREA);
815 return B_OK;
819 const void*
820 media_format::MetaData() const
822 return meta_data;
826 int32
827 media_format::MetaDataSize() const
829 return meta_data_size;
833 media_format::media_format()
835 memset(this, 0x00, sizeof(*this));
836 meta_data_area = B_BAD_VALUE;
840 media_format::media_format(const media_format& other)
842 memset(this, 0x00, sizeof(*this));
843 meta_data_area = B_BAD_VALUE;
844 *this = other;
848 media_format::~media_format()
850 if (meta_data_area > 0)
851 delete_area(meta_data_area);
852 else
853 free(meta_data);
857 // final
858 media_format&
859 media_format::operator=(const media_format& clone)
861 // get rid of this format's meta data
862 this->~media_format();
863 // danger: using only ~media_format() would call the constructor
865 // make a binary copy
866 memcpy(this, &clone, sizeof(*this));
867 // some binary copies are invalid:
868 meta_data = NULL;
869 meta_data_area = B_BAD_VALUE;
871 // clone or copy the meta data
872 if (clone.meta_data) {
873 if (clone.meta_data_area != B_BAD_VALUE) {
874 meta_data_area = clone_area("meta_data_clone_area", &meta_data,
875 B_ANY_ADDRESS, B_READ_AREA, clone.meta_data_area);
876 if (meta_data_area < 0) {
877 // whoops, we just lost our meta data
878 meta_data = NULL;
879 meta_data_size = 0;
881 } else {
882 meta_data = malloc(meta_data_size);
883 if (meta_data) {
884 memcpy(meta_data, clone.meta_data, meta_data_size);
885 } else {
886 // whoops, we just lost our meta data
887 meta_data_size = 0;
891 return *this;
895 // #pragma mark -
898 bool
899 operator==(const media_raw_audio_format& a, const media_raw_audio_format& b)
901 return a.frame_rate == b.frame_rate
902 && a.channel_count == b.channel_count
903 && a.format == b.format
904 && a.byte_order == b.byte_order
905 && a.buffer_size == b.buffer_size;
909 bool
910 operator==(const media_multi_audio_info& a, const media_multi_audio_info& b)
912 return a.channel_mask == b.channel_mask
913 && a.valid_bits == b.valid_bits
914 && a.matrix_mask == b.matrix_mask;
918 bool
919 operator==(const media_multi_audio_format& a,
920 const media_multi_audio_format& b)
922 return (media_raw_audio_format)a == (media_raw_audio_format)b
923 && (media_multi_audio_info)a == (media_multi_audio_info)b;
927 bool
928 operator==(const media_encoded_audio_format& a,
929 const media_encoded_audio_format& b)
931 return a.output == b.output
932 && a.encoding == b.encoding
933 && a.bit_rate == b.bit_rate
934 && a.frame_size == b.frame_size
935 && a.multi_info == b.multi_info;
939 bool
940 operator==(const media_video_display_info& a,
941 const media_video_display_info& b)
943 return a.format == b.format
944 && a.line_width == b.line_width
945 && a.line_count == b.line_count
946 && a.bytes_per_row == b.bytes_per_row
947 && a.pixel_offset == b.pixel_offset
948 && a.line_offset == b.line_offset
949 && a.flags == b.flags;
953 bool
954 operator==(const media_raw_video_format& a, const media_raw_video_format& b)
956 return a.field_rate == b.field_rate
957 && a.interlace == b.interlace
958 && a.first_active == b.first_active
959 && a.last_active == b.last_active
960 && a.orientation == b.orientation
961 && a.pixel_width_aspect == b.pixel_width_aspect
962 && a.pixel_height_aspect == b.pixel_height_aspect
963 && a.display == b.display;
967 bool
968 operator==(const media_encoded_video_format& a,
969 const media_encoded_video_format& b)
971 return a.output == b.output
972 && a.avg_bit_rate == b.avg_bit_rate
973 && a.max_bit_rate == b.max_bit_rate
974 && a.encoding == b.encoding
975 && a.frame_size == b.frame_size
976 && a.forward_history == b.forward_history
977 && a.backward_history == b.backward_history;
981 bool
982 operator==(const media_multistream_format::vid_info& a,
983 const media_multistream_format::vid_info& b)
985 return a.frame_rate == b.frame_rate
986 && a.width == b.width
987 && a.height == b.height
988 && a.space == b.space
989 && a.sampling_rate == b.sampling_rate
990 && a.sample_format == b.sample_format
991 && a.byte_order == b.byte_order
992 && a.channel_count == b.channel_count;
996 bool
997 operator==(const media_multistream_format::avi_info& a,
998 const media_multistream_format::avi_info& b)
1000 return a.us_per_frame == b.us_per_frame
1001 && a.width == b.width
1002 && a.height == b.height
1003 && a.type_count == b.type_count
1004 && a.types[0] == b.types[0]
1005 && a.types[1] == b.types[1]
1006 && a.types[2] == b.types[2]
1007 && a.types[3] == b.types[3]
1008 && a.types[4] == b.types[4];
1012 bool
1013 operator==(const media_multistream_format& a,
1014 const media_multistream_format& b)
1016 if (a.avg_bit_rate != b.avg_bit_rate
1017 || a.max_bit_rate != b.max_bit_rate
1018 || a.avg_chunk_size != b.avg_chunk_size
1019 || a.max_chunk_size != b.max_chunk_size
1020 || a.format != b.format
1021 || a.flags != b.flags) {
1022 return false;
1025 switch (a.format) {
1026 case media_multistream_format::B_VID:
1027 return a.u.vid == b.u.vid;
1029 case media_multistream_format::B_AVI:
1030 return a.u.avi == b.u.avi;
1032 default:
1033 return true; // TODO: really?
1038 bool
1039 operator==(const media_format& a, const media_format& b)
1041 if (a.type != b.type
1042 || a.user_data_type != b.user_data_type
1043 // TODO: compare user_data[48] ?
1044 || a.require_flags != b.require_flags
1045 || a.deny_flags != b.deny_flags) {
1046 return false;
1049 switch (a.type) {
1050 case B_MEDIA_RAW_AUDIO:
1051 return a.u.raw_audio == b.u.raw_audio;
1053 case B_MEDIA_RAW_VIDEO:
1054 return a.u.raw_video == b.u.raw_video;
1056 case B_MEDIA_MULTISTREAM:
1057 return a.u.multistream == b.u.multistream;
1059 case B_MEDIA_ENCODED_AUDIO:
1060 return a.u.encoded_audio == b.u.encoded_audio;
1062 case B_MEDIA_ENCODED_VIDEO:
1063 return a.u.encoded_video == b.u.encoded_video;
1065 default:
1066 return true; // TODO: really?
1071 // #pragma mark -
1074 /*! return \c true if a and b are compatible (accounting for wildcards)
1075 a is the format you want to feed to something accepting b
1077 bool
1078 format_is_compatible(const media_format& a, const media_format& b)
1080 return a.Matches(&b);
1084 bool
1085 string_for_format(const media_format& f, char* buf, size_t size)
1087 char encoding[10]; /* maybe Be wanted to use some 4CCs ? */
1088 const char* videoOrientation = "0"; /* I'd use "NC", R5 uses 0. */
1090 if (buf == NULL)
1091 return false;
1092 switch (f.type) {
1093 case B_MEDIA_RAW_AUDIO:
1094 snprintf(buf, size,
1095 "raw_audio;%g;%" B_PRIu32 ";0x%" B_PRIx32 ";%" B_PRIu32 ";0x%"
1096 B_PRIxSIZE ";0x%#" B_PRIx32 ";%d;0x%04x",
1097 f.u.raw_audio.frame_rate,
1098 f.u.raw_audio.channel_count,
1099 f.u.raw_audio.format,
1100 f.u.raw_audio.byte_order,
1101 f.u.raw_audio.buffer_size,
1102 f.u.raw_audio.channel_mask,
1103 f.u.raw_audio.valid_bits,
1104 f.u.raw_audio.matrix_mask);
1105 return true;
1106 case B_MEDIA_RAW_VIDEO:
1107 if (f.u.raw_video.orientation == B_VIDEO_TOP_LEFT_RIGHT)
1108 videoOrientation = "TopLR";
1109 else if (f.u.raw_video.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
1110 videoOrientation = "BotLR";
1111 snprintf(buf, size, "raw_video;%g;0x%x;%" B_PRIu32 ";%" B_PRIu32 ";%"
1112 B_PRIu32 ";%" B_PRIu32 ";%s;%d;%d",
1113 f.u.raw_video.field_rate,
1114 f.u.raw_video.display.format,
1115 f.u.raw_video.interlace,
1116 f.u.raw_video.display.line_width,
1117 f.u.raw_video.display.line_count,
1118 f.u.raw_video.first_active,
1119 videoOrientation,
1120 f.u.raw_video.pixel_width_aspect,
1121 f.u.raw_video.pixel_height_aspect);
1122 return true;
1123 case B_MEDIA_ENCODED_AUDIO:
1124 snprintf(encoding, 10, "%d", f.u.encoded_audio.encoding);
1125 snprintf(buf, size,
1126 "caudio;%s;%g;%ld;(%g;%" B_PRIu32 ";0x%" B_PRIx32 ";%" B_PRIu32
1127 ";0x%" B_PRIxSIZE ";0x%08" B_PRIx32 ";%d;0x%04x)",
1128 encoding,
1129 f.u.encoded_audio.bit_rate,
1130 f.u.encoded_audio.frame_size,
1131 f.u.encoded_audio.output.frame_rate,
1132 f.u.encoded_audio.output.channel_count,
1133 f.u.encoded_audio.output.format,
1134 f.u.encoded_audio.output.byte_order,
1135 f.u.encoded_audio.output.buffer_size,
1136 f.u.encoded_audio.multi_info.channel_mask,
1137 f.u.encoded_audio.multi_info.valid_bits,
1138 f.u.encoded_audio.multi_info.matrix_mask);
1139 return true;
1140 case B_MEDIA_ENCODED_VIDEO:
1141 snprintf(encoding, 10, "%d", f.u.encoded_video.encoding);
1142 if (f.u.encoded_video.output.orientation == B_VIDEO_TOP_LEFT_RIGHT)
1143 videoOrientation = "TopLR";
1144 else if (f.u.encoded_video.output.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT)
1145 videoOrientation = "BotLR";
1146 snprintf(buf, size,
1147 "cvideo;%s;%g;%g;%" B_PRIuSIZE ";(%g;0x%x;%" B_PRIu32 ";%" B_PRIu32
1148 ";%" B_PRIu32 ";%" B_PRIu32 ";%s;%d;%d)",
1149 encoding,
1150 f.u.encoded_video.avg_bit_rate,
1151 f.u.encoded_video.max_bit_rate,
1152 f.u.encoded_video.frame_size,
1153 f.u.encoded_video.output.field_rate,
1154 f.u.encoded_video.output.display.format,
1155 f.u.encoded_video.output.interlace,
1156 f.u.encoded_video.output.display.line_width,
1157 f.u.encoded_video.output.display.line_count,
1158 f.u.encoded_video.output.first_active,
1159 videoOrientation,
1160 f.u.encoded_video.output.pixel_width_aspect,
1161 f.u.encoded_video.output.pixel_height_aspect);
1162 return true;
1163 default:
1164 snprintf(buf, size, "%d-", f.type);
1165 unsigned char* p = (unsigned char*)&(f.u);
1166 size -= strlen(buf);
1167 buf += strlen(buf);
1168 for (int i = 0; (size > 2) && (i < 96); i++) {
1169 snprintf(buf, 3, "%2.2x", *(p + i));
1170 buf+=2;
1171 size-=2;
1173 return true; // ?
1175 return false;
1179 // #pragma mark -
1182 bool
1183 operator==(const media_file_format_id& a, const media_file_format_id& b)
1185 return a.node == b.node && a.device == b.device
1186 && a.internal_id == b.internal_id;
1190 bool
1191 operator<(const media_file_format_id& a, const media_file_format_id& b)
1193 return a.internal_id < b.internal_id;
1197 // #pragma mark -
1200 //! Use this function to iterate through available file format writers.
1201 status_t
1202 get_next_file_format(int32* cookie, media_file_format* mff)
1204 if (cookie == NULL || mff == NULL)
1205 return B_BAD_VALUE;
1207 status_t ret = AddOnManager::GetInstance()->GetFileFormat(mff, *cookie);
1208 if (ret != B_OK)
1209 return ret;
1211 *cookie = *cookie + 1;
1213 return B_OK;
1217 // #pragma mark -
1220 // final & verified
1221 const char* B_MEDIA_SERVER_SIGNATURE = "application/x-vnd.Be.media-server";
1222 const char* B_MEDIA_ADDON_SERVER_SIGNATURE = "application/x-vnd.Be.addon-host";
1224 const type_code B_CODEC_TYPE_INFO = 0x040807b2;
1227 // #pragma mark -
1230 // shutdown_media_server() and launch_media_server()
1231 // are provided by libbe.so in BeOS R5
1233 #define MEDIA_SERVICE_NOTIFICATION_ID "MediaServiceNotificationID"
1236 void
1237 notify_system(float progress, const char* message)
1239 BNotification notification(B_PROGRESS_NOTIFICATION);
1240 notification.SetMessageID(MEDIA_SERVICE_NOTIFICATION_ID);
1241 notification.SetProgress(progress);
1242 notification.SetGroup(B_TRANSLATE("Media Service"));
1243 notification.SetContent(message);
1245 app_info info;
1246 be_app->GetAppInfo(&info);
1247 BBitmap icon(BRect(0, 0, 32, 32), B_RGBA32);
1248 BNode node(&info.ref);
1249 BIconUtils::GetVectorIcon(&node, "BEOS:ICON", &icon);
1250 notification.SetIcon(&icon);
1252 notification.Send();
1256 void
1257 progress_shutdown(int stage,
1258 bool (*progress)(int stage, const char* message, void* cookie),
1259 void* cookie)
1261 // parameter "message" is no longer used. It is kept for compatibility with
1262 // BeOS as this is used as a shutdown_media_server callback.
1264 PRINT(("stage : %i\n", stage));
1265 const char* string = "Unknown stage";
1266 switch (stage) {
1267 case 10:
1268 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS);
1269 break;
1270 case 20:
1271 string = B_TRANSLATE("Telling media_addon_server to quit.");
1272 break;
1273 case 40:
1274 string = B_TRANSLATE("Waiting for media_server to quit.");
1275 break;
1276 case 50:
1277 string = B_TRANSLATE("Waiting for media_server to quit.");
1278 break;
1279 case 70:
1280 string = B_TRANSLATE("Cleaning up.");
1281 break;
1282 case 100:
1283 string = B_TRANSLATE("Done shutting down.");
1284 break;
1287 if (progress == NULL)
1288 notify_system(stage, string);
1289 else
1290 progress(stage, string, cookie);
1294 status_t
1295 shutdown_media_server(bigtime_t timeout,
1296 bool (*progress)(int stage, const char* message, void* cookie),
1297 void* cookie)
1299 BMessage msg(B_QUIT_REQUESTED);
1300 BMessage reply;
1301 status_t err;
1303 if ((err = msg.AddBool("be:_user_request", true)) != B_OK)
1304 return err;
1306 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1307 BMessenger messenger(B_MEDIA_SERVER_SIGNATURE);
1308 progress_shutdown(10, progress, cookie);
1310 err = messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1311 if (err != B_OK)
1312 return err;
1314 int32 rv;
1315 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1316 return rv;
1319 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1320 BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1321 progress_shutdown(20, progress, cookie);
1323 err = messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1324 if (err != B_OK)
1325 return err;
1327 int32 rv;
1328 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK)
1329 return rv;
1332 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1333 progress_shutdown(40, progress, cookie);
1334 snooze(200000);
1337 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1338 progress_shutdown(50, progress, cookie);
1339 snooze(200000);
1342 progress_shutdown(70, progress, cookie);
1343 snooze(1000000);
1345 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1346 kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE));
1349 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1350 kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1353 progress_shutdown(100, progress, cookie);
1354 snooze(1000000);
1356 return B_OK;
1360 void
1361 progress_startup(int stage,
1362 bool (*progress)(int stage, const char* message, void* cookie),
1363 void* cookie)
1365 // parameter "message" is no longer used. It is kept for compatibility with
1366 // BeOS as this is used as a shutdown_media_server callback.
1368 PRINT(("stage : %i\n", stage));
1369 const char* string = "Unknown stage";
1370 switch (stage) {
1371 case 10:
1372 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS);
1373 break;
1374 case 20:
1375 string = B_TRANSLATE("Telling media_addon_server to quit.");
1376 break;
1377 case 50:
1378 string = B_TRANSLATE("Starting media_services.");
1379 break;
1380 case 90:
1381 string = B_TRANSLATE("Error occurred starting media services.");
1382 break;
1383 case 100:
1384 string = B_TRANSLATE("Ready for use.");
1385 break;
1388 if (progress == NULL)
1389 notify_system(stage, string);
1390 else
1391 progress(stage, string, cookie);
1395 status_t
1396 launch_media_server(uint32 flags)
1398 return launch_media_server(0, NULL, NULL, flags);
1402 status_t
1403 launch_media_server(bigtime_t timeout,
1404 bool (*progress)(int stage, const char* message, void* cookie),
1405 void* cookie, uint32 flags)
1407 if (BMediaRoster::IsRunning())
1408 return B_ALREADY_RUNNING;
1410 // The media_server crashed
1411 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) {
1412 progress_startup(10, progress, cookie);
1413 kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE));
1414 snooze(1000000);
1417 // The media_addon_server crashed
1418 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) {
1419 progress_startup(20, progress, cookie);
1420 kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE));
1421 snooze(1000000);
1424 progress_startup(50, progress, cookie);
1426 status_t err = be_roster->Launch(B_MEDIA_SERVER_SIGNATURE);
1427 if (err != B_OK)
1428 return err;
1430 err = B_MEDIA_SYSTEM_FAILURE;
1431 for (int i = 0; i < 15; i++) {
1432 snooze(2000000);
1434 BMessage msg(1); // this is a hack
1435 BMessage reply;
1436 BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE);
1438 if (messenger.IsValid()) {
1439 messenger.SendMessage(&msg, &reply, 2000000, 2000000);
1440 err = B_OK;
1441 progress_startup(100, progress, cookie);
1442 break;
1446 if (err != B_OK)
1447 progress_startup(90, progress, cookie);
1449 return err;
1453 // #pragma mark -
1456 // Given an image_id, prepare that image_id for realtime media
1457 // If the kind of media indicated by "flags" is not enabled for real-time,
1458 // B_MEDIA_REALTIME_DISABLED is returned.
1459 // If there are not enough system resources to enable real-time performance,
1460 // B_MEDIA_REALTIME_UNAVAILABLE is returned.
1461 status_t
1462 media_realtime_init_image(image_id image, uint32 flags)
1464 UNIMPLEMENTED();
1465 return B_OK;
1468 // Given a thread ID, and an optional indication of what the thread is
1469 // doing in "flags", prepare the thread for real-time media performance.
1470 // Currently, this means locking the thread stack, up to size_used bytes,
1471 // or all of it if 0 is passed. Typically, you will not be using all
1472 // 256 kB of the stack, so you should pass some smaller value you determine
1473 // from profiling the thread; typically in the 32-64kB range.
1474 // Return values are the same as for media_prepare_realtime_image().
1475 status_t
1476 media_realtime_init_thread(thread_id thread, size_t stack_used, uint32 flags)
1478 UNIMPLEMENTED();
1479 return B_OK;
1483 // #pragma mark - media_encode_info
1486 media_encode_info::media_encode_info()
1488 flags = 0;
1489 used_data_size = 0;
1490 start_time = 0;
1491 time_to_encode = INT64_MAX;
1492 file_format_data = NULL;
1493 file_format_data_size = 0;
1494 codec_data = NULL;
1495 codec_data_size = 0;
1499 media_decode_info::media_decode_info()
1501 time_to_decode = INT64_MAX;
1502 file_format_data = NULL;
1503 file_format_data_size = 0;
1504 codec_data = NULL;
1505 codec_data_size = 0;