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