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