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// MediaFormatIO.cpp
33// e.moon 2jul99
34
35#include "MediaFormatIO.h"
36//#include "xml_export_utils.h"
37
38__USE_CORTEX_NAMESPACE
39
40// -------------------------------------------------------- //
41// *** constants
42// -------------------------------------------------------- //
43
44// these tags map directly to MediaFormatIO
45const char* const MediaFormatIO::s_multi_audio_tag 			= "multi_audio_format";
46const char* const MediaFormatIO::s_raw_audio_tag 				= "raw_audio_format";
47const char* const MediaFormatIO::s_raw_video_tag 				= "raw_video_format";
48const char* const MediaFormatIO::s_multistream_tag 			= "multistream_format";
49const char* const MediaFormatIO::s_encoded_audio_tag 		= "encoded_audio_format";
50const char* const MediaFormatIO::s_encoded_video_tag 		= "encoded_video_format";
51
52// nested tags
53const char* const MediaFormatIO::s_video_display_info_tag		= "video_display_info";
54const char* const MediaFormatIO::s_multistream_flags_tag			= "multistream_flags";
55const char* const MediaFormatIO::s_multistream_vid_info_tag	= "multistream_vid_info";
56const char* const MediaFormatIO::s_multistream_avi_info_tag	= "multistream_avi_info";
57const char* const MediaFormatIO::s_multi_audio_info_tag			= "multi_audio_info";
58const char* const MediaFormatIO::s_media_type_tag						= "media_type";
59
60// -------------------------------------------------------- //
61// *** ctor/dtor
62// -------------------------------------------------------- //
63
64MediaFormatIO::~MediaFormatIO() {}
65
66MediaFormatIO::MediaFormatIO() :
67	m_complete(false) {}
68MediaFormatIO::MediaFormatIO(const media_format& format) :
69	m_complete(true),
70	m_format(format) {}
71
72// -------------------------------------------------------- //
73// *** accessors
74// -------------------------------------------------------- //
75
76// returns B_OK if the object contains a valid format,
77// or B_ERROR if not.
78
79status_t MediaFormatIO::getFormat(media_format& outFormat) const {
80	if(!m_complete)
81		return B_ERROR;
82	outFormat = m_format;
83	return B_OK;
84}
85
86// -------------------------------------------------------- //
87// *** static setup method
88// -------------------------------------------------------- //
89
90// call this method to install hooks for the tags needed by
91// MediaFormatIO
92
93/*static*/
94void MediaFormatIO::AddTo(XML::DocumentType* pDocType) {
95
96	pDocType->addMapping(new Mapping
97		<MediaFormatIO>(s_multi_audio_tag));
98	pDocType->addMapping(new Mapping
99		<MediaFormatIO>(s_raw_audio_tag));
100	pDocType->addMapping(new Mapping
101		<MediaFormatIO>(s_raw_video_tag));
102	pDocType->addMapping(new Mapping
103		<MediaFormatIO>(s_multistream_tag));
104	pDocType->addMapping(new Mapping
105		<MediaFormatIO>(s_encoded_audio_tag));
106	pDocType->addMapping(new Mapping
107		<MediaFormatIO>(s_encoded_video_tag));
108}
109
110// -------------------------------------------------------- //
111// *** IPersistent
112// -------------------------------------------------------- //
113
114// -------------------------------------------------------- //
115// attribute constants
116// -------------------------------------------------------- //
117
118// *** raw_audio_format
119const char* const gKey_frame_rate							= "frame_rate";
120const char* const gKey_channel_count					= "channel_count";
121const char* const gKey_format									= "format";
122const char* const gKey_byte_order							= "byte_order";
123const char* const gKey_buffer_size						= "buffer_size";
124
125// *** +multi_audio_format
126const char* const gKey_channel_mask						= "channel_mask";
127const char* const gKey_valid_bits							= "valid_bits";
128const char* const gKey_matrix_mask						= "matrix_mask";
129
130// *** raw_video_format
131const char* const gKey_field_rate							= "field_rate";
132const char* const gKey_interlace							= "interlace";
133const char* const gKey_first_active						= "first_active";
134const char* const gKey_last_active						= "last_active";
135const char* const gKey_orientation						= "orientation";
136const char* const gKey_pixel_width_aspect			= "pixel_width_aspect";
137const char* const gKey_pixel_height_aspect		= "pixel_height_aspect";
138
139// *** video_display_info
140const char* const gKey_color_space						= "color_space";
141const char* const gKey_line_width							= "line_width";
142const char* const gKey_line_count							= "line_count";
143const char* const gKey_bytes_per_row					= "bytes_per_row";
144const char* const gKey_pixel_offset						= "pixel_offset";
145const char* const gKey_line_offset						= "line_offset";
146
147// *** multistream_format
148const char* const gKey_multistream_format			= "format";
149const char* const gKey_avg_bit_rate						= "avg_bit_rate";
150const char* const gKey_max_bit_rate						= "max_bit_rate";
151const char* const gKey_avg_chunk_size					= "avg_chunk_size";
152const char* const gKey_max_chunk_size					= "max_chunk_size";
153
154// *** multistream_flags
155const char* const gKey_header_has_flags				= "header_has_flags";
156const char* const gKey_clean_buffers					= "clean_buffers";
157const char* const gKey_homogenous_buffers			= "homogenous_buffers";
158
159// *** multistream_vid_info
160// frame_rate
161const char* const gKey_width									= "width";
162const char* const gKey_height									= "height";
163const char* const gKey_space									= "space";
164const char* const gKey_sampling_rate					= "sampling_rate";
165const char* const gKey_sample_format					= "sample_format";
166// byte_order
167// channel_count
168
169// *** multistream_avi_info
170const char* const gKey_us_per_frame						= "us_per_frame";
171// width
172// height
173
174// *** encoded_audio_format
175const char* const gKey_encoding								= "encoding";
176const char* const gKey_bit_rate								= "bit_rate";
177const char* const gKey_frame_size							= "frame_size";
178
179// *** encoded_video_format
180// encoding
181// avg_bit_rate
182// max_bit_rate
183// frame_size
184const char* const gKey_forward_history				= "forward_history";
185const char* const gKey_backward_history				= "backward_history";
186
187// padding (number of spaces allowed for attribute name)
188const int16 g_padAttributes		= 30;
189
190// -------------------------------------------------------- //
191// export
192// -------------------------------------------------------- //
193
194void write_colorspace_attr(
195	const char* key,
196	color_space c,
197	ExportContext& context) {
198
199	switch(c) {
200		case B_RGB32:
201			context.writeAttr(key, "B_RGB32");
202			break;
203		case B_RGBA32:
204			context.writeAttr(key, "B_RGBA32");
205			break;
206		case B_RGB24:
207			context.writeAttr(key, "B_RGB24");
208			break;
209		case B_RGB16:
210			context.writeAttr(key, "B_RGB16");
211			break;
212		case B_RGB15:
213			context.writeAttr(key, "B_RGB15");
214			break;
215		case B_RGBA15:
216			context.writeAttr(key, "B_RGBA15");
217			break;
218		case B_CMAP8:
219			context.writeAttr(key, "B_CMAP8");
220			break;
221		case B_GRAY8:
222			context.writeAttr(key, "B_GRAY8");
223			break;
224		case B_GRAY1:
225			context.writeAttr(key, "B_GRAY1");
226			break;
227		case B_RGB32_BIG:
228			context.writeAttr(key, "B_RGB32_BIG");
229			break;
230		case B_RGBA32_BIG:
231			context.writeAttr(key, "B_RGBA32_BIG");
232			break;
233		case B_RGB24_BIG:
234			context.writeAttr(key, "B_RGB24_BIG");
235			break;
236		case B_RGB16_BIG:
237			context.writeAttr(key, "B_RGB16_BIG");
238			break;
239		case B_RGB15_BIG:
240			context.writeAttr(key, "B_RGB15_BIG");
241			break;
242		case B_RGBA15_BIG:
243			context.writeAttr(key, "B_RGBA15_BIG");
244			break;
245		case B_YCbCr422:
246			context.writeAttr(key, "B_YCbCr422");
247			break;
248		case B_YCbCr411:
249			context.writeAttr(key, "B_YCbCr411");
250			break;
251		case B_YCbCr444:
252			context.writeAttr(key, "B_YCbCr444");
253			break;
254		case B_YCbCr420:
255			context.writeAttr(key, "B_YCbCr420");
256			break;
257		case B_YUV422:
258			context.writeAttr(key, "B_YUV422");
259			break;
260		case B_YUV411:
261			context.writeAttr(key, "B_YUV411");
262			break;
263		case B_YUV444:
264			context.writeAttr(key, "B_YUV444");
265			break;
266		case B_YUV420:
267			context.writeAttr(key, "B_YUV420");
268			break;
269		case B_YUV9:
270			context.writeAttr(key, "B_YUV9");
271			break;
272		case B_YUV12:
273			context.writeAttr(key, "B_YUV12");
274			break;
275		case B_UVL24:
276			context.writeAttr(key, "B_UVL24");
277			break;
278		case B_UVL32:
279			context.writeAttr(key, "B_UVL32");
280			break;
281		case B_UVLA32:
282			context.writeAttr(key, "B_UVLA32");
283			break;
284		case B_LAB24:
285			context.writeAttr(key, "B_LAB24");
286			break;
287		case B_LAB32:
288			context.writeAttr(key, "B_LAB32");
289			break;
290		case B_LABA32:
291			context.writeAttr(key, "B_LABA32");
292			break;
293		case B_HSI24:
294			context.writeAttr(key, "B_HSI24");
295			break;
296		case B_HSI32:
297			context.writeAttr(key, "B_HSI32");
298			break;
299		case B_HSIA32:
300			context.writeAttr(key, "B_HSIA32");
301			break;
302		case B_HSV24:
303			context.writeAttr(key, "B_HSV24");
304			break;
305		case B_HSV32:
306			context.writeAttr(key, "B_HSV32");
307			break;
308		case B_HSVA32:
309			context.writeAttr(key, "B_HSVA32");
310			break;
311		case B_HLS24:
312			context.writeAttr(key, "B_HLS24");
313			break;
314		case B_HLS32:
315			context.writeAttr(key, "B_HLS32");
316			break;
317		case B_HLSA32:
318			context.writeAttr(key, "B_HLSA32");
319			break;
320		case B_CMY24:
321			context.writeAttr(key, "B_CMY24");
322			break;
323		case B_CMY32:
324			context.writeAttr(key, "B_CMY32");
325			break;
326		case B_CMYA32:
327			context.writeAttr(key, "B_CMYA32");
328			break;
329		case B_CMYK32:
330			context.writeAttr(key, "B_CMYK32");
331			break;
332		default:
333			break;
334	}
335}
336
337void import_color_space(
338	const char* value,
339	color_space& dest) {
340
341	if(!strcmp(value, "B_RGB32"))
342		dest = B_RGB32;
343	else if(!strcmp(value, "B_RGBA32"))
344		dest = B_RGBA32;
345	else if(!strcmp(value, "B_RGB24"))
346		dest = B_RGB24;
347	else if(!strcmp(value, "B_RGB16"))
348		dest = B_RGB16;
349	else if(!strcmp(value, "B_RGB15"))
350		dest = B_RGB15;
351	else if(!strcmp(value, "B_RGBA15"))
352		dest = B_RGBA15;
353	else if(!strcmp(value, "B_CMAP8"))
354		dest = B_CMAP8;
355	else if(!strcmp(value, "B_GRAY8"))
356		dest = B_GRAY8;
357	else if(!strcmp(value, "B_GRAY1"))
358		dest = B_GRAY1;
359	else if(!strcmp(value, "B_RGB32_BIG"))
360		dest = B_RGB32_BIG;
361	else if(!strcmp(value, "B_RGBA32_BIG"))
362		dest = B_RGBA32_BIG;
363	else if(!strcmp(value, "B_RGB24_BIG"))
364		dest = B_RGB24_BIG;
365	else if(!strcmp(value, "B_RGB16_BIG"))
366		dest = B_RGB16_BIG;
367	else if(!strcmp(value, "B_RGB15_BIG"))
368		dest = B_RGB15_BIG;
369	else if(!strcmp(value, "B_RGBA15_BIG"))
370		dest = B_RGBA15_BIG;
371	else if(!strcmp(value, "B_RGB32_LITTLE"))
372		dest = B_RGB32_LITTLE;
373	else if(!strcmp(value, "B_RGBA32_LITTLE"))
374		dest = B_RGBA32_LITTLE;
375	else if(!strcmp(value, "B_RGB24_LITTLE"))
376		dest = B_RGB24_LITTLE;
377	else if(!strcmp(value, "B_RGB16_LITTLE"))
378		dest = B_RGB16_LITTLE;
379	else if(!strcmp(value, "B_RGB15_LITTLE"))
380		dest = B_RGB15_LITTLE;
381	else if(!strcmp(value, "B_RGBA15_LITTLE"))
382		dest = B_RGBA15_LITTLE;
383	else if(!strcmp(value, "B_YCbCr422"))
384		dest = B_YCbCr422;
385	else if(!strcmp(value, "B_YCbCr411"))
386		dest = B_YCbCr411;
387	else if(!strcmp(value, "B_YCbCr444"))
388		dest = B_YCbCr444;
389	else if(!strcmp(value, "B_YCbCr420"))
390		dest = B_YCbCr420;
391	else if(!strcmp(value, "B_YUV422"))
392		dest = B_YUV422;
393	else if(!strcmp(value, "B_YUV411"))
394		dest = B_YUV411;
395	else if(!strcmp(value, "B_YUV444"))
396		dest = B_YUV444;
397	else if(!strcmp(value, "B_YUV420"))
398		dest = B_YUV420;
399	else if(!strcmp(value, "B_YUV9"))
400		dest = B_YUV9;
401	else if(!strcmp(value, "B_YUV12"))
402		dest = B_YUV12;
403	else if(!strcmp(value, "B_UVL24"))
404		dest = B_UVL24;
405	else if(!strcmp(value, "B_UVL32"))
406		dest = B_UVL32;
407	else if(!strcmp(value, "B_UVLA32"))
408		dest = B_UVLA32;
409	else if(!strcmp(value, "B_LAB24"))
410		dest = B_LAB24;
411	else if(!strcmp(value, "B_LAB32"))
412		dest = B_LAB32;
413	else if(!strcmp(value, "B_LABA32"))
414		dest = B_LABA32;
415	else if(!strcmp(value, "B_HSI24"))
416		dest = B_HSI24;
417	else if(!strcmp(value, "B_HSI32"))
418		dest = B_HSI32;
419	else if(!strcmp(value, "B_HSIA32"))
420		dest = B_HSIA32;
421	else if(!strcmp(value, "B_HSV24"))
422		dest = B_HSV24;
423	else if(!strcmp(value, "B_HSV32"))
424		dest = B_HSV32;
425	else if(!strcmp(value, "B_HSVA32"))
426		dest = B_HSVA32;
427	else if(!strcmp(value, "B_HLS24"))
428		dest = B_HLS24;
429	else if(!strcmp(value, "B_HLS32"))
430		dest = B_HLS32;
431	else if(!strcmp(value, "B_HLSA32"))
432		dest = B_HLSA32;
433	else if(!strcmp(value, "B_CMY24"))
434		dest = B_CMY24;
435	else if(!strcmp(value, "B_CMY32"))
436		dest = B_CMY32;
437	else if(!strcmp(value, "B_CMYA32"))
438		dest = B_CMYA32;
439	else if(!strcmp(value, "B_CMYK32"))
440		dest = B_CMYK32;
441}
442
443void write_media_type(
444	media_type t,
445	ExportContext& context) {
446
447	context.beginElement(MediaFormatIO::s_media_type_tag);
448	context.beginContent();
449
450	switch(t) {
451		case B_MEDIA_NO_TYPE:
452			context.writeString("B_MEDIA_NO_TYPE");
453			break;
454		case B_MEDIA_UNKNOWN_TYPE:
455			context.writeString("B_MEDIA_UNKNOWN_TYPE");
456			break;
457		case B_MEDIA_RAW_AUDIO:
458			context.writeString("B_MEDIA_RAW_AUDIO");
459			break;
460		case B_MEDIA_RAW_VIDEO:
461			context.writeString("B_MEDIA_RAW_VIDEO");
462			break;
463		case B_MEDIA_VBL:
464			context.writeString("B_MEDIA_VBL");
465			break;
466		case B_MEDIA_TIMECODE:
467			context.writeString("B_MEDIA_TIMECODE");
468			break;
469		case B_MEDIA_MIDI:
470			context.writeString("B_MEDIA_MIDI");
471			break;
472		case B_MEDIA_TEXT:
473			context.writeString("B_MEDIA_TEXT");
474			break;
475		case B_MEDIA_HTML:
476			context.writeString("B_MEDIA_HTML");
477			break;
478		case B_MEDIA_MULTISTREAM:
479			context.writeString("B_MEDIA_MULTISTREAM");
480			break;
481		case B_MEDIA_PARAMETERS:
482			context.writeString("B_MEDIA_PARAMETERS");
483			break;
484		case B_MEDIA_ENCODED_AUDIO:
485			context.writeString("B_MEDIA_ENCODED_AUDIO");
486			break;
487		case B_MEDIA_ENCODED_VIDEO:
488			context.writeString("B_MEDIA_ENCODED_VIDEO");
489			break;
490		default: {
491			BString val;
492			val << (uint32)t;
493			context.writeString(val);
494		}
495	}
496	context.endElement();
497}
498
499void import_media_type_content(
500	media_multistream_format::avi_info& f,
501	const char* value,
502	ImportContext& context) {
503
504	if(f.type_count == 5) {
505		// ignore
506		// +++++ should this be an error?
507		context.reportWarning("Ignoring media_type: maximum of 5 reached.");
508		return;
509	}
510
511	if(!strcmp(value, "B_MEDIA_NO_TYPE"))
512		f.types[f.type_count] = B_MEDIA_NO_TYPE;
513	else if(!strcmp(value, "B_MEDIA_UNKNOWN_TYPE"))
514		f.types[f.type_count] = B_MEDIA_UNKNOWN_TYPE;
515	else if(!strcmp(value, "B_MEDIA_RAW_AUDIO"))
516		f.types[f.type_count] = B_MEDIA_RAW_AUDIO;
517	else if(!strcmp(value, "B_MEDIA_RAW_VIDEO"))
518		f.types[f.type_count] = B_MEDIA_RAW_VIDEO;
519	else if(!strcmp(value, "B_MEDIA_VBL"))
520		f.types[f.type_count] = B_MEDIA_VBL;
521	else if(!strcmp(value, "B_MEDIA_TIMECODE"))
522		f.types[f.type_count] = B_MEDIA_TIMECODE;
523	else if(!strcmp(value, "B_MEDIA_MIDI"))
524		f.types[f.type_count] = B_MEDIA_MIDI;
525	else if(!strcmp(value, "B_MEDIA_TEXT"))
526		f.types[f.type_count] = B_MEDIA_TEXT;
527	else if(!strcmp(value, "B_MEDIA_HTML"))
528		f.types[f.type_count] = B_MEDIA_HTML;
529	else if(!strcmp(value, "B_MEDIA_MULTISTREAM"))
530		f.types[f.type_count] = B_MEDIA_MULTISTREAM;
531	else if(!strcmp(value, "B_MEDIA_PARAMETERS"))
532		f.types[f.type_count] = B_MEDIA_PARAMETERS;
533	else if(!strcmp(value, "B_MEDIA_ENCODED_AUDIO"))
534		f.types[f.type_count] = B_MEDIA_ENCODED_AUDIO;
535	else if(!strcmp(value, "B_MEDIA_ENCODED_VIDEO"))
536		f.types[f.type_count] = B_MEDIA_ENCODED_VIDEO;
537	else
538		f.types[f.type_count] = (media_type)atol(value);
539
540	++f.type_count;
541}
542
543
544void export_raw_audio_attr(
545	const media_raw_audio_format& f,
546	ExportContext& context) {
547
548	const media_raw_audio_format& w = media_raw_audio_format::wildcard;
549
550	if(f.frame_rate != w.frame_rate)
551		context.writeAttr(gKey_frame_rate, f.frame_rate);
552	if(f.channel_count != w.channel_count)
553		context.writeAttr(gKey_channel_count, f.channel_count);
554	if(f.buffer_size != w.buffer_size)
555		context.writeAttr(gKey_buffer_size, f.buffer_size);
556
557	switch(f.format) {
558		case media_raw_audio_format::B_AUDIO_UCHAR:
559			context.writeAttr(gKey_format, "B_AUDIO_UCHAR");
560			break;
561		case media_raw_audio_format::B_AUDIO_SHORT:
562			context.writeAttr(gKey_format, "B_AUDIO_SHORT");
563			break;
564		case media_raw_audio_format::B_AUDIO_FLOAT:
565			context.writeAttr(gKey_format, "B_AUDIO_FLOAT");
566			break;
567		case media_raw_audio_format::B_AUDIO_INT:
568			context.writeAttr(gKey_format, "B_AUDIO_INT");
569			break;
570		default:
571			break;
572	}
573
574	switch(f.byte_order) {
575		case B_MEDIA_BIG_ENDIAN:
576			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
577			break;
578		case B_MEDIA_LITTLE_ENDIAN:
579			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
580			break;
581		default:
582			break;
583	}
584}
585
586void export_multi_audio_info_attr(
587	const media_multi_audio_info& f,
588	ExportContext& context) {
589
590	const media_multi_audio_format& w = media_multi_audio_format::wildcard;
591
592	if(f.channel_mask != w.channel_mask)
593		context.writeAttr(gKey_channel_mask, f.channel_mask);
594
595	if(f.valid_bits != w.valid_bits)
596		context.writeAttr(gKey_valid_bits, f.valid_bits);
597
598	if(f.matrix_mask != w.matrix_mask)
599		context.writeAttr(gKey_matrix_mask, f.matrix_mask);
600}
601
602void export_video_display_info_attr(
603	const media_video_display_info& d,
604	ExportContext& context) {
605
606	const media_video_display_info& w = media_video_display_info::wildcard;
607
608	if(d.line_width != w.line_width)
609		context.writeAttr(gKey_line_width, d.line_width);
610	if(d.line_count != w.line_count)
611		context.writeAttr(gKey_line_count, d.line_count);
612	if(d.bytes_per_row != w.bytes_per_row)
613		context.writeAttr(gKey_bytes_per_row, d.bytes_per_row);
614	if(d.pixel_offset != w.pixel_offset)
615		context.writeAttr(gKey_pixel_offset, d.pixel_offset);
616	if(d.line_offset != w.line_offset)
617		context.writeAttr(gKey_line_offset, d.line_offset);
618
619	if(d.format != w.format)
620		write_colorspace_attr(gKey_format, d.format, context);
621}
622
623
624void export_raw_video_attr(
625	const media_raw_video_format& f,
626	ExportContext& context) {
627
628	const media_raw_video_format& w = media_raw_video_format::wildcard;
629
630	// attributes
631	if(f.field_rate != w.field_rate)
632		context.writeAttr(gKey_field_rate, f.field_rate);
633	if(f.interlace != w.interlace)
634		context.writeAttr(gKey_interlace, f.interlace);
635	if(f.first_active != w.first_active)
636		context.writeAttr(gKey_first_active, f.first_active);
637	if(f.last_active != w.last_active)
638		context.writeAttr(gKey_last_active, f.last_active);
639	if(f.pixel_width_aspect != w.pixel_width_aspect)
640		context.writeAttr(gKey_pixel_width_aspect, (uint32)f.pixel_width_aspect);
641	if(f.pixel_height_aspect != w.pixel_height_aspect)
642		context.writeAttr(gKey_pixel_height_aspect, (uint32)f.pixel_height_aspect);
643
644	switch(f.orientation) {
645		case B_VIDEO_TOP_LEFT_RIGHT:
646			context.writeAttr(gKey_orientation, "B_VIDEO_TOP_LEFT_RIGHT");
647			break;
648		case B_VIDEO_BOTTOM_LEFT_RIGHT:
649			context.writeAttr(gKey_orientation, "B_VIDEO_BOTTOM_LEFT_RIGHT");
650			break;
651		default:
652			break;
653	}
654}
655
656void export_raw_video_content(
657	const media_raw_video_format& f,
658	ExportContext& context) {
659
660	context.beginContent();
661	context.beginElement(MediaFormatIO::s_video_display_info_tag);
662	export_video_display_info_attr(f.display, context);
663	context.endElement();
664}
665
666void export_multistream_flags_attr(
667	uint32 flags,
668	ExportContext& context) {
669
670	if(flags & media_multistream_format::B_HEADER_HAS_FLAGS)
671		context.writeAttr(gKey_header_has_flags, (int32)1);
672
673	if(flags & media_multistream_format::B_CLEAN_BUFFERS)
674		context.writeAttr(gKey_clean_buffers, (int32)1);
675
676	if(flags & media_multistream_format::B_HOMOGENOUS_BUFFERS)
677		context.writeAttr(gKey_homogenous_buffers, (int32)1);
678}
679
680void export_multistream_vid_info_attr(
681	media_multistream_format::vid_info f,
682	ExportContext& context) {
683
684	// +++++ no wildcard to compare against (assume 0 == wildcard?)
685
686	context.writeAttr(gKey_frame_rate, f.frame_rate);
687	context.writeAttr(gKey_width, (uint32)f.width);
688	context.writeAttr(gKey_height, (uint32)f.height);
689	write_colorspace_attr(gKey_space, f.space, context);
690	context.writeAttr(gKey_sampling_rate, f.sampling_rate);
691
692	switch(f.sample_format) {
693		case B_UNDEFINED_SAMPLES:
694			context.writeAttr(gKey_sample_format, "B_UNDEFINED_SAMPLES");
695			break;
696		case B_LINEAR_SAMPLES:
697			context.writeAttr(gKey_sample_format, "B_LINEAR_SAMPLES");
698			break;
699		case B_FLOAT_SAMPLES:
700			context.writeAttr(gKey_sample_format, "B_FLOAT_SAMPLES");
701			break;
702		case B_MULAW_SAMPLES:
703			context.writeAttr(gKey_sample_format, "B_MULAW_SAMPLES");
704			break;
705		default:
706			break;
707	}
708
709	switch(f.byte_order) {
710		case B_MEDIA_BIG_ENDIAN:
711			context.writeAttr(gKey_byte_order, "B_MEDIA_BIG_ENDIAN");
712			break;
713		case B_MEDIA_LITTLE_ENDIAN:
714			context.writeAttr(gKey_byte_order, "B_MEDIA_LITTLE_ENDIAN");
715			break;
716		default:
717			break;
718	}
719
720	context.writeAttr(gKey_channel_count, (uint32)f.channel_count);
721}
722
723void export_multistream_avi_info_attr(
724	media_multistream_format::avi_info f,
725	ExportContext& context) {
726
727	context.writeAttr(gKey_us_per_frame, f.us_per_frame);
728	context.writeAttr(gKey_width, (uint32)f.width);
729	context.writeAttr(gKey_height, (uint32)f.height);
730}
731
732void export_multistream_avi_info_content(
733	media_multistream_format::avi_info f,
734	ExportContext& context) {
735
736	context.beginContent();
737
738	for(uint16 n = 0; n < f.type_count; ++n)
739		write_media_type(f.types[n], context);
740}
741
742void export_multistream_attr(
743	const media_multistream_format& f,
744	ExportContext& context) {
745
746	const media_multistream_format& w = media_multistream_format::wildcard;
747
748	// attributes
749	switch(f.format) {
750		case media_multistream_format::B_ANY:
751			context.writeAttr(gKey_multistream_format, "B_ANY");
752			break;
753		case media_multistream_format::B_VID:
754			context.writeAttr(gKey_multistream_format, "B_VID");
755			break;
756		case media_multistream_format::B_AVI:
757			context.writeAttr(gKey_multistream_format, "B_AVI");
758			break;
759		case media_multistream_format::B_MPEG1:
760			context.writeAttr(gKey_multistream_format, "B_MPEG1");
761			break;
762		case media_multistream_format::B_MPEG2:
763			context.writeAttr(gKey_multistream_format, "B_MPEG2");
764			break;
765		case media_multistream_format::B_QUICKTIME:
766			context.writeAttr(gKey_multistream_format, "B_QUICKTIME");
767			break;
768		default:
769			if(f.format != w.format) {
770				// write numeric value
771				context.writeAttr(gKey_multistream_format, f.format);
772			}
773			break;
774	}
775
776	if(f.avg_bit_rate != w.avg_bit_rate)
777		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
778	if(f.max_bit_rate != w.max_bit_rate)
779		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
780	if(f.avg_chunk_size != w.avg_chunk_size)
781		context.writeAttr(gKey_avg_chunk_size, f.avg_chunk_size);
782	if(f.max_chunk_size != w.max_chunk_size)
783		context.writeAttr(gKey_max_chunk_size, f.max_chunk_size);
784}
785
786void export_multistream_content(
787	const media_multistream_format& f,
788	ExportContext& context) {
789
790	context.beginContent();
791
792	// write flags
793	context.beginElement(MediaFormatIO::s_multistream_flags_tag);
794	export_multistream_flags_attr(f.flags, context);
795	context.endElement();
796
797	// write format-specific info
798	if(f.format == media_multistream_format::B_VID) {
799		context.beginElement(MediaFormatIO::s_multistream_vid_info_tag);
800		export_multistream_vid_info_attr(f.u.vid, context);
801		context.endElement();
802	}
803	else if(f.format == media_multistream_format::B_AVI) {
804		context.beginElement(MediaFormatIO::s_multistream_avi_info_tag);
805		export_multistream_avi_info_attr(f.u.avi, context);
806		context.beginContent();
807		export_multistream_avi_info_content(f.u.avi, context);
808		context.endElement();
809	}
810}
811
812void export_encoded_audio_attr(
813	const media_encoded_audio_format& f,
814	ExportContext& context) {
815
816	const media_encoded_audio_format& w = media_encoded_audio_format::wildcard;
817
818	switch(f.encoding) {
819		case media_encoded_audio_format::B_ANY:
820			context.writeAttr(gKey_encoding, "B_ANY");
821			break;
822		default:
823			break;
824	}
825
826	if(f.bit_rate != w.bit_rate)
827		context.writeAttr(gKey_bit_rate, f.bit_rate);
828
829	if(f.frame_size != w.frame_size)
830		context.writeAttr(gKey_frame_size, f.frame_size);
831}
832
833void export_encoded_audio_content(
834	const media_encoded_audio_format& f,
835	ExportContext& context) {
836
837	context.beginContent();
838
839	context.beginElement(MediaFormatIO::s_raw_audio_tag);
840	export_raw_audio_attr(f.output, context);
841
842	export_multi_audio_info_attr(f.multi_info, context);
843
844	context.endElement();
845}
846
847void export_encoded_video_attr(
848	const media_encoded_video_format& f,
849	ExportContext& context) {
850
851	const media_encoded_video_format& w = media_encoded_video_format::wildcard;
852
853	switch(f.encoding) {
854		case media_encoded_video_format::B_ANY:
855			context.writeAttr(gKey_encoding, "B_ANY");
856			break;
857		default:
858			break;
859	}
860
861	if(f.avg_bit_rate != w.avg_bit_rate)
862		context.writeAttr(gKey_avg_bit_rate, f.avg_bit_rate);
863	if(f.max_bit_rate != w.max_bit_rate)
864		context.writeAttr(gKey_max_bit_rate, f.max_bit_rate);
865	if(f.frame_size != w.frame_size)
866		context.writeAttr(gKey_frame_size, f.frame_size);
867	if(f.forward_history != w.forward_history)
868		context.writeAttr(gKey_forward_history, (int32)f.forward_history);
869	if(f.backward_history != w.backward_history)
870		context.writeAttr(gKey_backward_history, (int32)f.backward_history);
871}
872
873void export_encoded_video_content(
874	const media_encoded_video_format& f,
875	ExportContext& context) {
876
877	context.beginContent();
878
879	context.beginElement(MediaFormatIO::s_raw_video_tag);
880	export_raw_video_attr(f.output, context);
881	context.endElement();
882}
883
884
885void MediaFormatIO::xmlExportBegin(
886	ExportContext&		context) const {
887
888	switch(m_format.type) {
889
890		case B_MEDIA_RAW_AUDIO:
891			context.beginElement(s_raw_audio_tag);
892			break;
893
894		case B_MEDIA_RAW_VIDEO:
895			context.beginElement(s_raw_video_tag);
896			break;
897
898		case B_MEDIA_MULTISTREAM:
899			context.beginElement(s_multistream_tag);
900			break;
901
902		case B_MEDIA_ENCODED_AUDIO:
903			context.beginElement(s_encoded_audio_tag);
904			break;
905
906		case B_MEDIA_ENCODED_VIDEO:
907			context.beginElement(s_encoded_video_tag);
908			break;
909
910		default:
911			// +++++ not very polite
912			context.reportError("MediaFormatIO: type not supported\n");
913			break;
914	}
915}
916
917void MediaFormatIO::xmlExportAttributes(
918	ExportContext&		context) const {
919
920	switch(m_format.type) {
921		case B_MEDIA_RAW_AUDIO:
922			export_raw_audio_attr(m_format.u.raw_audio, context);
923			export_multi_audio_info_attr(m_format.u.raw_audio, context);
924			break;
925
926		case B_MEDIA_RAW_VIDEO:
927			export_raw_video_attr(m_format.u.raw_video, context);
928			break;
929
930		case B_MEDIA_MULTISTREAM:
931			export_multistream_attr(m_format.u.multistream, context);
932			break;
933
934		case B_MEDIA_ENCODED_AUDIO:
935			export_encoded_audio_attr(m_format.u.encoded_audio, context);
936			break;
937
938		case B_MEDIA_ENCODED_VIDEO:
939			export_encoded_video_attr(m_format.u.encoded_video, context);
940			break;
941
942		default:
943			break;
944	}
945}
946
947void MediaFormatIO::xmlExportContent(
948	ExportContext&		context) const {
949
950	switch(m_format.type) {
951		case B_MEDIA_RAW_VIDEO:
952			export_raw_video_content(m_format.u.raw_video, context);
953			break;
954
955		case B_MEDIA_MULTISTREAM:
956			export_multistream_content(m_format.u.multistream, context);
957			break;
958
959		case B_MEDIA_ENCODED_AUDIO:
960			export_encoded_audio_content(m_format.u.encoded_audio, context);
961			break;
962
963		case B_MEDIA_ENCODED_VIDEO:
964			export_encoded_video_content(m_format.u.encoded_video, context);
965			break;
966
967		default:
968			break;
969	}
970}
971
972void MediaFormatIO::xmlExportEnd(
973	ExportContext&		context) const {
974
975	context.endElement();
976}
977
978// -------------------------------------------------------- //
979// import
980// -------------------------------------------------------- //
981
982void import_raw_audio_attribute(
983	media_raw_audio_format& f,
984	const char* key,
985	const char* value,
986	ImportContext& context) {
987
988	if(!strcmp(key, gKey_frame_rate))
989		f.frame_rate = atof(value);
990	else if(!strcmp(key, gKey_channel_count))
991		f.channel_count = atol(value);
992	else if(!strcmp(key, gKey_buffer_size))
993		f.buffer_size = atol(value);
994	else if(!strcmp(key, gKey_format)) {
995		if(!strcmp(value, "B_AUDIO_UCHAR"))
996			f.format = media_raw_audio_format::B_AUDIO_UCHAR;
997		else if(!strcmp(value, "B_AUDIO_SHORT"))
998			f.format = media_raw_audio_format::B_AUDIO_SHORT;
999		else if(!strcmp(value, "B_AUDIO_FLOAT"))
1000			f.format = media_raw_audio_format::B_AUDIO_FLOAT;
1001		else if(!strcmp(value, "B_AUDIO_INT"))
1002			f.format = media_raw_audio_format::B_AUDIO_INT;
1003	}
1004	else if(!strcmp(key, gKey_byte_order)) {
1005		if(!strcmp(value, "B_MEDIA_BIG_ENDIAN"))
1006			f.byte_order = B_MEDIA_BIG_ENDIAN;
1007		else if(!strcmp(value, "B_MEDIA_LITTLE_ENDIAN"))
1008			f.byte_order = B_MEDIA_LITTLE_ENDIAN;
1009	}
1010}
1011
1012void import_multi_audio_info_attribute(
1013	media_multi_audio_info& f,
1014	const char* key,
1015	const char* value,
1016	ImportContext& context) {
1017
1018	if(!strcmp(key, gKey_channel_mask))
1019		f.channel_mask = atol(value);
1020	else if(!strcmp(key, gKey_valid_bits))
1021		f.valid_bits = atoi(value);
1022	else if(!strcmp(key, gKey_matrix_mask))
1023		f.matrix_mask = atoi(value);
1024}
1025
1026void import_raw_video_attribute(
1027	media_raw_video_format& f,
1028	const char* key,
1029	const char* value,
1030	ImportContext& context) {
1031
1032	if(!strcmp(key, gKey_field_rate))
1033		f.field_rate = atof(value);
1034	else if(!strcmp(key, gKey_interlace))
1035		f.interlace = atol(value);
1036	else if(!strcmp(key, gKey_first_active))
1037		f.first_active = atol(value);
1038	else if(!strcmp(key, gKey_last_active))
1039		f.last_active = atol(value);
1040	else if(!strcmp(key, gKey_pixel_width_aspect))
1041		f.pixel_width_aspect = atol(value);
1042	else if(!strcmp(key, gKey_pixel_height_aspect))
1043		f.pixel_height_aspect = atol(value);
1044	else if(!strcmp(key, gKey_orientation)) {
1045		if(!strcmp(value, "B_VIDEO_TOP_LEFT_RIGHT"))
1046			f.orientation = B_VIDEO_TOP_LEFT_RIGHT;
1047		else if(!strcmp(value, "B_VIDEO_BOTTOM_LEFT_RIGHT"))
1048			f.orientation = B_VIDEO_BOTTOM_LEFT_RIGHT;
1049	}
1050}
1051
1052void import_video_display_info_attribute(
1053	media_video_display_info& d,
1054	const char* key,
1055	const char* value,
1056	ImportContext& context) {
1057
1058	if(!strcmp(key, gKey_line_width))
1059		d.line_width = atol(value);
1060	else if(!strcmp(key, gKey_line_count))
1061		d.line_count = atol(value);
1062	else if(!strcmp(key, gKey_bytes_per_row))
1063		d.bytes_per_row = atol(value);
1064	else if(!strcmp(key, gKey_pixel_offset))
1065		d.pixel_offset = atol(value);
1066	else if(!strcmp(key, gKey_line_offset))
1067		d.line_offset = atol(value);
1068	else if(!strcmp(key, gKey_format)) {
1069		import_color_space(value, d.format);
1070	}
1071}
1072
1073void import_multistream_attribute(
1074	media_multistream_format& f,
1075	const char* key,
1076	const char* value,
1077	ImportContext& context) {
1078
1079	if(!strcmp(key, gKey_format)) {
1080		if(!strcmp(value, "B_ANY"))
1081			f.format = media_multistream_format::B_ANY;
1082		else if(!strcmp(value, "B_VID"))
1083			f.format = media_multistream_format::B_VID;
1084		else if(!strcmp(value, "B_AVI"))
1085			f.format = media_multistream_format::B_AVI;
1086		else if(!strcmp(value, "B_MPEG1"))
1087			f.format = media_multistream_format::B_MPEG1;
1088		else if(!strcmp(value, "B_MPEG2"))
1089			f.format = media_multistream_format::B_MPEG2;
1090		else if(!strcmp(value, "B_QUICKTIME"))
1091			f.format = media_multistream_format::B_QUICKTIME;
1092		else
1093			f.format = atol(value);
1094	}
1095	else if(!strcmp(key, gKey_avg_bit_rate))
1096		f.avg_bit_rate = atof(value);
1097	else if(!strcmp(key, gKey_max_bit_rate))
1098		f.max_bit_rate = atof(value);
1099	else if(!strcmp(key, gKey_avg_chunk_size))
1100		f.avg_chunk_size = atol(value);
1101	else if(!strcmp(key, gKey_max_chunk_size))
1102		f.max_chunk_size = atol(value);
1103}
1104
1105void import_multistream_flags_attribute(
1106	uint32& flags,
1107	const char* key,
1108	const char* value,
1109	ImportContext& context) {
1110
1111	if(!atol(value))
1112		return;
1113
1114	if(!strcmp(key, gKey_header_has_flags))
1115		flags |= media_multistream_format::B_HEADER_HAS_FLAGS;
1116	else if(!strcmp(key, gKey_clean_buffers))
1117		flags |= media_multistream_format::B_CLEAN_BUFFERS;
1118	else if(!strcmp(key, gKey_homogenous_buffers))
1119		flags |= media_multistream_format::B_HOMOGENOUS_BUFFERS;
1120}
1121
1122void import_multistream_vid_info_attribute(
1123	media_multistream_format::vid_info& f,
1124	const char* key,
1125	const char* value,
1126	ImportContext& context) {
1127
1128	if(!strcmp(key, gKey_frame_rate))
1129		f.frame_rate = atof(value);
1130	else if(!strcmp(key, gKey_width))
1131		f.width = atol(value);
1132	else if(!strcmp(key, gKey_height))
1133		f.height = atol(value);
1134	else if(!strcmp(key, gKey_space))
1135		import_color_space(value, f.space);
1136	else if(!strcmp(key, gKey_sampling_rate))
1137		f.sampling_rate = atof(value);
1138	else if(!strcmp(key, gKey_channel_count))
1139		f.channel_count = atol(value);
1140	else if(!strcmp(key, gKey_sample_format)) {
1141		if(!strcmp(value, "B_UNDEFINED_SAMPLES"))
1142			f.sample_format = B_UNDEFINED_SAMPLES;
1143		else if(!strcmp(value, "B_LINEAR_SAMPLES"))
1144			f.sample_format = B_LINEAR_SAMPLES;
1145		else if(!strcmp(value, "B_FLOAT_SAMPLES"))
1146			f.sample_format = B_FLOAT_SAMPLES;
1147		else if(!strcmp(value, "B_MULAW_SAMPLES"))
1148			f.sample_format = B_MULAW_SAMPLES;
1149	}
1150	else if(!strcmp(key, gKey_byte_order)) {
1151		if(!strcmp(value, "B_MEDIA_BIG_ENDIAN"))
1152			f.byte_order = B_MEDIA_BIG_ENDIAN;
1153		else if(!strcmp(value, "B_MEDIA_LITTLE_ENDIAN"))
1154			f.byte_order = B_MEDIA_LITTLE_ENDIAN;
1155	}
1156}
1157
1158void import_multistream_avi_info_attribute(
1159	media_multistream_format::avi_info& f,
1160	const char* key,
1161	const char* value,
1162	ImportContext& context) {
1163
1164	if(!strcmp(key, gKey_us_per_frame))
1165		f.us_per_frame = atol(value);
1166	else if(!strcmp(key, gKey_width))
1167		f.width = atol(value);
1168	else if(!strcmp(key, gKey_height))
1169		f.height = atol(value);
1170}
1171
1172void import_encoded_audio_attribute(
1173	media_encoded_audio_format& f,
1174	const char* key,
1175	const char* value,
1176	ImportContext& context) {
1177
1178	if(!strcmp(key, gKey_encoding)) {
1179		if(!strcmp(value, "B_ANY"))
1180			f.encoding = media_encoded_audio_format::B_ANY;
1181	}
1182	else if(!strcmp(key, gKey_bit_rate))
1183		f.bit_rate = atof(value);
1184	else if(!strcmp(key, gKey_frame_size))
1185		f.frame_size = atol(value);
1186}
1187
1188void import_encoded_video_attribute(
1189	media_encoded_video_format& f,
1190	const char* key,
1191	const char* value,
1192	ImportContext& context) {
1193
1194	if(!strcmp(key, gKey_encoding)) {
1195		if(!strcmp(value, "B_ANY"))
1196			f.encoding = media_encoded_video_format::B_ANY;
1197	}
1198	else if(!strcmp(key, gKey_avg_bit_rate))
1199		f.avg_bit_rate = atof(value);
1200	else if(!strcmp(key, gKey_max_bit_rate))
1201		f.max_bit_rate = atof(value);
1202	else if(!strcmp(key, gKey_frame_size))
1203		f.frame_size = atol(value);
1204	else if(!strcmp(key, gKey_forward_history))
1205		f.forward_history = atol(value);
1206	else if(!strcmp(key, gKey_backward_history))
1207		f.backward_history = atol(value);
1208}
1209
1210// -------------------------------------------------------- //
1211
1212void MediaFormatIO::xmlImportBegin(
1213	ImportContext&		context) {
1214
1215	// initialize format
1216	if(!strcmp(context.element(), s_raw_audio_tag)) {
1217		m_format.type = B_MEDIA_RAW_AUDIO;
1218		m_format.u.raw_audio = media_raw_audio_format::wildcard;
1219	}
1220	else if(!strcmp(context.element(), s_raw_video_tag)) {
1221		m_format.type = B_MEDIA_RAW_VIDEO;
1222		m_format.u.raw_video = media_raw_video_format::wildcard;
1223	}
1224	else if(!strcmp(context.element(), s_multistream_tag)) {
1225		m_format.type = B_MEDIA_MULTISTREAM;
1226		m_format.u.multistream = media_multistream_format::wildcard;
1227	}
1228	else if(!strcmp(context.element(), s_encoded_audio_tag)) {
1229		m_format.type = B_MEDIA_ENCODED_AUDIO;
1230		m_format.u.encoded_audio = media_encoded_audio_format::wildcard;
1231	}
1232	else if(!strcmp(context.element(), s_encoded_video_tag)) {
1233		m_format.type = B_MEDIA_ENCODED_VIDEO;
1234		m_format.u.encoded_video = media_encoded_video_format::wildcard;
1235	}
1236	else
1237		context.reportError("Bad element mapping?  MediaFormatIO can't cope.");
1238}
1239
1240void MediaFormatIO::xmlImportAttribute(
1241	const char*					key,
1242	const char*					value,
1243	ImportContext&		context) {
1244	switch(m_format.type) {
1245		case B_MEDIA_RAW_AUDIO:
1246			import_raw_audio_attribute(
1247				m_format.u.raw_audio, key, value, context);
1248
1249			import_multi_audio_info_attribute(
1250				m_format.u.raw_audio, key, value, context);
1251			break;
1252
1253		case B_MEDIA_RAW_VIDEO:
1254			import_raw_video_attribute(
1255				m_format.u.raw_video, key, value, context);
1256			break;
1257
1258		case B_MEDIA_MULTISTREAM:
1259			import_multistream_attribute(
1260				m_format.u.multistream, key, value, context);
1261			break;
1262
1263		case B_MEDIA_ENCODED_AUDIO:
1264			import_encoded_audio_attribute(
1265				m_format.u.encoded_audio, key, value, context);
1266			break;
1267
1268		case B_MEDIA_ENCODED_VIDEO:
1269			import_encoded_video_attribute(
1270				m_format.u.encoded_video, key, value, context);
1271			break;
1272
1273		default:
1274			context.reportError("MediaFormatIO: bad type.");
1275	}
1276}
1277
1278void MediaFormatIO::xmlImportContent(
1279	const char*					data,
1280	uint32						length,
1281	ImportContext&		context) {}
1282
1283void MediaFormatIO::xmlImportChild(
1284	IPersistent*			child,
1285	ImportContext&		context) {
1286
1287	MediaFormatIO* childAsFormat = dynamic_cast<MediaFormatIO*>(child);
1288	if(m_format.type == B_MEDIA_ENCODED_AUDIO) {
1289		if (childAsFormat == NULL
1290			|| childAsFormat->m_format.type != B_MEDIA_RAW_AUDIO) {
1291			context.reportError("Expected a raw_audio_format.");
1292		} else {
1293			m_format.u.encoded_audio.output =
1294				childAsFormat->m_format.u.raw_audio;
1295		}
1296	}
1297	else if(m_format.type == B_MEDIA_ENCODED_VIDEO) {
1298		if (childAsFormat == NULL
1299			|| childAsFormat->m_format.type != B_MEDIA_RAW_VIDEO) {
1300			context.reportError("Expected a raw_video_format.");
1301		} else {
1302			m_format.u.encoded_video.output =
1303				childAsFormat->m_format.u.raw_video;
1304		}
1305	}
1306	else {
1307		// +++++ should this be an error?
1308		context.reportWarning("MediaFormatIO: Unexpected child element.");
1309	}
1310	delete child;
1311}
1312
1313void MediaFormatIO::xmlImportComplete(
1314	ImportContext&		context) {
1315
1316	// +++++ validity checks?
1317
1318	m_complete = true;
1319}
1320
1321void MediaFormatIO::xmlImportChildBegin(
1322	const char*					name,
1323	ImportContext&		context) {
1324
1325	if(!strcmp(name, s_video_display_info_tag)) {
1326		if(m_format.type != B_MEDIA_RAW_VIDEO)
1327			context.reportError("MediaFormatIO: unexpected element.");
1328	}
1329	else if(!strcmp(name, s_multistream_flags_tag)) {
1330		if(m_format.type != B_MEDIA_MULTISTREAM)
1331			context.reportError("MediaFormatIO: unexpected element.");
1332	}
1333	else if(!strcmp(name, s_multistream_vid_info_tag)) {
1334		if(m_format.type != B_MEDIA_MULTISTREAM ||
1335			m_format.u.multistream.format != media_multistream_format::B_VID)
1336			context.reportError("MediaFormatIO: unexpected element.");
1337	}
1338	else if(!strcmp(name, s_multistream_avi_info_tag)) {
1339		if(m_format.type != B_MEDIA_MULTISTREAM ||
1340			m_format.u.multistream.format != media_multistream_format::B_AVI)
1341			context.reportError("MediaFormatIO: unexpected element.");
1342	}
1343	else if(!strcmp(name, s_media_type_tag)) {
1344		if(m_format.type != B_MEDIA_MULTISTREAM ||
1345			m_format.u.multistream.format != media_multistream_format::B_AVI)
1346			context.reportError("MediaFormatIO: unexpected element.");
1347	}
1348}
1349
1350void MediaFormatIO::xmlImportChildAttribute(
1351	const char*					key,
1352	const char*					value,
1353	ImportContext&		context) {
1354
1355	if(!strcmp(context.element(), s_video_display_info_tag))
1356		import_video_display_info_attribute(
1357			m_format.u.raw_video.display, key, value, context);
1358
1359	else if(!strcmp(context.element(), s_multistream_flags_tag	))
1360		import_multistream_flags_attribute(
1361			m_format.u.multistream.flags, key, value, context);
1362
1363	else if(!strcmp(context.element(), s_multistream_vid_info_tag	))
1364		import_multistream_vid_info_attribute(
1365			m_format.u.multistream.u.vid, key, value, context);
1366
1367	else if(!strcmp(context.element(), s_multistream_avi_info_tag	))
1368		import_multistream_avi_info_attribute(
1369			m_format.u.multistream.u.avi, key, value, context);
1370
1371	else
1372		context.reportError("MediaFormatIO: bad child element.");
1373}
1374
1375void MediaFormatIO::xmlImportChildContent(
1376	const char*					data,
1377	uint32						length,
1378	ImportContext&		context) {
1379
1380	if(!strcmp(context.element(), s_media_type_tag)) {
1381		m_mediaType.Append(data, length);
1382	}
1383}
1384
1385void MediaFormatIO::xmlImportChildComplete(
1386	const char*					name,
1387	ImportContext&		context) {
1388
1389	if(!strcmp(context.element(), s_media_type_tag)) {
1390		import_media_type_content(
1391			m_format.u.multistream.u.avi,
1392			m_mediaType.String(),	context);
1393
1394		m_mediaType = "";
1395	}
1396}
1397
1398
1399// END -- MediaFormatIO.cpp --
1400