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
54static BCatalog sCatalog("x-vnd.Cortex.support");
55
56// -------------------------------------------------------- //
57// *** media_node strings (public)
58// -------------------------------------------------------- //
59
60BString	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
168BString 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
194BString	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
238BString	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
265BString 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
320BString 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
375BString 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
397BString 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
433BString 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
475BString 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
523BString 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
542BString 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
566BString 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
601BString 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
615BString 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
642BString 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
664BString 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
680BString 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
890BString 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
911BString 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
925BString 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
947BString 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
1045BString 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.SetToFormat(B_TRANSLATE_COMMENT("%" B_PRId32" �� %" B_PRId32,
1058			"The '��' is the Unicode multiplication sign U+00D7"),
1059			lineWidth, lineCount);
1060	return s;
1061}
1062
1063BString MediaString::forVideoFieldRate(
1064	float fieldRate,
1065	uint32 interlace)
1066{
1067	D_METHOD(("MediaString::forVideoFieldRate()\n"));
1068
1069	if (fieldRate == media_raw_video_format::wildcard.field_rate) {
1070		return "*";
1071	}
1072
1073	BString s = "";
1074	if (interlace == 1) {
1075		s << B_TRANSLATE("Non-interlaced ");
1076	}
1077	else {
1078		s << B_TRANSLATE("Interlaced ");
1079	}
1080	s << fieldRate << B_TRANSLATE(" Hz");
1081	if ((fieldRate > 49.9) && (fieldRate < 50.1)) {
1082		s << B_TRANSLATE(" (PAL)");
1083	}
1084	else if (((interlace == 2) && (fieldRate > 59.9) && (fieldRate < 60.0))
1085		  || ((interlace == 1) && (fieldRate > 29.9) && (fieldRate < 30.0))) {
1086		s << B_TRANSLATE(" (NTSC)");
1087	}
1088
1089	return s;
1090}
1091
1092BString MediaString::forVideoOrientation(
1093	uint32 orientation)
1094{
1095	D_METHOD(("MediaString::forVideoOrientation()\n"));
1096
1097	if (orientation == media_raw_video_format::wildcard.orientation) {
1098		return "*";
1099	}
1100
1101	switch (orientation) {
1102		case B_VIDEO_TOP_LEFT_RIGHT: {
1103			return B_TRANSLATE("Top to bottom, left to right");
1104		}
1105		case B_VIDEO_BOTTOM_LEFT_RIGHT: {
1106			return B_TRANSLATE("Bottom to top, left to right");
1107		}
1108		default: {
1109			return B_TRANSLATE("(unkown video orientation)");
1110		}
1111	}
1112}
1113
1114BString MediaString::forVideoAspectRatio(
1115	uint16 pixelWidth,
1116	uint16 pixelHeight)
1117{
1118	D_METHOD(("MediaString::forVideoPixelAspect()\n"));
1119
1120	if ((pixelWidth == media_raw_video_format::wildcard.pixel_width_aspect)
1121	 || (pixelHeight == media_raw_video_format::wildcard.pixel_height_aspect)) {
1122		return "*";
1123	}
1124
1125	BString s = "";
1126	s << static_cast<uint32>(pixelWidth);
1127	s << ":" << static_cast<uint32>(pixelHeight);
1128	return s;
1129}
1130
1131BString MediaString::forVideoActiveLines(
1132	uint32 firstActive,
1133	uint32 lastActive)
1134{
1135	D_METHOD(("MediaString::forVideoActiveLines()\n"));
1136
1137	if ((firstActive == media_raw_video_format::wildcard.first_active)
1138	 || (lastActive == media_raw_video_format::wildcard.last_active)) {
1139	 	return "*";
1140	}
1141
1142	BString s = "";
1143	s.SetToFormat(
1144		B_TRANSLATE("Video data between line %" B_PRIu32 " and %" B_PRIu32),
1145		firstActive, lastActive);
1146	return s;
1147}
1148
1149BString MediaString::forVideoBytesPerRow(
1150	uint32 bytesPerRow)
1151{
1152	D_METHOD(("MediaString::forVideoBytesPerRow()\n"));
1153
1154	if (bytesPerRow == media_video_display_info::wildcard.bytes_per_row) {
1155		return "*";
1156	}
1157
1158	BString s = "";
1159	static BStringFormat format(B_TRANSLATE("{0, plural, one{# byte per row}"
1160			"other{# bytes per row}}"));
1161	format.Format(s, bytesPerRow);
1162	return s;
1163}
1164
1165BString MediaString::forVideoOffset(
1166	uint32 pixelOffset,
1167	uint32 lineOffset)
1168{
1169	D_METHOD(("MediaString::forVideoResolution()\n"));
1170
1171	BString s = "";
1172	if (pixelOffset != media_video_display_info::wildcard.pixel_offset) {
1173		static BStringFormat format(
1174			B_TRANSLATE("{0, plural, one{# pixel} other{# pixels}}"));
1175		format.Format(s, pixelOffset);
1176	}
1177	if (lineOffset != media_video_display_info::wildcard.line_offset) {
1178		if (s != "") {
1179			s << ", ";
1180		}
1181		BString t = "";
1182		static BStringFormat format(
1183			B_TRANSLATE("{0, plural, one{# line} other{# lines}}"));
1184		format.Format(t, lineOffset);
1185		s += t;
1186	}
1187	if (s == "") {
1188		s = "*";
1189	}
1190	return s;
1191}
1192
1193// -------------------------------------------------------- //
1194// *** strings for single fields in media_encoded_video_format
1195// 	   (public)
1196// -------------------------------------------------------- //
1197
1198BString MediaString::forVideoBitRate(
1199	float avgBitRate,
1200	float maxBitRate)
1201{
1202	D_METHOD(("MediaString::forVideoBitRate()\n"));
1203
1204	BString s = "";
1205	if (avgBitRate != media_encoded_video_format::wildcard.avg_bit_rate) {
1206		s << avgBitRate / 1000.0f << B_TRANSLATE(" kb/s (avg)");
1207	}
1208	if (maxBitRate != media_encoded_video_format::wildcard.max_bit_rate) {
1209		if (s != "") {
1210			s << ", ";
1211		}
1212		s << maxBitRate / 1000.0f << B_TRANSLATE(" kb/s (max)");
1213	}
1214	if (s == "") {
1215		s = "*";
1216	}
1217	return s;
1218}
1219
1220BString MediaString::forVideoFrameSize(
1221	size_t frameSize)
1222{
1223	D_METHOD(("MediaString::forVideoFrameSize()\n"));
1224
1225	if (frameSize == media_encoded_video_format::wildcard.frame_size) {
1226		return "*";
1227	}
1228
1229	BString s = "";
1230	static BStringFormat format(B_TRANSLATE("{0, plural,"
1231			"one{# byte per frame}"
1232			"other{# bytes per frame}}"));
1233	format.Format(s, frameSize);
1234	return s;
1235}
1236
1237BString MediaString::forVideoHistory(
1238	int16 forwardHistory,
1239	int16 backwardHistory)
1240{
1241	D_METHOD(("MediaString::forVideoHistory()\n"));
1242
1243	BString s = "";
1244	if (forwardHistory != media_encoded_video_format::wildcard.forward_history) {
1245		static BStringFormat format(B_TRANSLATE("{0, plural,"
1246				"one{# frame forward}"
1247				"other{# frames forward}}"));
1248		format.Format(s, static_cast<int32>(forwardHistory));
1249	}
1250	if (backwardHistory != media_encoded_video_format::wildcard.backward_history) {
1251		if (s != "") {
1252			s << ", ";
1253		}
1254		BString t = "";
1255		static BStringFormat format(B_TRANSLATE("{0, plural,"
1256				"one{# frame backward}"
1257				"other{# frames backward}}"));
1258		format.Format(t, static_cast<int32>(backwardHistory));
1259		s += t;
1260	}
1261	if (s == "") {
1262		s = "*";
1263	}
1264	return s;
1265}
1266
1267// -------------------------------------------------------- //
1268// *** strings for single fields in media_multistream_format
1269// 	   (public)
1270// -------------------------------------------------------- //
1271
1272BString MediaString::forMultistreamFormat(
1273	int32 format)
1274{
1275	D_METHOD(("MediaString::forMultistreamFormat()\n"));
1276
1277	if (format == media_multistream_format::wildcard.format) {
1278		return "*";
1279	}
1280
1281	switch (format) {
1282		case media_multistream_format::B_VID:
1283			return B_TRANSLATE("BeOS video");
1284		case media_multistream_format::B_AVI:
1285			return B_TRANSLATE("AVI");
1286		case media_multistream_format::B_MPEG1:
1287			return B_TRANSLATE("MPEG1");
1288		case media_multistream_format::B_MPEG2:
1289			return B_TRANSLATE("MPEG2");
1290		case media_multistream_format::B_QUICKTIME:
1291			return B_TRANSLATE("QuickTime");
1292		default:
1293			return B_TRANSLATE("(unknown multistream format)");
1294	}
1295}
1296
1297BString MediaString::forMultistreamBitRate(
1298	float avgBitRate,
1299	float maxBitRate)
1300{
1301	D_METHOD(("MediaString::forMultistreamFormat()\n"));
1302
1303	BString s = "";
1304	if (avgBitRate != media_multistream_format::wildcard.avg_bit_rate) {
1305		s << avgBitRate / 1000.0f << B_TRANSLATE(" kb/s (avg)");
1306	}
1307	if (maxBitRate != media_multistream_format::wildcard.max_bit_rate) {
1308		if (s != "") {
1309			s << ", ";
1310		}
1311		s << maxBitRate / 1000.0f << B_TRANSLATE(" kb/s (max)");
1312	}
1313	if (s == "") {
1314		s = "*";
1315	}
1316	return s;
1317}
1318
1319BString MediaString::forMultistreamChunkSize(
1320	uint32 avgChunkSize,
1321	uint32 maxChunkSize)
1322{
1323	D_METHOD(("MediaString::forMultistreamChunkSize()\n"));
1324
1325	BString s = "";
1326	if (avgChunkSize != media_multistream_format::wildcard.avg_chunk_size) {
1327		static BStringFormat format(B_TRANSLATE("{0, plural,"
1328				"one{# byte (avg)}"
1329				"other{# bytes (avg)}}"));
1330		format.Format(s, avgChunkSize);
1331	}
1332	if (maxChunkSize != media_multistream_format::wildcard.max_chunk_size) {
1333		if (s != "") {
1334			s << ", ";
1335		}
1336		static BStringFormat format(B_TRANSLATE("{0, plural,"
1337				"one{# byte (max)}"
1338				"other{# bytes (max)}}"));
1339		format.Format(s, maxChunkSize);
1340	}
1341	if (s == "") {
1342		s = "*";
1343	}
1344	return s;
1345}
1346
1347BString MediaString::forMultistreamFlags(
1348	uint32 flags)
1349{
1350	D_METHOD(("MediaString::forMultistreamFlags()\n"));
1351
1352	BString list, last;
1353	bool first = true;
1354
1355	if (flags & media_multistream_format::B_HEADER_HAS_FLAGS) {
1356		if (first) {
1357			list = B_TRANSLATE("Header has flags");
1358			first = false;
1359		}
1360	}
1361	if (flags & media_multistream_format::B_CLEAN_BUFFERS) {
1362		if (first) {
1363			list = B_TRANSLATE("Clean buffers");
1364			first = false;
1365		}
1366		else {
1367			if (last != "")
1368				list << ", " << last;
1369			last = B_TRANSLATE("Clean buffers");
1370		}
1371	}
1372	if (flags & media_multistream_format::B_HOMOGENOUS_BUFFERS) {
1373		if (first) {
1374			list = B_TRANSLATE("Homogenous buffers");
1375			first = false;
1376		}
1377		else {
1378			if (last != "")
1379				list << ", " << last;
1380			last = B_TRANSLATE("Homogenous buffers");
1381		}
1382	}
1383
1384	if (last != "")
1385		list << " & " << last;
1386
1387	if (list == "")
1388		list = B_TRANSLATE("(none)");
1389
1390	return list;
1391}
1392
1393// END -- MediaString.cpp --
1394