xref: /haiku/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp (revision 6e04e144d606e6ecc2f8216f04533683ee78849f)
1ca16f5cbSbeveloper #include <stdio.h>
2bce1ab5eSbeveloper #include <string.h>
3ca16f5cbSbeveloper #include <DataIO.h>
4bb1d6ef2Sbeveloper #include <OS.h>
5bb1d6ef2Sbeveloper #include <MediaRoster.h>
6bb1d6ef2Sbeveloper #include "RawFormats.h"
7ca16f5cbSbeveloper #include "RawDecoderPlugin.h"
8bb1d6ef2Sbeveloper #include "AudioConversion.h"
9ca16f5cbSbeveloper 
10ca16f5cbSbeveloper #define TRACE_THIS 1
11ca16f5cbSbeveloper #if TRACE_THIS
12ca16f5cbSbeveloper   #define TRACE printf
13ca16f5cbSbeveloper #else
14bb1d6ef2Sbeveloper   #define TRACE(a...)
15ca16f5cbSbeveloper #endif
16ca16f5cbSbeveloper 
1754348708Sbeveloper inline size_t
1854348708Sbeveloper AudioBufferSize(int32 channel_count, uint32 sample_format, float frame_rate, bigtime_t buffer_duration = 50000 /* 50 ms */)
1954348708Sbeveloper {
2054348708Sbeveloper 	return (sample_format & 0xf) * channel_count * (size_t)((frame_rate * buffer_duration) / 1000000.0);
2154348708Sbeveloper }
22ca16f5cbSbeveloper 
23a0a20160SAxel Dörfler 
24a0a20160SAxel Dörfler void
25*6e04e144Sbeveloper RawDecoder::GetCodecInfo(media_codec_info *info)
26a0a20160SAxel Dörfler {
27*6e04e144Sbeveloper 	strcpy(info->short_name, "raw");
28a0a20160SAxel Dörfler 
29a0a20160SAxel Dörfler 	if (fInputFormat.IsAudio())
30*6e04e144Sbeveloper 		strcpy(info->pretty_name, "Raw audio decoder");
31a0a20160SAxel Dörfler 	else
32*6e04e144Sbeveloper 		strcpy(info->pretty_name, "Raw video decoder");
33a0a20160SAxel Dörfler }
34a0a20160SAxel Dörfler 
35a0a20160SAxel Dörfler 
36ca16f5cbSbeveloper status_t
3725305239Sbeveloper RawDecoder::Setup(media_format *ioEncodedFormat,
38bce1ab5eSbeveloper 				  const void *infoBuffer, int32 infoSize)
39ca16f5cbSbeveloper {
40bb1d6ef2Sbeveloper 	char s[200];
41bb1d6ef2Sbeveloper 	string_for_format(*ioEncodedFormat, s, sizeof(s));
42bb1d6ef2Sbeveloper 	TRACE("RawDecoder::Setup: %s\n", s);
43bb1d6ef2Sbeveloper 
44bce1ab5eSbeveloper 	if (ioEncodedFormat->type != B_MEDIA_RAW_AUDIO && ioEncodedFormat->type != B_MEDIA_RAW_VIDEO)
45ca16f5cbSbeveloper 		return B_ERROR;
46ca16f5cbSbeveloper 
4725305239Sbeveloper 	fInputFormat = *ioEncodedFormat;
4825305239Sbeveloper 
49bb1d6ef2Sbeveloper 	if (ioEncodedFormat->type == B_MEDIA_RAW_VIDEO) {
50bb1d6ef2Sbeveloper 		fInputSampleSize = ioEncodedFormat->u.raw_video.display.line_count * ioEncodedFormat->u.raw_video.display.bytes_per_row;
51bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize;
52bb1d6ef2Sbeveloper 	} else {
53bb1d6ef2Sbeveloper 		fInputSampleSize = (ioEncodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
54bb1d6ef2Sbeveloper 		fInputFrameSize = fInputSampleSize * ioEncodedFormat->u.raw_audio.channel_count;
55bb1d6ef2Sbeveloper 	}
56bb1d6ef2Sbeveloper 
57bb1d6ef2Sbeveloper 	// since ioEncodedFormat is later passed to the application by BMediaTrack::EncodedFormat()
58bb1d6ef2Sbeveloper 	// we need to remove non public format specifications
59bb1d6ef2Sbeveloper 
60bb1d6ef2Sbeveloper 	// remove non format bits, like channel order
61bb1d6ef2Sbeveloper 	ioEncodedFormat->u.raw_audio.format &= B_AUDIO_FORMAT_MASK;
62bb1d6ef2Sbeveloper 
63bb1d6ef2Sbeveloper 	switch (ioEncodedFormat->u.raw_audio.format) {
64bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
65bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
66bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
67bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
68bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
69bb1d6ef2Sbeveloper 			break; // ok to pass through
70bb1d6ef2Sbeveloper 
71bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
72bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_INT32;
73bb1d6ef2Sbeveloper 			break;
74bb1d6ef2Sbeveloper 
75bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
76bb1d6ef2Sbeveloper 			ioEncodedFormat->u.raw_audio.format = B_AUDIO_FORMAT_FLOAT32;
77bb1d6ef2Sbeveloper 			break;
78bb1d6ef2Sbeveloper 
79bb1d6ef2Sbeveloper 		default:
80bb1d6ef2Sbeveloper 			TRACE("RawDecoder::Setup: unknown input format\n");
81bb1d6ef2Sbeveloper 			return B_ERROR;
82bb1d6ef2Sbeveloper 	}
83bce1ab5eSbeveloper 
8454348708Sbeveloper 	// since we can translate to a different buffer size,
8554348708Sbeveloper 	// suggest something nicer than delivered by the
8654348708Sbeveloper 	// file reader (perhaps we should even report wildcard?)
8754348708Sbeveloper 	ioEncodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
8854348708Sbeveloper 														ioEncodedFormat->u.raw_audio.channel_count,
8954348708Sbeveloper 														ioEncodedFormat->u.raw_audio.format,
9054348708Sbeveloper 														ioEncodedFormat->u.raw_audio.frame_rate);
9125305239Sbeveloper 	return B_OK;
9225305239Sbeveloper }
93bce1ab5eSbeveloper 
9425305239Sbeveloper 
9525305239Sbeveloper status_t
9625305239Sbeveloper RawDecoder::NegotiateOutputFormat(media_format *ioDecodedFormat)
9725305239Sbeveloper {
9825305239Sbeveloper 	// BeBook says: The codec will find and return in ioFormat its best matching format
9925305239Sbeveloper 	// => This means, we never return an error, and always change the format values
10025305239Sbeveloper 	//    that we don't support to something more applicable
101bb1d6ef2Sbeveloper 	if (ioDecodedFormat->type == B_MEDIA_RAW_VIDEO)
102bb1d6ef2Sbeveloper 		return NegotiateVideoOutputFormat(ioDecodedFormat);
103bb1d6ef2Sbeveloper 	if (ioDecodedFormat->type == B_MEDIA_RAW_AUDIO)
104bb1d6ef2Sbeveloper 		return NegotiateAudioOutputFormat(ioDecodedFormat);
105bb1d6ef2Sbeveloper 	return B_ERROR;
106bb1d6ef2Sbeveloper }
10725305239Sbeveloper 
108bb1d6ef2Sbeveloper 
109bb1d6ef2Sbeveloper status_t
110bb1d6ef2Sbeveloper RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat)
111bb1d6ef2Sbeveloper {
112bb1d6ef2Sbeveloper 	return B_ERROR;
113bb1d6ef2Sbeveloper }
114bb1d6ef2Sbeveloper 
115bb1d6ef2Sbeveloper 
116bb1d6ef2Sbeveloper status_t
117bb1d6ef2Sbeveloper RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat)
118bb1d6ef2Sbeveloper {
1194ba72fcdSbeveloper 	char s[1024];
1204ba72fcdSbeveloper 
1214ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
122bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s);
1234ba72fcdSbeveloper 
124bb1d6ef2Sbeveloper 	ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
125bb1d6ef2Sbeveloper 	switch (ioDecodedFormat->u.raw_audio.format) {
126bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_FLOAT:
127bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_SHORT:
128bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_UCHAR:
129bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_CHAR:
130bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = 0;
131bb1d6ef2Sbeveloper 			break; // we can produce this on request
132a3d7908eSbeveloper 
133bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_INT:
134bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
135bb1d6ef2Sbeveloper 			break; // we can produce this on request
136bb1d6ef2Sbeveloper 
137bb1d6ef2Sbeveloper 		default:
138bb1d6ef2Sbeveloper 			switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
139bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_SHORT:
140bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_UCHAR:
141bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_CHAR:
142bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK;
143bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
144bb1d6ef2Sbeveloper 					break;
145bb1d6ef2Sbeveloper 
146bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_INT:
147bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT24:
148bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
149bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
150bb1d6ef2Sbeveloper 					break;
151bb1d6ef2Sbeveloper 
152bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_FLOAT:
153bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT64:
154bb1d6ef2Sbeveloper 				default:
155bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
156bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
157bb1d6ef2Sbeveloper 					break;
158bb1d6ef2Sbeveloper 			}
159bb1d6ef2Sbeveloper 			break;
160bb1d6ef2Sbeveloper 	}
161bb1d6ef2Sbeveloper 
162bb1d6ef2Sbeveloper 	fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate;
163bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.frame_rate = fInputFormat.u.raw_audio.frame_rate;
164bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_count = fInputFormat.u.raw_audio.channel_count;
165bb1d6ef2Sbeveloper 
166bb1d6ef2Sbeveloper 	fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
167bb1d6ef2Sbeveloper 	fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count;
168bb1d6ef2Sbeveloper 
169bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == 0)
170bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
171bb1d6ef2Sbeveloper 
172bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_mask = 0;
173bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.matrix_mask = 0;
174bb1d6ef2Sbeveloper 
175bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) {
17654348708Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
177bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.channel_count,
178bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.format,
179bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.frame_rate);
180bb1d6ef2Sbeveloper 	} else {
181bb1d6ef2Sbeveloper 		// round down to exact multiple of output frame size
182bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize;
183bb1d6ef2Sbeveloper 	}
184bb1d6ef2Sbeveloper 
185bb1d6ef2Sbeveloper 	fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize;
186bb1d6ef2Sbeveloper 
187bb1d6ef2Sbeveloper 	// setup input swapping function
188bb1d6ef2Sbeveloper 	if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
189bb1d6ef2Sbeveloper 		fSwapInput = 0;
190bb1d6ef2Sbeveloper 	} else {
191bb1d6ef2Sbeveloper 		switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
192bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
193bb1d6ef2Sbeveloper 				fSwapInput = &swap_int16;
194bb1d6ef2Sbeveloper 				break;
195bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT24:
196bb1d6ef2Sbeveloper 				fSwapInput = &swap_int24;
197bb1d6ef2Sbeveloper 				break;
198bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
199bb1d6ef2Sbeveloper 				fSwapInput = &swap_int32;
200bb1d6ef2Sbeveloper 				break;
201bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
202bb1d6ef2Sbeveloper 				fSwapInput = &swap_float32;
203bb1d6ef2Sbeveloper 				break;
204bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT64:
205bb1d6ef2Sbeveloper 				fSwapInput = &swap_float64;
206bb1d6ef2Sbeveloper 				break;
207bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
208bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
209bb1d6ef2Sbeveloper 				fSwapInput = 0;
210bb1d6ef2Sbeveloper 				break;
211bb1d6ef2Sbeveloper 			default:
21216611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
213bb1d6ef2Sbeveloper 				break;
214bb1d6ef2Sbeveloper 		}
215bb1d6ef2Sbeveloper 	}
216bb1d6ef2Sbeveloper 
217bb1d6ef2Sbeveloper 	// setup output swapping function
218bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
219bb1d6ef2Sbeveloper 		fSwapOutput = 0;
220bb1d6ef2Sbeveloper 	} else {
221bb1d6ef2Sbeveloper 		switch (ioDecodedFormat->u.raw_audio.format) {
222bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
223bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int16;
224bb1d6ef2Sbeveloper 				break;
225bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
226bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int32;
227bb1d6ef2Sbeveloper 				break;
228bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
229bb1d6ef2Sbeveloper 				fSwapOutput = &swap_float32;
230bb1d6ef2Sbeveloper 				break;
231bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
232bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
233bb1d6ef2Sbeveloper 				fSwapOutput = 0;
234bb1d6ef2Sbeveloper 				break;
235bb1d6ef2Sbeveloper 			default:
23616611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
237bb1d6ef2Sbeveloper 				break;
238bb1d6ef2Sbeveloper 		}
239bb1d6ef2Sbeveloper 	}
240bb1d6ef2Sbeveloper 
241bb1d6ef2Sbeveloper 	// setup sample conversation function
242bb1d6ef2Sbeveloper 	switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
243bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
244bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
245bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
246bb1d6ef2Sbeveloper 					fConvert = &uint8_to_uint8;
247bb1d6ef2Sbeveloper 					break;
248bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
249bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int8;
250bb1d6ef2Sbeveloper 					break;
251bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
252bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int16;
253bb1d6ef2Sbeveloper 					break;
254bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
255bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int32;
256bb1d6ef2Sbeveloper 					break;
257bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
258bb1d6ef2Sbeveloper 					fConvert = &uint8_to_float32;
259bb1d6ef2Sbeveloper 					break;
260bb1d6ef2Sbeveloper 				default:
26116611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
262bb1d6ef2Sbeveloper 					break;
263bb1d6ef2Sbeveloper 			}
264bb1d6ef2Sbeveloper 			break;
265bb1d6ef2Sbeveloper 
266bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
267bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
268bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
269bb1d6ef2Sbeveloper 					fConvert = &int8_to_uint8;
270bb1d6ef2Sbeveloper 					break;
271bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
272bb1d6ef2Sbeveloper 					fConvert = &int8_to_int8;
273bb1d6ef2Sbeveloper 					break;
274bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
275bb1d6ef2Sbeveloper 					fConvert = &int8_to_int16;
276bb1d6ef2Sbeveloper 					break;
277bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
278bb1d6ef2Sbeveloper 					fConvert = &int8_to_int32;
279bb1d6ef2Sbeveloper 					break;
280bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
281bb1d6ef2Sbeveloper 					fConvert = &int8_to_float32;
282bb1d6ef2Sbeveloper 					break;
283bb1d6ef2Sbeveloper 				default:
28416611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
285bb1d6ef2Sbeveloper 					break;
286bb1d6ef2Sbeveloper 			}
287bb1d6ef2Sbeveloper 			break;
288bb1d6ef2Sbeveloper 
289bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
290bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
291bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
292bb1d6ef2Sbeveloper 					fConvert = &int16_to_uint8;
293bb1d6ef2Sbeveloper 					break;
294bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
295bb1d6ef2Sbeveloper 					fConvert = &int16_to_int8;
296bb1d6ef2Sbeveloper 					break;
297bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
298bb1d6ef2Sbeveloper 					fConvert = &int16_to_int16;
299bb1d6ef2Sbeveloper 					break;
300bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
301bb1d6ef2Sbeveloper 					fConvert = &int16_to_int32;
302bb1d6ef2Sbeveloper 					break;
303bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
304bb1d6ef2Sbeveloper 					fConvert = &int16_to_float32;
305bb1d6ef2Sbeveloper 					break;
306bb1d6ef2Sbeveloper 				default:
30716611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
308bb1d6ef2Sbeveloper 					break;
309bb1d6ef2Sbeveloper 			}
310bb1d6ef2Sbeveloper 			break;
311bb1d6ef2Sbeveloper 
312bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
313bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
314bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
315bb1d6ef2Sbeveloper 					fConvert = &int24_to_uint8;
316bb1d6ef2Sbeveloper 					break;
317bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
318bb1d6ef2Sbeveloper 					fConvert = &int24_to_int8;
319bb1d6ef2Sbeveloper 					break;
320bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
321bb1d6ef2Sbeveloper 					fConvert = &int24_to_int16;
322bb1d6ef2Sbeveloper 					break;
323bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
324bb1d6ef2Sbeveloper 					fConvert = &int24_to_int32;
325bb1d6ef2Sbeveloper 					break;
326bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
327bb1d6ef2Sbeveloper 					fConvert = &int24_to_float32;
328bb1d6ef2Sbeveloper 					break;
329bb1d6ef2Sbeveloper 				default:
33016611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
331bb1d6ef2Sbeveloper 					break;
332bb1d6ef2Sbeveloper 			}
333bb1d6ef2Sbeveloper 			break;
334bb1d6ef2Sbeveloper 
335bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
336bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
337bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
338bb1d6ef2Sbeveloper 					fConvert = &int32_to_uint8;
339bb1d6ef2Sbeveloper 					break;
340bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
341bb1d6ef2Sbeveloper 					fConvert = &int32_to_int8;
342bb1d6ef2Sbeveloper 					break;
343bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
344bb1d6ef2Sbeveloper 					fConvert = &int32_to_int16;
345bb1d6ef2Sbeveloper 					break;
346bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
347bb1d6ef2Sbeveloper 					fConvert = &int32_to_int32;
348bb1d6ef2Sbeveloper 					break;
349bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
350bb1d6ef2Sbeveloper 					fConvert = &int32_to_float32;
351bb1d6ef2Sbeveloper 					break;
352bb1d6ef2Sbeveloper 				default:
35316611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
354bb1d6ef2Sbeveloper 					break;
355bb1d6ef2Sbeveloper 			}
356bb1d6ef2Sbeveloper 			break;
357bb1d6ef2Sbeveloper 
358bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
359bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
360bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
361bb1d6ef2Sbeveloper 					fConvert = &float32_to_uint8;
362bb1d6ef2Sbeveloper 					break;
363bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
364bb1d6ef2Sbeveloper 					fConvert = &float32_to_int8;
365bb1d6ef2Sbeveloper 					break;
366bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
367bb1d6ef2Sbeveloper 					fConvert = &float32_to_int16;
368bb1d6ef2Sbeveloper 					break;
369bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
370bb1d6ef2Sbeveloper 					fConvert = &float32_to_int32;
371bb1d6ef2Sbeveloper 					break;
372bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
373bb1d6ef2Sbeveloper 					fConvert = &float32_to_float32;
374bb1d6ef2Sbeveloper 					break;
375bb1d6ef2Sbeveloper 				default:
37616611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
377bb1d6ef2Sbeveloper 					break;
378bb1d6ef2Sbeveloper 			}
379bb1d6ef2Sbeveloper 			break;
380bb1d6ef2Sbeveloper 
381bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
382bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
383bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
384bb1d6ef2Sbeveloper 					fConvert = &float64_to_uint8;
385bb1d6ef2Sbeveloper 					break;
386bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
387bb1d6ef2Sbeveloper 					fConvert = &float64_to_int8;
388bb1d6ef2Sbeveloper 					break;
389bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
390bb1d6ef2Sbeveloper 					fConvert = &float64_to_int16;
391bb1d6ef2Sbeveloper 					break;
392bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
393bb1d6ef2Sbeveloper 					fConvert = &float64_to_int32;
394bb1d6ef2Sbeveloper 					break;
395bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
396bb1d6ef2Sbeveloper 					fConvert = &float64_to_float32;
397bb1d6ef2Sbeveloper 					break;
398bb1d6ef2Sbeveloper 				default:
39916611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
400bb1d6ef2Sbeveloper 					break;
401bb1d6ef2Sbeveloper 			}
402bb1d6ef2Sbeveloper 			break;
403bb1d6ef2Sbeveloper 
404bb1d6ef2Sbeveloper 		default:
40516611de7Sbeveloper 			debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
406bb1d6ef2Sbeveloper 			break;
407bb1d6ef2Sbeveloper 	}
408bb1d6ef2Sbeveloper 
409bb1d6ef2Sbeveloper 	fChunkBuffer = 0;
410bb1d6ef2Sbeveloper 	fChunkSize = 0;
411bb1d6ef2Sbeveloper 	fStartTime = 0;
4124ba72fcdSbeveloper 
4134ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
414bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s);
415bb1d6ef2Sbeveloper /*
416bb1d6ef2Sbeveloper 	TRACE("fFrameRate              %ld\n", fFrameRate);
417bb1d6ef2Sbeveloper 	TRACE("fInputFrameSize         %ld\n", fInputFrameSize);
418bb1d6ef2Sbeveloper 	TRACE("fOutputFrameSize        %ld\n", fOutputFrameSize);
419bb1d6ef2Sbeveloper 	TRACE("fInputSampleSize        %ld\n", fInputSampleSize);
420bb1d6ef2Sbeveloper 	TRACE("fOutputSampleSize       %ld\n", fOutputSampleSize);
421bb1d6ef2Sbeveloper 	TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount);
422bb1d6ef2Sbeveloper 	TRACE("fSwapInput              %p\n", fSwapInput);
423bb1d6ef2Sbeveloper 	TRACE("fConvert                %p\n", fConvert);
424bb1d6ef2Sbeveloper 	TRACE("fSwapOutput             %p\n", fSwapOutput);
425bb1d6ef2Sbeveloper */
426ca16f5cbSbeveloper 	return B_OK;
427ca16f5cbSbeveloper }
428ca16f5cbSbeveloper 
429ca16f5cbSbeveloper 
430ca16f5cbSbeveloper status_t
431d8591482Sbeveloper RawDecoder::Seek(uint32 seekTo,
432bce1ab5eSbeveloper 				 int64 seekFrame, int64 *frame,
433bce1ab5eSbeveloper 				 bigtime_t seekTime, bigtime_t *time)
434ca16f5cbSbeveloper {
435bb1d6ef2Sbeveloper 	fChunkSize = 0;
436bb1d6ef2Sbeveloper 	fStartTime = *time;
437ca16f5cbSbeveloper 	return B_OK;
438ca16f5cbSbeveloper }
439ca16f5cbSbeveloper 
440ca16f5cbSbeveloper 
441ca16f5cbSbeveloper status_t
442ca16f5cbSbeveloper RawDecoder::Decode(void *buffer, int64 *frameCount,
443d8591482Sbeveloper 				   media_header *mediaHeader, media_decode_info *info /* = 0 */)
444ca16f5cbSbeveloper {
445bb1d6ef2Sbeveloper 	char *output_buffer = (char *)buffer;
446bb1d6ef2Sbeveloper 	mediaHeader->start_time = fStartTime;
447bb1d6ef2Sbeveloper 	*frameCount = 0;
448bb1d6ef2Sbeveloper 	while (*frameCount < fOutputBufferFrameCount) {
449bb1d6ef2Sbeveloper 		if (fChunkSize == 0) {
450bb1d6ef2Sbeveloper 			media_header mh;
4512d923d67Sbeveloper 			status_t err;
452bb1d6ef2Sbeveloper 			err = GetNextChunk((void **)&fChunkBuffer, &fChunkSize, &mh);
453bb1d6ef2Sbeveloper 			if (err != B_OK || fChunkSize < fInputFrameSize) {
454bb1d6ef2Sbeveloper 				fChunkSize = 0;
455bb1d6ef2Sbeveloper 				break;
456bb1d6ef2Sbeveloper 			}
457bb1d6ef2Sbeveloper 			if (fSwapInput)
458bb1d6ef2Sbeveloper 				fSwapInput(fChunkBuffer, fChunkSize / fInputSampleSize);
459bb1d6ef2Sbeveloper 			fStartTime = mh.start_time;
460bb1d6ef2Sbeveloper 			continue;
461bb1d6ef2Sbeveloper 		}
462bb1d6ef2Sbeveloper 		int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize);
463bb1d6ef2Sbeveloper 		int32 samples = frames * fInputFormat.u.raw_audio.channel_count;
464bb1d6ef2Sbeveloper 		fConvert(output_buffer, fChunkBuffer, samples);
465bb1d6ef2Sbeveloper 		fChunkBuffer += frames * fInputFrameSize;
466bb1d6ef2Sbeveloper 		fChunkSize -= frames * fInputFrameSize;
467bb1d6ef2Sbeveloper 		output_buffer += frames * fOutputFrameSize;
468bb1d6ef2Sbeveloper 		*frameCount += frames;
469bb1d6ef2Sbeveloper 		fStartTime +=  (1000000LL * frames) / fFrameRate;
470bb1d6ef2Sbeveloper 	}
471bb1d6ef2Sbeveloper 	// XXX should change channel order here for
472bb1d6ef2Sbeveloper 	// B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF
4732d923d67Sbeveloper 
474bb1d6ef2Sbeveloper 	if (fSwapOutput)
475bb1d6ef2Sbeveloper 		fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count);
476bb1d6ef2Sbeveloper 	return *frameCount ? B_OK : B_ERROR;
477ca16f5cbSbeveloper }
478ca16f5cbSbeveloper 
479ca16f5cbSbeveloper 
480ca16f5cbSbeveloper Decoder *
481ca16f5cbSbeveloper RawDecoderPlugin::NewDecoder()
482ca16f5cbSbeveloper {
483ca16f5cbSbeveloper 	return new RawDecoder;
484ca16f5cbSbeveloper }
485ca16f5cbSbeveloper 
486bce1ab5eSbeveloper status_t
487a0a20160SAxel Dörfler RawDecoderPlugin::RegisterDecoder()
488bce1ab5eSbeveloper {
489a0a20160SAxel Dörfler 	BMediaFormats formats;
490a0a20160SAxel Dörfler 	media_format_description description;
491a0a20160SAxel Dörfler 	media_format format;
492a0a20160SAxel Dörfler 
493a0a20160SAxel Dörfler 	// audio decoder
494a0a20160SAxel Dörfler 
49540d68dd2Sbeveloper 	description.family = B_BEOS_FORMAT_FAMILY;
496a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
49740d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_AUDIO;
49840d68dd2Sbeveloper 	format.u.raw_audio = media_multi_audio_format::wildcard;
499a0a20160SAxel Dörfler 
500a0a20160SAxel Dörfler 	status_t status = formats.MakeFormatFor(&description, 1, &format);
501a0a20160SAxel Dörfler 	if (status < B_OK)
502a0a20160SAxel Dörfler 		return status;
503a0a20160SAxel Dörfler 
504a0a20160SAxel Dörfler 	// video decoder
505a0a20160SAxel Dörfler 
506a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO;
50740d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_VIDEO;
50840d68dd2Sbeveloper 	format.u.raw_video = media_raw_video_format::wildcard;
509a0a20160SAxel Dörfler 
510a0a20160SAxel Dörfler 	return formats.MakeFormatFor(&description, 1, &format);
511bce1ab5eSbeveloper }
512ca16f5cbSbeveloper 
513ca16f5cbSbeveloper MediaPlugin *instantiate_plugin()
514ca16f5cbSbeveloper {
515ca16f5cbSbeveloper 	return new RawDecoderPlugin;
516ca16f5cbSbeveloper }
517