xref: /haiku/src/add-ons/media/plugins/raw_decoder/RawDecoderPlugin.cpp (revision 6736ae524a343f42152863f0a64d05874d2f97f4)
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 
10*6736ae52Sbeveloper #define TRACE_DECODER
11*6736ae52Sbeveloper #ifdef TRACE_DECODER
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
256e04e144Sbeveloper RawDecoder::GetCodecInfo(media_codec_info *info)
26a0a20160SAxel Dörfler {
276e04e144Sbeveloper 	strcpy(info->short_name, "raw");
28a0a20160SAxel Dörfler 
29a0a20160SAxel Dörfler 	if (fInputFormat.IsAudio())
306e04e144Sbeveloper 		strcpy(info->pretty_name, "Raw audio decoder");
31a0a20160SAxel Dörfler 	else
326e04e144Sbeveloper 		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
101*6736ae52Sbeveloper 	if (fInputFormat.type == B_MEDIA_RAW_VIDEO)
102bb1d6ef2Sbeveloper 		return NegotiateVideoOutputFormat(ioDecodedFormat);
103*6736ae52Sbeveloper 	if (fInputFormat.type == B_MEDIA_RAW_AUDIO)
104bb1d6ef2Sbeveloper 		return NegotiateAudioOutputFormat(ioDecodedFormat);
105*6736ae52Sbeveloper 	debugger("RawDecoder::NegotiateOutputFormat: wrong encoded format type");
106bb1d6ef2Sbeveloper 	return B_ERROR;
107bb1d6ef2Sbeveloper }
10825305239Sbeveloper 
109bb1d6ef2Sbeveloper 
110bb1d6ef2Sbeveloper status_t
111bb1d6ef2Sbeveloper RawDecoder::NegotiateVideoOutputFormat(media_format *ioDecodedFormat)
112bb1d6ef2Sbeveloper {
113bb1d6ef2Sbeveloper 	return B_ERROR;
114bb1d6ef2Sbeveloper }
115bb1d6ef2Sbeveloper 
116bb1d6ef2Sbeveloper 
117bb1d6ef2Sbeveloper status_t
118bb1d6ef2Sbeveloper RawDecoder::NegotiateAudioOutputFormat(media_format *ioDecodedFormat)
119bb1d6ef2Sbeveloper {
1204ba72fcdSbeveloper 	char s[1024];
1214ba72fcdSbeveloper 
1224ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
123bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat enter: %s\n", s);
1244ba72fcdSbeveloper 
125bb1d6ef2Sbeveloper 	ioDecodedFormat->type = B_MEDIA_RAW_AUDIO;
126bb1d6ef2Sbeveloper 	switch (ioDecodedFormat->u.raw_audio.format) {
127bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_FLOAT:
128bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_SHORT:
129bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_UCHAR:
130bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_CHAR:
131bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = 0;
132bb1d6ef2Sbeveloper 			break; // we can produce this on request
133a3d7908eSbeveloper 
134bb1d6ef2Sbeveloper 		case media_raw_audio_format::B_AUDIO_INT:
135bb1d6ef2Sbeveloper 			ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
136bb1d6ef2Sbeveloper 			break; // we can produce this on request
137bb1d6ef2Sbeveloper 
138bb1d6ef2Sbeveloper 		default:
139bb1d6ef2Sbeveloper 			switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
140bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_SHORT:
141bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_UCHAR:
142bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_CHAR:
143bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK;
144bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
145bb1d6ef2Sbeveloper 					break;
146bb1d6ef2Sbeveloper 
147bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_INT:
148bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT24:
149bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
150bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = fInputFormat.u.raw_audio.valid_bits;
151bb1d6ef2Sbeveloper 					break;
152bb1d6ef2Sbeveloper 
153bb1d6ef2Sbeveloper 				case media_raw_audio_format::B_AUDIO_FLOAT:
154bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT64:
155bb1d6ef2Sbeveloper 				default:
156bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
157bb1d6ef2Sbeveloper 					ioDecodedFormat->u.raw_audio.valid_bits = 0;
158bb1d6ef2Sbeveloper 					break;
159bb1d6ef2Sbeveloper 			}
160bb1d6ef2Sbeveloper 			break;
161bb1d6ef2Sbeveloper 	}
162bb1d6ef2Sbeveloper 
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 
166*6736ae52Sbeveloper 	fFrameRate = (int32) ioDecodedFormat->u.raw_audio.frame_rate;
167*6736ae52Sbeveloper 
168bb1d6ef2Sbeveloper 	fOutputSampleSize = (ioDecodedFormat->u.raw_audio.format & B_AUDIO_FORMAT_SIZE_MASK);
169bb1d6ef2Sbeveloper 	fOutputFrameSize = fOutputSampleSize * ioDecodedFormat->u.raw_audio.channel_count;
170bb1d6ef2Sbeveloper 
171bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == 0)
172bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
173bb1d6ef2Sbeveloper 
174bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.channel_mask = 0;
175bb1d6ef2Sbeveloper 	ioDecodedFormat->u.raw_audio.matrix_mask = 0;
176bb1d6ef2Sbeveloper 
177bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.buffer_size < 128 || ioDecodedFormat->u.raw_audio.buffer_size > 65536) {
17854348708Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = AudioBufferSize(
179bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.channel_count,
180bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.format,
181bb1d6ef2Sbeveloper 														ioDecodedFormat->u.raw_audio.frame_rate);
182bb1d6ef2Sbeveloper 	} else {
183bb1d6ef2Sbeveloper 		// round down to exact multiple of output frame size
184bb1d6ef2Sbeveloper 		ioDecodedFormat->u.raw_audio.buffer_size = (ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize) * fOutputFrameSize;
185bb1d6ef2Sbeveloper 	}
186bb1d6ef2Sbeveloper 
187bb1d6ef2Sbeveloper 	fOutputBufferFrameCount = ioDecodedFormat->u.raw_audio.buffer_size / fOutputFrameSize;
188bb1d6ef2Sbeveloper 
189bb1d6ef2Sbeveloper 	// setup input swapping function
190bb1d6ef2Sbeveloper 	if (fInputFormat.u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
191bb1d6ef2Sbeveloper 		fSwapInput = 0;
192bb1d6ef2Sbeveloper 	} else {
193bb1d6ef2Sbeveloper 		switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
194bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
195bb1d6ef2Sbeveloper 				fSwapInput = &swap_int16;
196bb1d6ef2Sbeveloper 				break;
197bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT24:
198bb1d6ef2Sbeveloper 				fSwapInput = &swap_int24;
199bb1d6ef2Sbeveloper 				break;
200bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
201bb1d6ef2Sbeveloper 				fSwapInput = &swap_int32;
202bb1d6ef2Sbeveloper 				break;
203bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
204bb1d6ef2Sbeveloper 				fSwapInput = &swap_float32;
205bb1d6ef2Sbeveloper 				break;
206bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT64:
207bb1d6ef2Sbeveloper 				fSwapInput = &swap_float64;
208bb1d6ef2Sbeveloper 				break;
209bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
210bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
211bb1d6ef2Sbeveloper 				fSwapInput = 0;
212bb1d6ef2Sbeveloper 				break;
213bb1d6ef2Sbeveloper 			default:
21416611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
215bb1d6ef2Sbeveloper 				break;
216bb1d6ef2Sbeveloper 		}
217bb1d6ef2Sbeveloper 	}
218bb1d6ef2Sbeveloper 
219bb1d6ef2Sbeveloper 	// setup output swapping function
220bb1d6ef2Sbeveloper 	if (ioDecodedFormat->u.raw_audio.byte_order == B_MEDIA_HOST_ENDIAN) {
221bb1d6ef2Sbeveloper 		fSwapOutput = 0;
222bb1d6ef2Sbeveloper 	} else {
223bb1d6ef2Sbeveloper 		switch (ioDecodedFormat->u.raw_audio.format) {
224bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT16:
225bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int16;
226bb1d6ef2Sbeveloper 				break;
227bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT32:
228bb1d6ef2Sbeveloper 				fSwapOutput = &swap_int32;
229bb1d6ef2Sbeveloper 				break;
230bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_FLOAT32:
231bb1d6ef2Sbeveloper 				fSwapOutput = &swap_float32;
232bb1d6ef2Sbeveloper 				break;
233bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_UINT8:
234bb1d6ef2Sbeveloper 			case B_AUDIO_FORMAT_INT8:
235bb1d6ef2Sbeveloper 				fSwapOutput = 0;
236bb1d6ef2Sbeveloper 				break;
237bb1d6ef2Sbeveloper 			default:
23816611de7Sbeveloper 				debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
239bb1d6ef2Sbeveloper 				break;
240bb1d6ef2Sbeveloper 		}
241bb1d6ef2Sbeveloper 	}
242bb1d6ef2Sbeveloper 
243bb1d6ef2Sbeveloper 	// setup sample conversation function
244bb1d6ef2Sbeveloper 	switch (fInputFormat.u.raw_audio.format & B_AUDIO_FORMAT_MASK) {
245bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_UINT8:
246bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
247bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
248bb1d6ef2Sbeveloper 					fConvert = &uint8_to_uint8;
249bb1d6ef2Sbeveloper 					break;
250bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
251bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int8;
252bb1d6ef2Sbeveloper 					break;
253bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
254bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int16;
255bb1d6ef2Sbeveloper 					break;
256bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
257bb1d6ef2Sbeveloper 					fConvert = &uint8_to_int32;
258bb1d6ef2Sbeveloper 					break;
259bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
260bb1d6ef2Sbeveloper 					fConvert = &uint8_to_float32;
261bb1d6ef2Sbeveloper 					break;
262bb1d6ef2Sbeveloper 				default:
26316611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
264bb1d6ef2Sbeveloper 					break;
265bb1d6ef2Sbeveloper 			}
266bb1d6ef2Sbeveloper 			break;
267bb1d6ef2Sbeveloper 
268bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT8:
269bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
270bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
271bb1d6ef2Sbeveloper 					fConvert = &int8_to_uint8;
272bb1d6ef2Sbeveloper 					break;
273bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
274bb1d6ef2Sbeveloper 					fConvert = &int8_to_int8;
275bb1d6ef2Sbeveloper 					break;
276bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
277bb1d6ef2Sbeveloper 					fConvert = &int8_to_int16;
278bb1d6ef2Sbeveloper 					break;
279bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
280bb1d6ef2Sbeveloper 					fConvert = &int8_to_int32;
281bb1d6ef2Sbeveloper 					break;
282bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
283bb1d6ef2Sbeveloper 					fConvert = &int8_to_float32;
284bb1d6ef2Sbeveloper 					break;
285bb1d6ef2Sbeveloper 				default:
28616611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
287bb1d6ef2Sbeveloper 					break;
288bb1d6ef2Sbeveloper 			}
289bb1d6ef2Sbeveloper 			break;
290bb1d6ef2Sbeveloper 
291bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT16:
292bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
293bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
294bb1d6ef2Sbeveloper 					fConvert = &int16_to_uint8;
295bb1d6ef2Sbeveloper 					break;
296bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
297bb1d6ef2Sbeveloper 					fConvert = &int16_to_int8;
298bb1d6ef2Sbeveloper 					break;
299bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
300bb1d6ef2Sbeveloper 					fConvert = &int16_to_int16;
301bb1d6ef2Sbeveloper 					break;
302bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
303bb1d6ef2Sbeveloper 					fConvert = &int16_to_int32;
304bb1d6ef2Sbeveloper 					break;
305bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
306bb1d6ef2Sbeveloper 					fConvert = &int16_to_float32;
307bb1d6ef2Sbeveloper 					break;
308bb1d6ef2Sbeveloper 				default:
30916611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
310bb1d6ef2Sbeveloper 					break;
311bb1d6ef2Sbeveloper 			}
312bb1d6ef2Sbeveloper 			break;
313bb1d6ef2Sbeveloper 
314bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT24:
315bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
316bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
317bb1d6ef2Sbeveloper 					fConvert = &int24_to_uint8;
318bb1d6ef2Sbeveloper 					break;
319bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
320bb1d6ef2Sbeveloper 					fConvert = &int24_to_int8;
321bb1d6ef2Sbeveloper 					break;
322bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
323bb1d6ef2Sbeveloper 					fConvert = &int24_to_int16;
324bb1d6ef2Sbeveloper 					break;
325bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
326bb1d6ef2Sbeveloper 					fConvert = &int24_to_int32;
327bb1d6ef2Sbeveloper 					break;
328bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
329bb1d6ef2Sbeveloper 					fConvert = &int24_to_float32;
330bb1d6ef2Sbeveloper 					break;
331bb1d6ef2Sbeveloper 				default:
33216611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
333bb1d6ef2Sbeveloper 					break;
334bb1d6ef2Sbeveloper 			}
335bb1d6ef2Sbeveloper 			break;
336bb1d6ef2Sbeveloper 
337bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_INT32:
338bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
339bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
340bb1d6ef2Sbeveloper 					fConvert = &int32_to_uint8;
341bb1d6ef2Sbeveloper 					break;
342bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
343bb1d6ef2Sbeveloper 					fConvert = &int32_to_int8;
344bb1d6ef2Sbeveloper 					break;
345bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
346bb1d6ef2Sbeveloper 					fConvert = &int32_to_int16;
347bb1d6ef2Sbeveloper 					break;
348bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
349bb1d6ef2Sbeveloper 					fConvert = &int32_to_int32;
350bb1d6ef2Sbeveloper 					break;
351bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
352bb1d6ef2Sbeveloper 					fConvert = &int32_to_float32;
353bb1d6ef2Sbeveloper 					break;
354bb1d6ef2Sbeveloper 				default:
35516611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
356bb1d6ef2Sbeveloper 					break;
357bb1d6ef2Sbeveloper 			}
358bb1d6ef2Sbeveloper 			break;
359bb1d6ef2Sbeveloper 
360bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT32:
361bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
362bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
363bb1d6ef2Sbeveloper 					fConvert = &float32_to_uint8;
364bb1d6ef2Sbeveloper 					break;
365bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
366bb1d6ef2Sbeveloper 					fConvert = &float32_to_int8;
367bb1d6ef2Sbeveloper 					break;
368bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
369bb1d6ef2Sbeveloper 					fConvert = &float32_to_int16;
370bb1d6ef2Sbeveloper 					break;
371bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
372bb1d6ef2Sbeveloper 					fConvert = &float32_to_int32;
373bb1d6ef2Sbeveloper 					break;
374bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
375bb1d6ef2Sbeveloper 					fConvert = &float32_to_float32;
376bb1d6ef2Sbeveloper 					break;
377bb1d6ef2Sbeveloper 				default:
37816611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
379bb1d6ef2Sbeveloper 					break;
380bb1d6ef2Sbeveloper 			}
381bb1d6ef2Sbeveloper 			break;
382bb1d6ef2Sbeveloper 
383bb1d6ef2Sbeveloper 		case B_AUDIO_FORMAT_FLOAT64:
384bb1d6ef2Sbeveloper 			switch (ioDecodedFormat->u.raw_audio.format) {
385bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_UINT8:
386bb1d6ef2Sbeveloper 					fConvert = &float64_to_uint8;
387bb1d6ef2Sbeveloper 					break;
388bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT8:
389bb1d6ef2Sbeveloper 					fConvert = &float64_to_int8;
390bb1d6ef2Sbeveloper 					break;
391bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT16:
392bb1d6ef2Sbeveloper 					fConvert = &float64_to_int16;
393bb1d6ef2Sbeveloper 					break;
394bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_INT32:
395bb1d6ef2Sbeveloper 					fConvert = &float64_to_int32;
396bb1d6ef2Sbeveloper 					break;
397bb1d6ef2Sbeveloper 				case B_AUDIO_FORMAT_FLOAT32:
398bb1d6ef2Sbeveloper 					fConvert = &float64_to_float32;
399bb1d6ef2Sbeveloper 					break;
400bb1d6ef2Sbeveloper 				default:
40116611de7Sbeveloper 					debugger("RawDecoder::NegotiateAudioOutputFormat unknown output format\n");
402bb1d6ef2Sbeveloper 					break;
403bb1d6ef2Sbeveloper 			}
404bb1d6ef2Sbeveloper 			break;
405bb1d6ef2Sbeveloper 
406bb1d6ef2Sbeveloper 		default:
40716611de7Sbeveloper 			debugger("RawDecoder::NegotiateAudioOutputFormat unknown input format\n");
408bb1d6ef2Sbeveloper 			break;
409bb1d6ef2Sbeveloper 	}
410bb1d6ef2Sbeveloper 
411bb1d6ef2Sbeveloper 	fChunkBuffer = 0;
412bb1d6ef2Sbeveloper 	fChunkSize = 0;
413bb1d6ef2Sbeveloper 	fStartTime = 0;
4144ba72fcdSbeveloper 
4154ba72fcdSbeveloper 	string_for_format(*ioDecodedFormat, s, sizeof(s));
416bb1d6ef2Sbeveloper 	TRACE("RawDecoder::NegotiateAudioOutputFormat leave: %s\n", s);
417*6736ae52Sbeveloper 
418*6736ae52Sbeveloper 	if (ioDecodedFormat->type == 0)
419*6736ae52Sbeveloper 		debugger("RawDecoder::NegotiateAudioOutputFormat ioDecodedFormat->type == 0");
420bb1d6ef2Sbeveloper /*
421bb1d6ef2Sbeveloper 	TRACE("fFrameRate              %ld\n", fFrameRate);
422bb1d6ef2Sbeveloper 	TRACE("fInputFrameSize         %ld\n", fInputFrameSize);
423bb1d6ef2Sbeveloper 	TRACE("fOutputFrameSize        %ld\n", fOutputFrameSize);
424bb1d6ef2Sbeveloper 	TRACE("fInputSampleSize        %ld\n", fInputSampleSize);
425bb1d6ef2Sbeveloper 	TRACE("fOutputSampleSize       %ld\n", fOutputSampleSize);
426bb1d6ef2Sbeveloper 	TRACE("fOutputBufferFrameCount %ld\n", fOutputBufferFrameCount);
427bb1d6ef2Sbeveloper 	TRACE("fSwapInput              %p\n", fSwapInput);
428bb1d6ef2Sbeveloper 	TRACE("fConvert                %p\n", fConvert);
429bb1d6ef2Sbeveloper 	TRACE("fSwapOutput             %p\n", fSwapOutput);
430bb1d6ef2Sbeveloper */
431ca16f5cbSbeveloper 	return B_OK;
432ca16f5cbSbeveloper }
433ca16f5cbSbeveloper 
434ca16f5cbSbeveloper 
435ca16f5cbSbeveloper status_t
436d8591482Sbeveloper RawDecoder::Seek(uint32 seekTo,
437bce1ab5eSbeveloper 				 int64 seekFrame, int64 *frame,
438bce1ab5eSbeveloper 				 bigtime_t seekTime, bigtime_t *time)
439ca16f5cbSbeveloper {
440bb1d6ef2Sbeveloper 	fChunkSize = 0;
441bb1d6ef2Sbeveloper 	fStartTime = *time;
442ca16f5cbSbeveloper 	return B_OK;
443ca16f5cbSbeveloper }
444ca16f5cbSbeveloper 
445ca16f5cbSbeveloper 
446ca16f5cbSbeveloper status_t
447ca16f5cbSbeveloper RawDecoder::Decode(void *buffer, int64 *frameCount,
448d8591482Sbeveloper 				   media_header *mediaHeader, media_decode_info *info /* = 0 */)
449ca16f5cbSbeveloper {
450bb1d6ef2Sbeveloper 	char *output_buffer = (char *)buffer;
451bb1d6ef2Sbeveloper 	mediaHeader->start_time = fStartTime;
452bb1d6ef2Sbeveloper 	*frameCount = 0;
453bb1d6ef2Sbeveloper 	while (*frameCount < fOutputBufferFrameCount) {
454bb1d6ef2Sbeveloper 		if (fChunkSize == 0) {
455bb1d6ef2Sbeveloper 			media_header mh;
4562d923d67Sbeveloper 			status_t err;
457bb1d6ef2Sbeveloper 			err = GetNextChunk((void **)&fChunkBuffer, &fChunkSize, &mh);
458bb1d6ef2Sbeveloper 			if (err != B_OK || fChunkSize < fInputFrameSize) {
459bb1d6ef2Sbeveloper 				fChunkSize = 0;
460bb1d6ef2Sbeveloper 				break;
461bb1d6ef2Sbeveloper 			}
462bb1d6ef2Sbeveloper 			if (fSwapInput)
463bb1d6ef2Sbeveloper 				fSwapInput(fChunkBuffer, fChunkSize / fInputSampleSize);
464bb1d6ef2Sbeveloper 			fStartTime = mh.start_time;
465bb1d6ef2Sbeveloper 			continue;
466bb1d6ef2Sbeveloper 		}
467bb1d6ef2Sbeveloper 		int32 frames = min_c(fOutputBufferFrameCount - *frameCount, fChunkSize / fInputFrameSize);
468bb1d6ef2Sbeveloper 		int32 samples = frames * fInputFormat.u.raw_audio.channel_count;
469bb1d6ef2Sbeveloper 		fConvert(output_buffer, fChunkBuffer, samples);
470bb1d6ef2Sbeveloper 		fChunkBuffer += frames * fInputFrameSize;
471bb1d6ef2Sbeveloper 		fChunkSize -= frames * fInputFrameSize;
472bb1d6ef2Sbeveloper 		output_buffer += frames * fOutputFrameSize;
473bb1d6ef2Sbeveloper 		*frameCount += frames;
474bb1d6ef2Sbeveloper 		fStartTime +=  (1000000LL * frames) / fFrameRate;
475bb1d6ef2Sbeveloper 	}
476bb1d6ef2Sbeveloper 	// XXX should change channel order here for
477bb1d6ef2Sbeveloper 	// B_AUDIO_FORMAT_CHANNEL_ORDER_WAVE and B_AUDIO_FORMAT_CHANNEL_ORDER_AIFF
4782d923d67Sbeveloper 
479bb1d6ef2Sbeveloper 	if (fSwapOutput)
480bb1d6ef2Sbeveloper 		fSwapOutput(buffer, *frameCount * fInputFormat.u.raw_audio.channel_count);
481bb1d6ef2Sbeveloper 	return *frameCount ? B_OK : B_ERROR;
482ca16f5cbSbeveloper }
483ca16f5cbSbeveloper 
484ca16f5cbSbeveloper 
485ca16f5cbSbeveloper Decoder *
486fa8dbc01Sshatty RawDecoderPlugin::NewDecoder(uint index)
487ca16f5cbSbeveloper {
488ca16f5cbSbeveloper 	return new RawDecoder;
489ca16f5cbSbeveloper }
490ca16f5cbSbeveloper 
491fa8dbc01Sshatty 
492fa8dbc01Sshatty static media_format raw_formats[2];
493fa8dbc01Sshatty 
494bce1ab5eSbeveloper status_t
495fa8dbc01Sshatty RawDecoderPlugin::GetSupportedFormats(media_format ** formats, size_t * count)
496bce1ab5eSbeveloper {
497fa8dbc01Sshatty 	BMediaFormats mediaFormats;
498a0a20160SAxel Dörfler 	media_format_description description;
499a0a20160SAxel Dörfler 	media_format format;
500a0a20160SAxel Dörfler 
501a0a20160SAxel Dörfler 	// audio decoder
502a0a20160SAxel Dörfler 
50340d68dd2Sbeveloper 	description.family = B_BEOS_FORMAT_FAMILY;
504a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_AUDIO;
50540d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_AUDIO;
50640d68dd2Sbeveloper 	format.u.raw_audio = media_multi_audio_format::wildcard;
507a0a20160SAxel Dörfler 
508fa8dbc01Sshatty 	status_t status = mediaFormats.MakeFormatFor(&description, 1, &format);
509a0a20160SAxel Dörfler 	if (status < B_OK)
510a0a20160SAxel Dörfler 		return status;
511fa8dbc01Sshatty 	raw_formats[0] = format;
512a0a20160SAxel Dörfler 
513a0a20160SAxel Dörfler 	// video decoder
514a0a20160SAxel Dörfler 
515a0a20160SAxel Dörfler 	description.u.beos.format = B_BEOS_FORMAT_RAW_VIDEO;
51640d68dd2Sbeveloper 	format.type = B_MEDIA_RAW_VIDEO;
51740d68dd2Sbeveloper 	format.u.raw_video = media_raw_video_format::wildcard;
518a0a20160SAxel Dörfler 
519fa8dbc01Sshatty 	status = mediaFormats.MakeFormatFor(&description, 1, &format);
520fa8dbc01Sshatty 	if (status < B_OK)
521fa8dbc01Sshatty 		return status;
522fa8dbc01Sshatty 	raw_formats[1] = format;
523fa8dbc01Sshatty 
524fa8dbc01Sshatty 	*formats = raw_formats;
525fa8dbc01Sshatty 	*count = 2;
526fa8dbc01Sshatty 
527fa8dbc01Sshatty 	return B_OK;
528bce1ab5eSbeveloper }
529ca16f5cbSbeveloper 
530ca16f5cbSbeveloper MediaPlugin *instantiate_plugin()
531ca16f5cbSbeveloper {
532ca16f5cbSbeveloper 	return new RawDecoderPlugin;
533ca16f5cbSbeveloper }
534