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