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