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