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