xref: /haiku/src/apps/cortex/support/MediaString.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
1 /*
2  * Copyright (c) 1999-2000, Eric Moon.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions, and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions, and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 
32 // MediaString.cpp
33 
34 #include "MediaString.h"
35 
36 // Media Kit
37 #include <MediaFormats.h>
38 // Support Kit
39 #include <String.h>
40 
41 __USE_CORTEX_NAMESPACE
42 
43 #include <Debug.h>
44 #define D_METHOD(x) //PRINT (x)
45 
46 // -------------------------------------------------------- //
47 // *** media_node strings (public)
48 // -------------------------------------------------------- //
49 
50 BString	MediaString::getStringFor(
51 	node_kind kinds,
52 	bool complete) {
53 	D_METHOD(("MediaString::getStringFor(node_kind)\n"));
54 
55 	BString list, last;
56 	bool first = true;
57 
58 	if (kinds & B_BUFFER_PRODUCER) {
59 		if (first) {
60 			list = "Buffer producer";
61 			first = false;
62 		}
63 	}
64 	if (kinds & B_BUFFER_CONSUMER) {
65 		if (first) {
66 			list = "Buffer consumer";
67 			first = false;
68 		}
69 		else {
70 			if (last != "")
71 				list << ", " << last;
72 			last = "Buffer consumer";
73 		}
74 	}
75 	if (kinds & B_TIME_SOURCE) {
76 		if (first) {
77 			list = "Time source";
78 			first = false;
79 		}
80 		else {
81 			if (last != "")
82 				list << ", " << last;
83 			last = "Time source";
84 		}
85 	}
86 	if (kinds & B_CONTROLLABLE) {
87 		if (first) {
88 			list = "Controllable";
89 			first = false;
90 		}
91 		else {
92 			if (last != "")
93 				list << ", " << last;
94 			last = "Controllable";
95 		}
96 	}
97 	if (kinds & B_FILE_INTERFACE) {
98 		if (first) {
99 			list = "File interface";
100 			first = false;
101 		}
102 		else {
103 			if (last != "")
104 				list << ", " << last;
105 			last = "File interface";
106 		}
107 	}
108 	if (kinds & B_ENTITY_INTERFACE) {
109 		if (first) {
110 			list = "Entity interface";
111 			first = false;
112 		}
113 		else {
114 			if (last != "")
115 				list << ", " << last;
116 			last = "Entity interface";
117 		}
118 	}
119 	if (kinds & B_PHYSICAL_INPUT) {
120 		if (first) {
121 			list = "Physical input";
122 			first = false;
123 		}
124 		else {
125 			if (last != "")
126 				list << ", " << last;
127 			last = "Physical input";
128 		}
129 	}
130 	if (kinds & B_PHYSICAL_OUTPUT) {
131 		if (first) {
132 			list = "Physical output";
133 			first = false;
134 		}
135 		else {
136 			if (last != "")
137 				list << ", " << last;
138 			last = "Physical output";
139 		}
140 	}
141 	if (kinds & B_SYSTEM_MIXER) {
142 		if (first) {
143 			list = "System mixer";
144 			first = false;
145 		}
146 		else {
147 			if (last != "")
148 				list << ", " << last;
149 			last = "System mixer";
150 		}
151 	}
152 
153 	if (last != "")
154 		list << " & " << last;
155 	return list;
156 }
157 
158 BString MediaString::getStringFor(
159 	BMediaNode::run_mode runMode,
160 	bool complete)
161 {
162 	D_METHOD(("MediaString::getStringFor(run_mode)\n"));
163 
164 	switch (runMode) {
165 		case BMediaNode::B_OFFLINE:				return "Offline";
166 		case BMediaNode::B_RECORDING:			return "Recording";
167 		case BMediaNode::B_DECREASE_PRECISION:	return "Decrease precision";
168 		case BMediaNode::B_INCREASE_LATENCY:	return "Increase latency";
169 		case BMediaNode::B_DROP_DATA:			return "Drop data";
170 		default:								return "(unknown run mode)";
171 	}
172 }
173 
174 // -------------------------------------------------------- //
175 // *** media_format strings (public)
176 // -------------------------------------------------------- //
177 
178 BString	MediaString::getStringFor(
179 	media_type type,
180 	bool complete) {
181 	D_METHOD(("MediaString::getStringFor(media_type)\n"));
182 
183 	switch (type) {
184 		case B_MEDIA_NO_TYPE:			return "Typeless media";
185 		case B_MEDIA_UNKNOWN_TYPE:		return "Unknown media type";
186 		case B_MEDIA_RAW_AUDIO:			return "Raw audio";
187 		case B_MEDIA_RAW_VIDEO:			return "Raw video";
188 		case B_MEDIA_VBL:				return "Raw data from VBL area";
189 		case B_MEDIA_TIMECODE:			return "Timecode";
190 		case B_MEDIA_MIDI:				return "MIDI";
191 		case B_MEDIA_TEXT:				return "Text";
192 		case B_MEDIA_HTML:				return "HTML";
193 		case B_MEDIA_MULTISTREAM:		return "Multistream media";
194 		case B_MEDIA_PARAMETERS:		return "Parameters";
195 		case B_MEDIA_ENCODED_AUDIO:		return "Encoded audio";
196 		case B_MEDIA_ENCODED_VIDEO:		return "Encoded video";
197 		default: {
198 			if (type >= B_MEDIA_FIRST_USER_TYPE)
199 				return "User-defined media type";
200 			if (type >= B_MEDIA_PRIVATE)
201 				return "Private Be media type";
202 		}
203 	}
204 	return "Unknown Media Type";
205 }
206 
207 BString	MediaString::getStringFor(
208 	media_format_family family,
209 	bool complete) {
210 	D_METHOD(("MediaString::getStringFor(media_format_family)\n"));
211 
212 	switch (family) {
213 		case B_ANY_FORMAT_FAMILY:		return "Any format family";
214 		case B_BEOS_FORMAT_FAMILY:		return "BeOS format family";
215 		case B_QUICKTIME_FORMAT_FAMILY:	return "QuickTime format family";
216 		case B_AVI_FORMAT_FAMILY:		return "AVI format family";
217 		case B_ASF_FORMAT_FAMILY:		return "ASF format family";
218 		case B_MPEG_FORMAT_FAMILY:		return "MPEG format family";
219 		case B_WAV_FORMAT_FAMILY:		return "WAV format family";
220 		case B_AIFF_FORMAT_FAMILY:		return "AIFF format family";
221 		default:						return "Miscellaneous format family";
222 	}
223 }
224 
225 BString MediaString::getStringFor(
226 	const media_multi_audio_format &format,
227 	bool complete) {
228 	D_METHOD(("MediaString::getStringFor(media_raw_audio_format)\n"));
229 
230 	BString s = "";
231 	bool empty = true;
232 
233 	// sample rate
234 	if (format.frame_rate != media_raw_audio_format::wildcard.frame_rate) {
235 		s << (empty ? "" : ", ") << forAudioFrameRate(format.frame_rate);
236 		empty = false;
237 	}
238 
239 	// format
240 	if (format.format != media_raw_audio_format::wildcard.format) {
241 		s << (empty ? "" : ", ") << forAudioFormat(format.format, format.valid_bits);
242 		empty = false;
243 	}
244 
245 	// channels
246 	if (format.channel_count != media_raw_audio_format::wildcard.channel_count) {
247 		s << (empty ? "" : ", ") << forAudioChannelCount(format.channel_count);
248 		empty = false;
249 	}
250 
251 	if (complete) {
252 		// channel mask
253 		if (format.channel_mask != media_multi_audio_format::wildcard.channel_mask) {
254 			s << (empty ? "" : " ") << "(" << forAudioChannelMask(format.channel_mask) << ")";
255 			empty = false;
256 		}
257 
258 		// matrix mask
259 		if (format.matrix_mask != media_multi_audio_format::wildcard.matrix_mask) {
260 			s << (empty ? "" : " ") << "(" << forAudioMatrixMask(format.matrix_mask) << ")";
261 			empty = false;
262 		}
263 
264 		// endianess
265 		if (format.byte_order != media_raw_audio_format::wildcard.byte_order) {
266 			s << (empty ? "" : ", ") << forAudioByteOrder(format.byte_order);
267 			empty = false;
268 		}
269 
270 		// buffer size
271 		if (format.buffer_size != media_raw_audio_format::wildcard.buffer_size) {
272 			s << (empty ? "" : ", ") << forAudioBufferSize(format.buffer_size);
273 			empty = false;
274 		}
275 	}
276 
277 	return s;
278 }
279 
280 BString MediaString::getStringFor(
281 	const media_raw_video_format &format,
282 	bool complete) {
283 	D_METHOD(("MediaString::getStringFor(media_raw_video_format)\n"));
284 
285 	BString s = "";
286 	bool empty = true;
287 
288 	// format / color space
289 	if (format.display.format != media_video_display_info::wildcard.format) {
290 		s << (empty ? "" : ", ") << forVideoFormat(format.display.format);
291 		empty = false;
292 	}
293 
294 	// resolution
295 	if ((format.display.line_width != media_video_display_info::wildcard.line_width)
296 	 && (format.display.line_count != media_video_display_info::wildcard.line_count)) {
297 		s << (empty ? "" : ", ") << forVideoResolution(format.display.line_width,
298 													   format.display.line_count);
299 	}
300 
301 	// field rate / interlace
302 	if (format.field_rate != media_raw_video_format::wildcard.field_rate) {
303 		s << (empty ? "" : ", ") << forVideoFieldRate(format.field_rate,
304 													  format.interlace);
305 		empty = false;
306 	}
307 
308 	if (complete) {
309 
310 		// aspect ratio
311 		if ((format.pixel_width_aspect != media_raw_video_format::wildcard.pixel_width_aspect)
312 		 && (format.pixel_height_aspect != media_raw_video_format::wildcard.pixel_height_aspect)) {
313 			s << (empty ? "" : ", ") << forVideoAspectRatio(format.pixel_width_aspect,
314 															format.pixel_height_aspect);
315 			empty = false;
316 		}
317 
318 		// orientation
319 		if (format.orientation != media_raw_video_format::wildcard.orientation) {
320 			s << (empty ? "" : ", ") << forVideoOrientation(format.orientation);
321 			empty = false;
322 		}
323 
324 		// active lines
325 		if ((format.first_active != media_raw_video_format::wildcard.first_active)
326 		 && (format.last_active != media_raw_video_format::wildcard.last_active)) {
327 			s << (empty ? "" : ", ") << forVideoActiveLines(format.first_active,
328 															format.last_active);
329 			empty = false;
330 		}
331 	}
332 	return s;
333 }
334 
335 BString MediaString::getStringFor(
336 	const media_encoded_audio_format &format,
337 	bool complete) {
338 	D_METHOD(("MediaString::getStringFor(media_encoded_audio_format)\n"));
339 
340 	BString s = "";
341 	bool empty = true;
342 
343 	// bit rate
344 	if (format.bit_rate != media_encoded_audio_format::wildcard.bit_rate) {
345 		s << (empty ? "" : ", ") << forAudioBitRate(format.bit_rate);
346 		empty = false;
347 	}
348 
349 	// frame size
350 	if (format.frame_size != media_encoded_audio_format::wildcard.frame_size) {
351 		s << (empty ? "" : ", ") << forAudioFrameSize(format.frame_size);
352 		empty = false;
353 	}
354 	return s;
355 }
356 
357 BString MediaString::getStringFor(
358 	const media_encoded_video_format &format,
359 	bool complete) {
360 	D_METHOD(("MediaString::getStringFor(media_encoded_video_format)\n"));
361 
362 	BString s = "";
363 	bool empty = true;
364 
365 	// bit rate
366 	if ((format.avg_bit_rate != media_encoded_video_format::wildcard.avg_bit_rate)
367 	 && (format.max_bit_rate != media_encoded_video_format::wildcard.max_bit_rate))	{
368 		s << (empty ? "" : ", ") << forVideoBitRate(format.avg_bit_rate,
369 													format.max_bit_rate);
370 		empty = false;
371 	}
372 
373 	if (complete) {
374 
375 		// frame size
376 		if (format.frame_size != media_encoded_video_format::wildcard.frame_size) {
377 			s << (empty ? "" : ", ") << forVideoFrameSize(format.frame_size);
378 			empty = false;
379 		}
380 
381 		// history
382 		if ((format.forward_history != media_encoded_video_format::wildcard.forward_history)
383 		 && (format.backward_history != media_encoded_video_format::wildcard.backward_history)) {
384 			s << (empty ? "" : ", ") << forVideoHistory(format.forward_history,
385 														format.backward_history);
386 			empty = false;
387 		}
388 	}
389 
390 	return s;
391 }
392 
393 BString MediaString::getStringFor(
394 	const media_multistream_format &format,
395 	bool complete) {
396 	D_METHOD(("MediaString::getStringFor(media_multistream_format)\n"));
397 
398 	BString s = "";
399 	bool empty = true;
400 
401 	// format
402 	if (format.format != media_multistream_format::wildcard.format) {
403 		s << (empty ? "" : ", ") << forMultistreamFormat(format.format);
404 		empty = false;
405 	}
406 
407 	// bit rate
408 	if ((format.avg_bit_rate != media_multistream_format::wildcard.avg_bit_rate)
409 	 && (format.max_bit_rate != media_multistream_format::wildcard.max_bit_rate)) {
410 		s << (empty ? "" : ", ") << forMultistreamBitRate(format.avg_bit_rate,
411 														  format.max_bit_rate);
412 		empty = false;
413 	}
414 
415 	if (complete) {
416 
417 		// chunk size
418 		if ((format.avg_chunk_size != media_multistream_format::wildcard.avg_chunk_size)
419 		 && (format.max_chunk_size != media_multistream_format::wildcard.max_chunk_size)) {
420 			s << (empty ? "" : ", ") << forMultistreamChunkSize(format.avg_chunk_size,
421 																format.max_chunk_size);
422 			empty = false;
423 		}
424 
425 		// flags
426 		if (format.flags != media_multistream_format::wildcard.flags) {
427 			s << (empty ? "" : ", ") << forMultistreamFlags(format.flags);
428 			empty = false;
429 		}
430 	}
431 
432 	return s;
433 }
434 
435 BString MediaString::getStringFor(
436 	const media_format &format,
437 	bool complete) {
438 	D_METHOD(("MediaString::getStringFor(media_format)\n"));
439 
440 	BString s = getStringFor(format.type, complete);
441 	switch (format.type) {
442 		case B_MEDIA_RAW_AUDIO:	{
443 			BString formatInfo = getStringFor(format.u.raw_audio, complete);
444 			if (formatInfo.Length() > 0)
445 				s << " (" << formatInfo << ")";
446 			break;
447 		}
448 		case B_MEDIA_RAW_VIDEO:	{
449 			BString formatInfo = getStringFor(format.u.raw_video, complete);
450 			if (formatInfo.Length() > 0)
451 				s << " (" << formatInfo << ")";
452 			break;
453 		}
454 		case B_MEDIA_ENCODED_AUDIO:	{
455 			BString formatInfo = getStringFor(format.u.encoded_audio, complete);
456 			if (formatInfo.Length() > 0)
457 				s << " (" << formatInfo << ")";
458 			break;
459 		}
460 		case B_MEDIA_ENCODED_VIDEO: {
461 			BString formatInfo = getStringFor(format.u.encoded_video, complete);
462 			if (formatInfo.Length() > 0)
463 				s << " (" << formatInfo << ")";
464 			break;
465 		}
466 		case B_MEDIA_MULTISTREAM: {
467 			BString formatInfo = getStringFor(format.u.multistream, complete);
468 			if (formatInfo.Length() > 0)
469 				s << " (" << formatInfo << ")";
470 			break;
471 		}
472 		default: {
473 			break;
474 		}
475 	}
476 	return s;
477 }
478 
479 // -------------------------------------------------------- //
480 // *** media_source / media_destination strings (public)
481 // -------------------------------------------------------- //
482 
483 BString MediaString::getStringFor(
484 	const media_source &source,
485 	bool complete) {
486 	D_METHOD(("MediaString::getStringFor(media_source)\n"));
487 
488 	BString s;
489 	if ((source.port != media_source::null.port)
490 	 && (source.id != media_source::null.id)) {
491 		s << "Port " << source.port << ", ID " << source.id;
492 	}
493 	else {
494 		s = "(none)";
495 	}
496 	return s;
497 }
498 
499 BString MediaString::getStringFor(
500 	const media_destination &destination,
501 	bool complete) {
502 	D_METHOD(("MediaString::getStringFor(media_destination)\n"));
503 
504 	BString s;
505 	if ((destination.port != media_destination::null.port)
506 	 && (destination.id != media_destination::null.id)) {
507 		s << "Port " << destination.port << ", ID " << destination.id;
508 	}
509 	else {
510 		s = "(none)";
511 	}
512 	return s;
513 }
514 
515 // -------------------------------------------------------- //
516 // *** strings for single fields in media_raw_audio_format
517 // 	   (public)
518 // -------------------------------------------------------- //
519 
520 BString MediaString::forAudioFormat(
521 	uint32 format,
522 	int32 validBits) {
523 	D_METHOD(("MediaString::forAudioFormat()\n"));
524 
525 	if (format == media_raw_audio_format::wildcard.format) {
526 		return "*";
527 	}
528 
529 	switch (format) {
530 		case media_raw_audio_format::B_AUDIO_UCHAR: {
531 			return "8 bit integer";
532 		}
533 		case media_raw_audio_format::B_AUDIO_SHORT:	{
534 			return "16 bit integer";
535 		}
536 		case media_raw_audio_format::B_AUDIO_FLOAT:	{
537 			return "32 bit float";
538 		}
539 		case media_raw_audio_format::B_AUDIO_INT: {
540 			BString s = "";
541 			if (validBits != media_multi_audio_format::wildcard.valid_bits)
542 				s << validBits << " bit ";
543 			else
544 				s << "32 bit ";
545 			s << "integer";
546 			return s;
547 		}
548 		default: {
549 			return "(unknown format)";
550 		}
551 	}
552 }
553 
554 BString MediaString::forAudioFrameRate(
555 	float frameRate)
556 {
557 	D_METHOD(("MediaString::forAudioFrameRate()\n"));
558 
559 	if (frameRate == media_raw_audio_format::wildcard.frame_rate) {
560 		return "*";
561 	}
562 
563 	BString s;
564 	s << (frameRate / 1000) << " kHz";
565 	return s;
566 }
567 
568 BString MediaString::forAudioChannelCount(
569 	uint32 channelCount)
570 {
571 	D_METHOD(("MediaString::forAudioChannelCount()\n"));
572 
573 	if (channelCount == media_raw_audio_format::wildcard.channel_count) {
574 		return "*";
575 	}
576 
577 	switch (channelCount) {
578 		case 1: {
579 			return "Mono";
580 		}
581 		case 2: {
582 			return "Stereo";
583 		}
584 		default: {
585 			BString s = "";
586 			s << channelCount << " Channels";
587 			return s;
588 		}
589 	}
590 }
591 
592 BString MediaString::forAudioByteOrder(
593 	uint32 byteOrder)
594 {
595 	D_METHOD(("MediaString::forAudioByteOrder()\n"));
596 
597 	if (byteOrder == media_raw_audio_format::wildcard.byte_order) {
598 		return "*";
599 	}
600 
601 	switch (byteOrder) {
602 		case B_MEDIA_BIG_ENDIAN: {
603 			return "Big endian";
604 		}
605 		case B_MEDIA_LITTLE_ENDIAN: {
606 			return "Little endian";
607 		}
608 		default: {
609 			return "(unknown byte order)";
610 		}
611 	}
612 }
613 
614 BString MediaString::forAudioBufferSize(
615 	size_t bufferSize)
616 {
617 	D_METHOD(("MediaString::forAudioBufferSize()\n"));
618 
619 	if (bufferSize == media_raw_audio_format::wildcard.buffer_size) {
620 		return "*";
621 	}
622 
623 	BString s = "";
624 	s << bufferSize << " bytes per buffer";
625 	return s;
626 }
627 
628 BString MediaString::forAudioChannelMask(
629 	uint32 channelMask) {
630 	D_METHOD(("MediaString::forAudioChannelMask()\n"));
631 
632 	BString list, last;
633 	bool first = true;
634 
635 	if (channelMask & B_CHANNEL_LEFT) {
636 		if (first) {
637 			list = "Left";
638 			first = false;
639 		}
640 	}
641 	if (channelMask & B_CHANNEL_RIGHT) {
642 		if (first) {
643 			list = "Right";
644 			first = false;
645 		}
646 		else {
647 			if (last != "")
648 				list << ", " << last;
649 			last = "Right";
650 		}
651 	}
652 	if (channelMask & B_CHANNEL_CENTER) {
653 		if (first) {
654 			list = "Center";
655 			first = false;
656 		}
657 		else {
658 			if (last != "")
659 				list << ", " << last;
660 			last = "Center";
661 		}
662 	}
663 	if (channelMask & B_CHANNEL_SUB) {
664 		if (first) {
665 			list = "Sub";
666 			first = false;
667 		}
668 		else {
669 			if (last != "")
670 				list << ", " << last;
671 			last = "Sub";
672 		}
673 	}
674 	if (channelMask & B_CHANNEL_REARLEFT) {
675 		if (first) {
676 			list = "Rear-left";
677 			first = false;
678 		}
679 		else {
680 			if (last != "")
681 				list << ", " << last;
682 			last = "Rear-left";
683 		}
684 	}
685 	if (channelMask & B_CHANNEL_REARRIGHT) {
686 		if (first) {
687 			list = "Rear-right";
688 			first = false;
689 		}
690 		else {
691 			if (last != "")
692 				list << ", " << last;
693 			last = "Rear-right";
694 		}
695 	}
696 	if (channelMask & B_CHANNEL_FRONT_LEFT_CENTER) {
697 		if (first) {
698 			list = "Front-left-center";
699 			first = false;
700 		}
701 		else {
702 			if (last != "")
703 				list << ", " << last;
704 			last = "Front-left-center";
705 		}
706 	}
707 	if (channelMask & B_CHANNEL_FRONT_RIGHT_CENTER) {
708 		if (first) {
709 			list = "Front-right-center";
710 			first = false;
711 		}
712 		else {
713 			if (last != "")
714 				list << ", " << last;
715 			last = "Front-right-center";
716 		}
717 	}
718 	if (channelMask & B_CHANNEL_BACK_CENTER) {
719 		if (first) {
720 			list = "Back-center";
721 			first = false;
722 		}
723 		else {
724 			if (last != "")
725 				list << ", " << last;
726 			last = "Back-center";
727 		}
728 	}
729 	if (channelMask & B_CHANNEL_SIDE_LEFT) {
730 		if (first) {
731 			list = "Side-left";
732 			first = false;
733 		}
734 		else {
735 			if (last != "")
736 				list << ", " << last;
737 			last = "Side-left";
738 		}
739 	}
740 	if (channelMask & B_CHANNEL_SIDE_RIGHT) {
741 		if (first) {
742 			list = "Side-right";
743 			first = false;
744 		}
745 		else {
746 			if (last != "")
747 				list << ", " << last;
748 			last = "Side-right";
749 		}
750 	}
751 	if (channelMask & B_CHANNEL_TOP_CENTER) {
752 		if (first) {
753 			list = "Top-center";
754 			first = false;
755 		}
756 		else {
757 			if (last != "")
758 				list << ", " << last;
759 			last = "Top-center";
760 		}
761 	}
762 	if (channelMask & B_CHANNEL_TOP_FRONT_LEFT) {
763 		if (first) {
764 			list = "Top-Front-left";
765 			first = false;
766 		}
767 		else {
768 			if (last != "")
769 				list << ", " << last;
770 			last = "Top-Front-left";
771 		}
772 	}
773 	if (channelMask & B_CHANNEL_TOP_FRONT_CENTER) {
774 		if (first) {
775 			list = "Top-Front-center";
776 			first = false;
777 		}
778 		else {
779 			if (last != "")
780 				list << ", " << last;
781 			last = "Top-Front-center";
782 		}
783 	}
784 	if (channelMask & B_CHANNEL_TOP_FRONT_RIGHT) {
785 		if (first) {
786 			list = "Top-Front-right";
787 			first = false;
788 		}
789 		else {
790 			if (last != "")
791 				list << ", " << last;
792 			last = "Top-Front-right";
793 		}
794 	}
795 	if (channelMask & B_CHANNEL_TOP_BACK_LEFT) {
796 		if (first) {
797 			list = "Top-Back-left";
798 			first = false;
799 		}
800 		else {
801 			if (last != "")
802 				list << ", " << last;
803 			last = "Top-Back-left";
804 		}
805 	}
806 	if (channelMask & B_CHANNEL_TOP_BACK_CENTER) {
807 		if (first) {
808 			list = "Top-Back-center";
809 			first = false;
810 		}
811 		else {
812 			if (last != "")
813 				list << ", " << last;
814 			last = "Top-Back-center";
815 		}
816 	}
817 	if (channelMask & B_CHANNEL_TOP_BACK_RIGHT) {
818 		if (first) {
819 			list = "Top-Back-right";
820 			first = false;
821 		}
822 		else {
823 			if (last != "")
824 				list << ", " << last;
825 			last = "Top-Back-right";
826 		}
827 	}
828 	if (last != "") {
829 		list << " & " << last;
830 	}
831 	if (list == "") {
832 		list = "(none)";
833 	}
834 
835 	return list;
836 }
837 
838 BString MediaString::forAudioMatrixMask(
839 	uint16 matrixMask) {
840 	D_METHOD(("MediaString::forAudioMatrixMask()\n"));
841 
842 	switch (matrixMask) {
843 		case 0:									return "(none)";
844 		case B_MATRIX_PROLOGIC_LR:				return "ProLogic LR";
845 		case B_MATRIX_AMBISONIC_WXYZ:			return "Ambisonic WXYZ";
846 		default:								return "(unknown matrix mask)";
847 	}
848 }
849 
850 // -------------------------------------------------------- //
851 // *** strings for single fields in media_encoded_audio_format
852 // 	   (public)
853 // -------------------------------------------------------- //
854 
855 BString MediaString::forAudioBitRate(
856 	float bitRate)
857 {
858 	D_METHOD(("MediaString::forAudioBufferSize()\n"));
859 
860 	if (bitRate == media_encoded_audio_format::wildcard.bit_rate) {
861 		return "*";
862 	}
863 
864 	BString s = "";
865 	s << bitRate / 1000.0f << " kb/s";
866 	return s;
867 }
868 
869 BString MediaString::forAudioFrameSize(
870 	size_t frameSize)
871 {
872 	D_METHOD(("MediaString::forAudioFrameSize()\n"));
873 
874 	if (frameSize == media_encoded_audio_format::wildcard.frame_size) {
875 		return "*";
876 	}
877 
878 	BString s = "";
879 	s << frameSize << " bytes per frame";
880 	return s;
881 }
882 
883 // -------------------------------------------------------- //
884 // *** strings for single fields in media_raw_video_format
885 // 	   (public)
886 // -------------------------------------------------------- //
887 
888 BString MediaString::forVideoFormat(
889 	color_space format)
890 {
891 	D_METHOD(("MediaString::forVideoFormat()\n"));
892 
893 	if (format == media_video_display_info::wildcard.format) {
894 		return "*";
895 	}
896 
897 	switch (format) {
898 		case B_RGB32:
899 		case B_RGB32_BIG: 		return "32 bit RGB";
900 		case B_RGBA32:
901 		case B_RGBA32_BIG:		return "32 bit RGBA";
902 		case B_RGB24:
903 		case B_RGB24_BIG:		return "24 bit RGB";
904 		case B_RGB16:
905 		case B_RGB16_BIG:		return "16 bit RGB";
906 		case B_RGB15:
907 		case B_RGB15_BIG:		return "15 bit RGB";
908 		case B_RGBA15:
909 		case B_RGBA15_BIG:		return "15 bit RGBA";
910 		case B_CMAP8:			return "8 bit color-index";
911 		case B_GRAY8:			return "8 bit grayscale-index";
912 		case B_GRAY1:			return "Monochrome";
913 		case B_YUV422:			return "YUV422";
914 		case B_YUV411:			return "YUV411";
915 		case B_YUV420:			return "YUV420";
916 		case B_YUV444:			return "YUV444";
917 		case B_YUV9:			return "YUV9";
918 		case B_YUV12:			return "YUV12";
919 		case B_YCbCr422:		return "YCbCr422";
920 		case B_YCbCr411:		return "YCbCr411";
921 		case B_YCbCr444:		return "YCbCr444";
922 		case B_YCbCr420:		return "YCbCr420";
923 		case B_UVL24:			return "24 bit UVL";
924 		case B_UVL32:			return "32 bit UVL";
925 		case B_UVLA32:			return "32 bit UVLA";
926 		case B_LAB24:			return "24 bit LAB";
927 		case B_LAB32:			return "32 bit LAB";
928 		case B_LABA32:			return "32 bit LABA";
929 		case B_HSI24:			return "24 bit HSI";
930 		case B_HSI32:			return "32 bit HSI";
931 		case B_HSIA32:			return "32 bit HSIA";
932 		case B_HSV24:			return "24 bit HSV";
933 		case B_HSV32:			return "32 bit HSV";
934 		case B_HSVA32:			return "32 bit HSVA";
935 		case B_HLS24:			return "24 bit HLS";
936 		case B_HLS32:			return "32 bit HLS";
937 		case B_HLSA32:			return "32 bit HLSA";
938 		case B_CMY24:			return "24 bit CMY";
939 		case B_CMY32:			return "32 bit CMY";
940 		case B_CMYA32:			return "32 bit CMYA";
941 		case B_CMYK32:			return "32 bit CMYK";
942 		default: {
943 			return "(unknown video format)";
944 		}
945 	}
946 }
947 
948 BString MediaString::forVideoResolution(
949 	uint32 lineWidth,
950 	uint32 lineCount)
951 {
952 	D_METHOD(("MediaString::forVideoResolution()\n"));
953 
954 	if ((lineWidth == media_video_display_info::wildcard.line_width)
955 	 || (lineCount == media_video_display_info::wildcard.line_count)) {
956 		return "*";
957 	}
958 
959 	BString s = "";
960 	s << lineWidth << " x " << lineCount;
961 	return s;
962 }
963 
964 BString MediaString::forVideoFieldRate(
965 	float fieldRate,
966 	uint32 interlace)
967 {
968 	D_METHOD(("MediaString::forVideoFieldRate()\n"));
969 
970 	if (fieldRate == media_raw_video_format::wildcard.field_rate) {
971 		return "*";
972 	}
973 
974 	BString s = "";
975 	if (interlace == 1) {
976 		s << "Non-interlaced ";
977 	}
978 	else {
979 		s << "Interlaced ";
980 	}
981 	s << fieldRate << " Hz";
982 	if ((fieldRate > 49.9) && (fieldRate < 50.1)) {
983 		s << " (PAL)";
984 	}
985 	else if (((interlace == 2) && (fieldRate > 59.9) && (fieldRate < 60.0))
986 		  || ((interlace == 1) && (fieldRate > 29.9) && (fieldRate < 30.0))) {
987 		s << " (NTSC)";
988 	}
989 
990 	return s;
991 }
992 
993 BString MediaString::forVideoOrientation(
994 	uint32 orientation)
995 {
996 	D_METHOD(("MediaString::forVideoOrientation()\n"));
997 
998 	if (orientation == media_raw_video_format::wildcard.orientation) {
999 		return "*";
1000 	}
1001 
1002 	switch (orientation) {
1003 		case B_VIDEO_TOP_LEFT_RIGHT: {
1004 			return "Top to bottom, left to right";
1005 		}
1006 		case B_VIDEO_BOTTOM_LEFT_RIGHT: {
1007 			return "Bottom to top, left to right";
1008 		}
1009 		default: {
1010 			return "(unkown video orientation)";
1011 		}
1012 	}
1013 }
1014 
1015 BString MediaString::forVideoAspectRatio(
1016 	uint16 pixelWidth,
1017 	uint16 pixelHeight)
1018 {
1019 	D_METHOD(("MediaString::forVideoPixelAspect()\n"));
1020 
1021 	if ((pixelWidth == media_raw_video_format::wildcard.pixel_width_aspect)
1022 	 || (pixelHeight == media_raw_video_format::wildcard.pixel_height_aspect)) {
1023 		return "*";
1024 	}
1025 
1026 	BString s = "";
1027 	s << static_cast<uint32>(pixelWidth);
1028 	s << ":" << static_cast<uint32>(pixelHeight);
1029 	return s;
1030 }
1031 
1032 BString MediaString::forVideoActiveLines(
1033 	uint32 firstActive,
1034 	uint32 lastActive)
1035 {
1036 	D_METHOD(("MediaString::forVideoActiveLines()\n"));
1037 
1038 	if ((firstActive == media_raw_video_format::wildcard.first_active)
1039 	 || (lastActive == media_raw_video_format::wildcard.last_active)) {
1040 	 	return "*";
1041 	}
1042 
1043 	BString s = "Video data between";
1044 	s << " line " << firstActive;
1045 	s << " and " << lastActive;
1046 	return s;
1047 }
1048 
1049 BString MediaString::forVideoBytesPerRow(
1050 	uint32 bytesPerRow)
1051 {
1052 	D_METHOD(("MediaString::forVideoBytesPerRow()\n"));
1053 
1054 	if (bytesPerRow == media_video_display_info::wildcard.bytes_per_row) {
1055 		return "*";
1056 	}
1057 
1058 	BString s = "";
1059 	s << bytesPerRow << " bytes per row";
1060 	return s;
1061 }
1062 
1063 BString MediaString::forVideoOffset(
1064 	uint32 pixelOffset,
1065 	uint32 lineOffset)
1066 {
1067 	D_METHOD(("MediaString::forVideoResolution()\n"));
1068 
1069 	BString s = "";
1070 	if (pixelOffset != media_video_display_info::wildcard.pixel_offset) {
1071 		s << pixelOffset << " pixels";
1072 	}
1073 	if (lineOffset != media_video_display_info::wildcard.line_offset) {
1074 		if (s != "") {
1075 			s << ", ";
1076 		}
1077 		s << pixelOffset << " lines";
1078 	}
1079 	if (s == "") {
1080 		s = "*";
1081 	}
1082 	return s;
1083 }
1084 
1085 // -------------------------------------------------------- //
1086 // *** strings for single fields in media_encoded_video_format
1087 // 	   (public)
1088 // -------------------------------------------------------- //
1089 
1090 BString MediaString::forVideoBitRate(
1091 	float avgBitRate,
1092 	float maxBitRate)
1093 {
1094 	D_METHOD(("MediaString::forVideoBitRate()\n"));
1095 
1096 	BString s = "";
1097 	if (avgBitRate != media_encoded_video_format::wildcard.avg_bit_rate) {
1098 		s << avgBitRate / 1000.0f << " kb/s (avg)";
1099 	}
1100 	if (maxBitRate != media_encoded_video_format::wildcard.max_bit_rate) {
1101 		if (s != "") {
1102 			s << ", ";
1103 		}
1104 		s << maxBitRate / 1000.0f << " kb/s (max)";
1105 	}
1106 	if (s == "") {
1107 		s = "*";
1108 	}
1109 	return s;
1110 }
1111 
1112 BString MediaString::forVideoFrameSize(
1113 	size_t frameSize)
1114 {
1115 	D_METHOD(("MediaString::forVideoFrameSize()\n"));
1116 
1117 	if (frameSize == media_encoded_video_format::wildcard.frame_size) {
1118 		return "*";
1119 	}
1120 
1121 	BString s = "";
1122 	s << frameSize << " bytes per frame";
1123 	return s;
1124 }
1125 
1126 BString MediaString::forVideoHistory(
1127 	int16 forwardHistory,
1128 	int16 backwardHistory)
1129 {
1130 	D_METHOD(("MediaString::forVideoHistory()\n"));
1131 
1132 	BString s = "";
1133 	if (forwardHistory != media_encoded_video_format::wildcard.forward_history) {
1134 		s << static_cast<int32>(forwardHistory) << " frames forward";
1135 	}
1136 	if (backwardHistory != media_encoded_video_format::wildcard.backward_history) {
1137 		if (s != "") {
1138 			s << ", ";
1139 		}
1140 		s << static_cast<int32>(backwardHistory) << " frames backward";
1141 	}
1142 	if (s == "") {
1143 		s = "*";
1144 	}
1145 	return s;
1146 }
1147 
1148 // -------------------------------------------------------- //
1149 // *** strings for single fields in media_multistream_format
1150 // 	   (public)
1151 // -------------------------------------------------------- //
1152 
1153 BString MediaString::forMultistreamFormat(
1154 	int32 format)
1155 {
1156 	D_METHOD(("MediaString::forMultistreamFormat()\n"));
1157 
1158 	if (format == media_multistream_format::wildcard.format) {
1159 		return "*";
1160 	}
1161 
1162 	switch (format) {
1163 		case media_multistream_format::B_VID:		return "BeOS video";
1164 		case media_multistream_format::B_AVI:		return "AVI";
1165 		case media_multistream_format::B_MPEG1:		return "MPEG1";
1166 		case media_multistream_format::B_MPEG2:		return "MPEG2";
1167 		case media_multistream_format::B_QUICKTIME:	return "QuickTime";
1168 		default:									return "(unknown multistream format)";
1169 	}
1170 }
1171 
1172 BString MediaString::forMultistreamBitRate(
1173 	float avgBitRate,
1174 	float maxBitRate)
1175 {
1176 	D_METHOD(("MediaString::forMultistreamFormat()\n"));
1177 
1178 	BString s = "";
1179 	if (avgBitRate != media_multistream_format::wildcard.avg_bit_rate) {
1180 		s << avgBitRate / 1000.0f << " kb/s (avg)";
1181 	}
1182 	if (maxBitRate != media_multistream_format::wildcard.max_bit_rate) {
1183 		if (s != "") {
1184 			s << ", ";
1185 		}
1186 		s << maxBitRate / 1000.0f << " kb/s (max)";
1187 	}
1188 	if (s == "") {
1189 		s = "*";
1190 	}
1191 	return s;
1192 }
1193 
1194 BString MediaString::forMultistreamChunkSize(
1195 	uint32 avgChunkSize,
1196 	uint32 maxChunkSize)
1197 {
1198 	D_METHOD(("MediaString::forMultistreamChunkSize()\n"));
1199 
1200 	BString s = "";
1201 	if (avgChunkSize != media_multistream_format::wildcard.avg_chunk_size) {
1202 		s << avgChunkSize << " bytes (avg)";
1203 	}
1204 	if (maxChunkSize != media_multistream_format::wildcard.max_chunk_size) {
1205 		if (s != "") {
1206 			s << ", ";
1207 		}
1208 		s << maxChunkSize << " bytes (max)";
1209 	}
1210 	if (s == "") {
1211 		s = "*";
1212 	}
1213 	return s;
1214 }
1215 
1216 BString MediaString::forMultistreamFlags(
1217 	uint32 flags)
1218 {
1219 	D_METHOD(("MediaString::forMultistreamFlags()\n"));
1220 
1221 	BString list, last;
1222 	bool first = true;
1223 
1224 	if (flags & media_multistream_format::B_HEADER_HAS_FLAGS) {
1225 		if (first) {
1226 			list = "Header has flags";
1227 			first = false;
1228 		}
1229 	}
1230 	if (flags & media_multistream_format::B_CLEAN_BUFFERS) {
1231 		if (first) {
1232 			list = "Clean buffers";
1233 			first = false;
1234 		}
1235 		else {
1236 			if (last != "")
1237 				list << ", " << last;
1238 			last = "Clean buffers";
1239 		}
1240 	}
1241 	if (flags & media_multistream_format::B_HOMOGENOUS_BUFFERS) {
1242 		if (first) {
1243 			list = "Homogenous buffers";
1244 			first = false;
1245 		}
1246 		else {
1247 			if (last != "")
1248 				list << ", " << last;
1249 			last = "Homogenous buffers";
1250 		}
1251 	}
1252 
1253 	if (last != "")
1254 		list << " & " << last;
1255 
1256 	if (list == "")
1257 		list = "(none)";
1258 
1259 	return list;
1260 }
1261 
1262 // END -- MediaString.cpp --
1263