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 <stdio.h> 10 #include <string.h> 11 #include <stdint.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 media_multistream_format of format %d\n", format->format); 521 } 522 } 523 524 static void 525 encoded_audio_format_specialize(media_encoded_audio_format *format, const media_encoded_audio_format *other) 526 { 527 raw_audio_format_specialize(&format->output, &other->output); 528 if (format->encoding == 0) 529 format->encoding = other->encoding; 530 if (format->bit_rate == 0) 531 format->bit_rate = other->bit_rate; 532 if (format->frame_size == 0) 533 format->frame_size = other->frame_size; 534 multi_audio_info_specialize(&format->multi_info, &other->multi_info); 535 } 536 537 static void 538 encoded_video_format_specialize(media_encoded_video_format *format, const media_encoded_video_format *other) 539 { 540 raw_video_format_specialize(&format->output, &other->output); 541 if (format->avg_bit_rate == 0) 542 format->avg_bit_rate = other->avg_bit_rate; 543 if (format->max_bit_rate == 0) 544 format->max_bit_rate = other->max_bit_rate; 545 if (format->encoding == 0) 546 format->encoding = other->encoding; 547 if (format->frame_size == 0) 548 format->frame_size = other->frame_size; 549 if (format->forward_history == 0) 550 format->forward_history = other->forward_history; 551 if (format->backward_history == 0) 552 format->backward_history = other->backward_history; 553 } 554 555 556 /************************************************************* 557 * media_format 558 *************************************************************/ 559 560 bool 561 media_format::Matches(const media_format *other) const 562 { 563 CALLED(); 564 if (type == 0 && other->type == 0) 565 return true; // XXX how do we compare two formats with no type? 566 567 if (type != 0 && other->type != 0 && type != other->type) 568 return false; 569 570 switch ((type != 0) ? type : other->type) { 571 case B_MEDIA_RAW_AUDIO: 572 return multi_audio_format_matches(u.raw_audio, other->u.raw_audio); 573 574 case B_MEDIA_RAW_VIDEO: 575 return raw_video_format_matches(u.raw_video, other->u.raw_video); 576 577 case B_MEDIA_MULTISTREAM: 578 return multistream_format_matches(u.multistream, other->u.multistream); 579 580 case B_MEDIA_ENCODED_AUDIO: 581 return encoded_audio_format_matches(u.encoded_audio, other->u.encoded_audio); 582 583 case B_MEDIA_ENCODED_VIDEO: 584 return encoded_video_format_matches(u.encoded_video, other->u.encoded_video); 585 586 default: 587 return true; // XXX really? 588 } 589 } 590 591 void 592 media_format::SpecializeTo(const media_format *otherFormat) 593 { 594 CALLED(); 595 if (type == 0 && otherFormat->type == 0) { 596 ERROR("media_format::SpecializeTo can't specialize wildcard to other wildcard format\n"); 597 return; 598 } 599 600 if (type == 0) 601 type = otherFormat->type; 602 603 switch (type) { 604 case B_MEDIA_RAW_AUDIO: 605 multi_audio_format_specialize(&u.raw_audio, &otherFormat->u.raw_audio); 606 return; 607 608 case B_MEDIA_RAW_VIDEO: 609 raw_video_format_specialize(&u.raw_video, &otherFormat->u.raw_video); 610 return; 611 612 case B_MEDIA_MULTISTREAM: 613 multistream_format_specialize(&u.multistream, &otherFormat->u.multistream); 614 return; 615 616 case B_MEDIA_ENCODED_AUDIO: 617 encoded_audio_format_specialize(&u.encoded_audio, &otherFormat->u.encoded_audio); 618 return; 619 620 case B_MEDIA_ENCODED_VIDEO: 621 encoded_video_format_specialize(&u.encoded_video, &otherFormat->u.encoded_video); 622 return; 623 624 default: 625 ERROR("media_format::SpecializeTo can't specialize format type %d\n", type); 626 } 627 } 628 629 630 status_t 631 media_format::SetMetaData(const void *data, 632 size_t size) 633 { 634 if (!data || size < 0 || size > META_DATA_MAX_SIZE) 635 return B_BAD_VALUE; 636 637 void *new_addr; 638 area_id new_area; 639 if (size < META_DATA_AREA_MIN_SIZE) { 640 new_area = B_BAD_VALUE; 641 new_addr = malloc(size); 642 if (!new_addr) 643 return B_NO_MEMORY; 644 } else { 645 new_area = create_area("meta_data_area", &new_addr, B_ANY_ADDRESS, ROUND_UP_TO_PAGE(size), 646 B_NO_LOCK, B_READ_AREA | B_WRITE_AREA); 647 if (new_area < 0) 648 return (status_t)new_area; 649 } 650 651 if (meta_data_area > 0) 652 delete_area(meta_data_area); 653 else 654 free(meta_data); 655 656 meta_data = new_addr; 657 meta_data_size = size; 658 meta_data_area = new_area; 659 660 memcpy(meta_data, data, size); 661 662 if (meta_data_area > 0) 663 set_area_protection(meta_data_area, B_READ_AREA); 664 665 return B_OK; 666 } 667 668 669 const void * 670 media_format::MetaData() const 671 { 672 return meta_data; 673 } 674 675 676 int32 677 media_format::MetaDataSize() const 678 { 679 return meta_data_size; 680 } 681 682 683 media_format::media_format() 684 { 685 memset(this, 0x00, sizeof(*this)); 686 meta_data_area = B_BAD_VALUE; 687 } 688 689 690 media_format::media_format(const media_format &other) 691 { 692 memset(this, 0x00, sizeof(*this)); 693 meta_data_area = B_BAD_VALUE; 694 *this = other; 695 } 696 697 698 media_format::~media_format() 699 { 700 if (meta_data_area > 0) 701 delete_area(meta_data_area); 702 else 703 free(meta_data); 704 } 705 706 707 // final 708 media_format & 709 media_format::operator=(const media_format &clone) 710 { 711 // get rid of this format's meta data 712 this->~media_format(); // danger: using only ~media_format() would call the constructor 713 714 // make a binary copy 715 memcpy(this, &clone, sizeof(*this)); 716 // some binary copies are invalid: 717 meta_data = NULL; 718 meta_data_area = B_BAD_VALUE; 719 720 // clone or copy the meta data 721 if (clone.meta_data) { 722 if (clone.meta_data_area) { 723 meta_data_area = clone_area("meta_data_clone_area", &meta_data, 724 B_ANY_ADDRESS, B_READ_AREA, clone.meta_data_area); 725 if (meta_data_area < 0) { 726 // whoops, we just lost our meta data 727 meta_data = NULL; 728 meta_data_size = NULL; 729 } 730 } else { 731 meta_data = malloc(meta_data_size); 732 if (meta_data) { 733 memcpy(meta_data, clone.meta_data, meta_data_size); 734 } else { 735 // whoops, we just lost our meta data 736 meta_data_size = NULL; 737 } 738 } 739 } 740 return *this; 741 } 742 743 /************************************************************* 744 * 745 *************************************************************/ 746 747 748 bool operator==(const media_raw_audio_format & a, const media_raw_audio_format & b) 749 { 750 return ( a.frame_rate == b.frame_rate 751 && a.channel_count == b.channel_count 752 && a.format == b.format 753 && a.byte_order == b.byte_order 754 && a.buffer_size == b.buffer_size); 755 } 756 757 bool operator==(const media_multi_audio_info & a, const media_multi_audio_info & b) 758 { 759 return ( a.channel_mask == b.channel_mask 760 && a.valid_bits == b.valid_bits 761 && a.matrix_mask == b.matrix_mask); 762 } 763 764 bool operator==(const media_multi_audio_format & a, const media_multi_audio_format & b) 765 { 766 return ( (media_raw_audio_format)a == (media_raw_audio_format)b 767 && (media_multi_audio_info)a == (media_multi_audio_info)b); 768 } 769 770 bool operator==(const media_encoded_audio_format & a, const media_encoded_audio_format & b) 771 { 772 return ( a.output == b.output 773 && a.encoding == b.encoding 774 && a.bit_rate == b.bit_rate 775 && a.frame_size == b.frame_size 776 && a.multi_info == b.multi_info); 777 } 778 779 bool operator==(const media_video_display_info & a, const media_video_display_info & b) 780 { 781 return ( a.format == b.format 782 && a.line_width == b.line_width 783 && a.line_count == b.line_count 784 && a.bytes_per_row == b.bytes_per_row 785 && a.pixel_offset == b.pixel_offset 786 && a.line_offset == b.line_offset 787 && a.flags == b.flags); 788 } 789 790 bool operator==(const media_raw_video_format & a, const media_raw_video_format & b) 791 { 792 return ( a.field_rate == b.field_rate 793 && a.interlace == b.interlace 794 && a.first_active == b.first_active 795 && a.last_active == b.last_active 796 && a.orientation == b.orientation 797 && a.pixel_width_aspect == b.pixel_width_aspect 798 && a.pixel_height_aspect == b.pixel_height_aspect 799 && a.display == b.display); 800 } 801 802 bool operator==(const media_encoded_video_format & a, const media_encoded_video_format & b) 803 { 804 return ( a.output == b.output 805 && a.avg_bit_rate == b.avg_bit_rate 806 && a.max_bit_rate == b.max_bit_rate 807 && a.encoding == b.encoding 808 && a.frame_size == b.frame_size 809 && a.forward_history == b.forward_history 810 && a.backward_history == b.backward_history); 811 } 812 813 bool operator==(const media_multistream_format::vid_info & a, const media_multistream_format::vid_info & b) 814 { 815 return ( a.frame_rate == b.frame_rate 816 && a.width == b.width 817 && a.height == b.height 818 && a.space == b.space 819 && a.sampling_rate == b.sampling_rate 820 && a.sample_format == b.sample_format 821 && a.byte_order == b.byte_order 822 && a.channel_count == b.channel_count); 823 } 824 825 bool operator==(const media_multistream_format::avi_info & a, const media_multistream_format::avi_info & b) 826 { 827 return ( a.us_per_frame == b.us_per_frame 828 && a.width == b.width 829 && a.height == b.height 830 && a.type_count == b.type_count 831 && a.types[0] == b.types[0] 832 && a.types[1] == b.types[1] 833 && a.types[2] == b.types[2] 834 && a.types[3] == b.types[3] 835 && a.types[4] == b.types[4]); 836 } 837 838 bool operator==(const media_multistream_format & a, const media_multistream_format & b) 839 { 840 if (a.avg_bit_rate != b.avg_bit_rate 841 || a.max_bit_rate != b.max_bit_rate 842 || a.avg_chunk_size != b.avg_chunk_size 843 || a.max_chunk_size != b.max_chunk_size 844 || a.format != b.format 845 || a.flags != b.flags) 846 return false; 847 848 switch (a.format) { 849 case media_multistream_format::B_VID: 850 return a.u.vid == b.u.vid; 851 852 case media_multistream_format::B_AVI: 853 return a.u.avi == b.u.avi; 854 855 default: 856 return true; // XXX really? 857 } 858 } 859 860 bool operator==(const media_format & a, const media_format & b) 861 { 862 if (a.type != b.type 863 || a.user_data_type != b.user_data_type 864 // XXX compare user_data[48] ? 865 || a.require_flags != b.require_flags 866 || a.deny_flags != b.deny_flags) 867 return false; 868 869 switch (a.type) { 870 case B_MEDIA_RAW_AUDIO: 871 return a.u.raw_audio == b.u.raw_audio; 872 873 case B_MEDIA_RAW_VIDEO: 874 return a.u.raw_video == b.u.raw_video; 875 876 case B_MEDIA_MULTISTREAM: 877 return a.u.multistream == b.u.multistream; 878 879 case B_MEDIA_ENCODED_AUDIO: 880 return a.u.encoded_audio == b.u.encoded_audio; 881 882 case B_MEDIA_ENCODED_VIDEO: 883 return a.u.encoded_video == b.u.encoded_video; 884 885 default: 886 return true; // XXX really? 887 } 888 } 889 890 /************************************************************* 891 * 892 *************************************************************/ 893 894 /* return true if a and b are compatible (accounting for wildcards) */ 895 bool format_is_compatible(const media_format & a, const media_format & b) /* a is the format you want to feed to something accepting b */ 896 { 897 return a.Matches(&b); 898 } 899 900 bool string_for_format(const media_format & f, char * buf, size_t size) 901 { 902 char encoding[10]; /* maybe Be wanted to use some 4CCs ? */ 903 const char *video_orientation = "0"; /* I'd use "NC", R5 uses 0. */ 904 905 if (buf == NULL) 906 return false; 907 switch (f.type) { 908 case B_MEDIA_RAW_AUDIO: 909 snprintf(buf, size, 910 "raw_audio;%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x", 911 f.u.raw_audio.frame_rate, 912 f.u.raw_audio.channel_count, 913 f.u.raw_audio.format, 914 f.u.raw_audio.byte_order, 915 f.u.raw_audio.buffer_size, 916 f.u.raw_audio.channel_mask, 917 f.u.raw_audio.valid_bits, 918 f.u.raw_audio.matrix_mask); 919 return true; 920 case B_MEDIA_RAW_VIDEO: 921 if (f.u.raw_video.orientation == B_VIDEO_TOP_LEFT_RIGHT) 922 video_orientation = "TopLR"; 923 else if (f.u.raw_video.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT) 924 video_orientation = "BotLR"; 925 //snprintf(buf, size, "raw_video;%g;%ld;%ld;%ld;%s;%d;%d;%d;%d;%d;%d;%d;%d", 926 snprintf(buf, size, "raw_video;%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d", 927 f.u.raw_video.field_rate, 928 f.u.raw_video.display.format, 929 f.u.raw_video.interlace, 930 f.u.raw_video.display.line_width, 931 f.u.raw_video.display.line_count, 932 f.u.raw_video.first_active, 933 video_orientation, 934 f.u.raw_video.pixel_width_aspect, 935 f.u.raw_video.pixel_height_aspect); 936 return true; 937 case B_MEDIA_ENCODED_AUDIO: 938 snprintf(encoding, 10, "%d", f.u.encoded_audio.encoding); 939 snprintf(buf, size, 940 "caudio;%s;%g;%ld;(%g;%ld;0x%lx;%ld;0x%lx;0x%08lx;%d;0x%04x)", 941 encoding, // f.u.encoded_audio.encoding, 942 f.u.encoded_audio.bit_rate, 943 f.u.encoded_audio.frame_size, 944 // ( 945 f.u.encoded_audio.output.frame_rate, 946 f.u.encoded_audio.output.channel_count, 947 f.u.encoded_audio.output.format, 948 f.u.encoded_audio.output.byte_order, 949 f.u.encoded_audio.output.buffer_size, 950 f.u.encoded_audio.multi_info.channel_mask, 951 f.u.encoded_audio.multi_info.valid_bits, 952 f.u.encoded_audio.multi_info.matrix_mask); 953 // ) 954 return true; 955 case B_MEDIA_ENCODED_VIDEO: 956 snprintf(encoding, 10, "%d", f.u.encoded_video.encoding); 957 if (f.u.encoded_video.output.orientation == B_VIDEO_TOP_LEFT_RIGHT) 958 video_orientation = "TopLR"; 959 else if (f.u.encoded_video.output.orientation == B_VIDEO_BOTTOM_LEFT_RIGHT) 960 video_orientation = "BotLR"; 961 snprintf(buf, size, 962 "cvideo;%s;%g;%g;%ld;(%g;0x%x;%ld;%ld;%ld;%ld;%s;%d;%d)", 963 encoding, 964 f.u.encoded_video.avg_bit_rate, 965 f.u.encoded_video.max_bit_rate, 966 f.u.encoded_video.frame_size, 967 // ( 968 f.u.encoded_video.output.field_rate, 969 f.u.encoded_video.output.display.format, 970 f.u.encoded_video.output.interlace, 971 f.u.encoded_video.output.display.line_width, 972 f.u.encoded_video.output.display.line_count, 973 f.u.encoded_video.output.first_active, 974 video_orientation, 975 f.u.encoded_video.output.pixel_width_aspect, 976 f.u.encoded_video.output.pixel_height_aspect); 977 // ) 978 return true; 979 default: 980 snprintf(buf, size, "%d-", f.type); 981 unsigned char *p = (unsigned char *)&(f.u); 982 size -= strlen(buf); 983 buf += strlen(buf); 984 for (int i = 0; (size > 2) && (i < 96); i++) { 985 snprintf(buf, 3, "%2.2x", *(p + i)); 986 buf+=2; 987 size-=2; 988 } 989 return true; // ? 990 } 991 return false; 992 } 993 994 /************************************************************* 995 * 996 *************************************************************/ 997 998 bool operator==(const media_file_format_id & a, const media_file_format_id & b) 999 { 1000 UNIMPLEMENTED(); 1001 return false; 1002 } 1003 1004 bool operator<(const media_file_format_id & a, const media_file_format_id & b) 1005 { 1006 UNIMPLEMENTED(); 1007 return false; 1008 } 1009 1010 /************************************************************* 1011 * 1012 *************************************************************/ 1013 1014 // 1015 // Use this function iterate through available file format writers 1016 // 1017 status_t get_next_file_format(int32 *cookie, media_file_format *mfi) 1018 { 1019 UNIMPLEMENTED(); 1020 return B_ERROR; 1021 } 1022 1023 1024 /************************************************************* 1025 * 1026 *************************************************************/ 1027 1028 // final & verified 1029 const char * B_MEDIA_SERVER_SIGNATURE = "application/x-vnd.Be.media-server"; 1030 const char * B_MEDIA_ADDON_SERVER_SIGNATURE = "application/x-vnd.Be.addon-host"; 1031 1032 const type_code B_CODEC_TYPE_INFO = 0x040807b2; 1033 1034 /************************************************************* 1035 * 1036 *************************************************************/ 1037 1038 struct dormant_node_info 1039 { 1040 }; 1041 1042 struct buffer_clone_info 1043 { 1044 }; 1045 1046 /************************************************************* 1047 * 1048 *************************************************************/ 1049 1050 1051 // shutdown_media_server() and launch_media_server() 1052 // are provided by libbe.so in BeOS R5 1053 1054 status_t 1055 shutdown_media_server(bigtime_t timeout, 1056 bool (*progress)(int stage, const char * message, void * cookie), 1057 void * cookie) 1058 { 1059 BMessage msg(B_QUIT_REQUESTED); 1060 BMessage reply; 1061 status_t err; 1062 1063 if ((err = msg.AddBool("be:_user_request", true)) != B_OK) 1064 return err; 1065 1066 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { 1067 BMessenger messenger(B_MEDIA_SERVER_SIGNATURE); 1068 progress(10, "Telling media_server to quit.", cookie); 1069 1070 if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK) 1071 return err; 1072 1073 int32 rv; 1074 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK) 1075 return rv; 1076 } 1077 1078 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { 1079 BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE); 1080 progress(20, "Telling media_addon_server to quit.", cookie); 1081 1082 if ((err = messenger.SendMessage(&msg, &reply, 2000000, 2000000)) != B_OK) 1083 return err; 1084 1085 int32 rv; 1086 if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK) 1087 return rv; 1088 } 1089 1090 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { 1091 progress(40, "Waiting for media_server to quit.", cookie); 1092 snooze(200000); 1093 } 1094 1095 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { 1096 progress(50, "Waiting for media_addon_server to quit.", cookie); 1097 snooze(200000); 1098 } 1099 1100 progress(70, "Cleaning Up.", cookie); 1101 snooze(1000000); 1102 1103 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { 1104 kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE)); 1105 } 1106 1107 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { 1108 kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE)); 1109 } 1110 1111 progress(100, "Done Shutting Down.", cookie); 1112 snooze(1000000); 1113 1114 return B_OK; 1115 } 1116 1117 1118 status_t 1119 launch_media_server(uint32 flags) 1120 { 1121 status_t err; 1122 1123 if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) 1124 return B_ALREADY_RUNNING; 1125 1126 if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { 1127 kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE)); 1128 snooze(1000000); 1129 } 1130 1131 err = be_roster->Launch(B_MEDIA_SERVER_SIGNATURE); 1132 if (err != B_OK) 1133 return err; 1134 1135 err = B_MEDIA_SYSTEM_FAILURE; 1136 for (int i = 0; i < 15; i++) { 1137 snooze(2000000); 1138 1139 BMessage msg(1); // this is a hack 1140 BMessage reply; 1141 BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE); 1142 1143 if (messenger.IsValid()) { 1144 messenger.SendMessage(&msg, &reply, 2000000, 2000000); 1145 err = B_OK; 1146 break; 1147 } 1148 } 1149 1150 return err; 1151 } 1152 1153 1154 /************************************************************* 1155 * 1156 *************************************************************/ 1157 1158 1159 // Given an image_id, prepare that image_id for realtime media 1160 // If the kind of media indicated by "flags" is not enabled for real-time, 1161 // B_MEDIA_REALTIME_DISABLED is returned. 1162 // If there are not enough system resources to enable real-time performance, 1163 // B_MEDIA_REALTIME_UNAVAILABLE is returned. 1164 status_t media_realtime_init_image(image_id image, uint32 flags) 1165 { 1166 UNIMPLEMENTED(); 1167 return B_OK; 1168 } 1169 1170 // Given a thread ID, and an optional indication of what the thread is 1171 // doing in "flags", prepare the thread for real-time media performance. 1172 // Currently, this means locking the thread stack, up to size_used bytes, 1173 // or all of it if 0 is passed. Typically, you will not be using all 1174 // 256 kB of the stack, so you should pass some smaller value you determine 1175 // from profiling the thread; typically in the 32-64kB range. 1176 // Return values are the same as for media_prepare_realtime_image(). 1177 status_t media_realtime_init_thread(thread_id thread, size_t stack_used, uint32 flags) 1178 { 1179 UNIMPLEMENTED(); 1180 return B_OK; 1181 } 1182 1183 /************************************************************* 1184 * media_encode_info 1185 *************************************************************/ 1186 1187 1188 media_encode_info::media_encode_info() 1189 { 1190 flags = 0; 1191 used_data_size = 0; 1192 start_time = 0; 1193 time_to_encode = INT64_MAX; 1194 file_format_data = NULL; 1195 file_format_data_size = 0; 1196 codec_data = NULL; 1197 codec_data_size = 0; 1198 } 1199 1200 1201 media_decode_info::media_decode_info() 1202 { 1203 time_to_decode = INT64_MAX; 1204 file_format_data = NULL; 1205 file_format_data_size = 0; 1206 codec_data = NULL; 1207 codec_data_size = 0; 1208 } 1209 1210 1211