xref: /haiku/src/kits/media/MediaTrack.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /***********************************************************************
2  * AUTHOR: Marcus Overhagen
3  *   FILE: MediaTrack.cpp
4  *  DESCR:
5  ***********************************************************************/
6 
7 #define __BUILDING_MEDIA_TRACK_CPP
8 
9 #include <MediaTrack.h>
10 #include <Roster.h>
11 #include <string.h>
12 #include "MediaExtractor.h"
13 #include "PluginManager.h"
14 #include "ReaderPlugin.h"
15 #include "debug.h"
16 
17 #define CONVERT_TO_INT32 0 // XXX test! this triggers a few bugs!
18 
19 // flags used for workarounds
20 enum {
21 	FORCE_RAW_AUDIO 				= 0x0001,
22 	FORCE_RAW_VIDEO 				= 0x0002,
23 	FORCE_RAW_AUDIO_INT16_FORMAT 	= 0x0010,
24 	FORCE_RAW_AUDIO_INT32_FORMAT 	= 0x0020,
25 	FORCE_RAW_AUDIO_FLOAT_FORMAT 	= 0x0040,
26 	FORCE_RAW_AUDIO_HOST_ENDIAN 	= 0x0100,
27 	IGNORE_ENCODED_AUDIO 			= 0x1000,
28 	IGNORE_ENCODED_VIDEO 			= 0x2000,
29 };
30 
31 #define B_MEDIA_DISABLE_FORMAT_TRANSLATION 0x4000 // XXX move this (after name change?) to MediaDefs.h
32 
33 class RawDecoderChunkProvider : public ChunkProvider
34 {
35 public:
36 				RawDecoderChunkProvider(Decoder *decoder, int buffer_size, int frame_size);
37 	virtual 	~RawDecoderChunkProvider();
38 
39 	status_t	GetNextChunk(void **chunkBuffer, int32 *chunkSize, media_header *mediaHeader);
40 
41 private:
42 	Decoder *fDecoder;
43 	void *fBuffer;
44 	int	fBufferSize;
45 	int	fFrameSize;
46 };
47 
48 
49 /*************************************************************
50  * protected BMediaTrack
51  *************************************************************/
52 
53 BMediaTrack::~BMediaTrack()
54 {
55 	CALLED();
56 	if (fRawDecoder)
57 		_DestroyDecoder(fRawDecoder);
58 	if (fDecoder)
59 		_DestroyDecoder(fDecoder);
60 }
61 
62 /*************************************************************
63  * public BMediaTrack
64  *************************************************************/
65 
66 status_t
67 BMediaTrack::InitCheck() const
68 {
69 	CALLED();
70 	return fErr;
71 }
72 
73 
74 status_t
75 BMediaTrack::GetCodecInfo(media_codec_info *mci) const
76 {
77 	CALLED();
78 	if (!fDecoder)
79 		return B_NO_INIT;
80 
81 	*mci = fMCI;
82 	snprintf(mci->pretty_name, sizeof(mci->pretty_name), "OpenBeOS Media Kit:\n%s", fMCI.pretty_name);
83 
84 	return B_OK;
85 }
86 
87 
88 status_t
89 BMediaTrack::EncodedFormat(media_format *out_format) const
90 {
91 	CALLED();
92 	if (!out_format)
93 		return B_BAD_VALUE;
94 	if (!fExtractor)
95 		return B_NO_INIT;
96 
97 	*out_format = *fExtractor->EncodedFormat(fStream);
98 
99 	char s[200];
100 	string_for_format(*out_format, s, sizeof(s));
101 	printf("BMediaTrack::EncodedFormat: %s\n", s);
102 
103 	return B_OK;
104 }
105 
106 
107 status_t
108 BMediaTrack::DecodedFormat(media_format *inout_format)
109 {
110 	return DecodedFormat(inout_format, 0);
111 }
112 
113 
114 status_t
115 BMediaTrack::DecodedFormat(media_format *inout_format, int32 flags)
116 {
117 	CALLED();
118 	if (!inout_format)
119 		return B_BAD_VALUE;
120 	if (!fExtractor || !fDecoder)
121 		return B_NO_INIT;
122 
123 	if (fRawDecoder) {
124 		_DestroyDecoder(fRawDecoder);
125 		fRawDecoder = 0;
126 	}
127 
128 	char s[200];
129 
130 	string_for_format(*inout_format, s, sizeof(s));
131 	printf("BMediaTrack::DecodedFormat: req1: %s\n", s);
132 
133 	if ((fWorkaroundFlags & FORCE_RAW_AUDIO) || ((fWorkaroundFlags & IGNORE_ENCODED_AUDIO) && inout_format->type == B_MEDIA_ENCODED_AUDIO)) {
134 		inout_format->type = B_MEDIA_RAW_AUDIO;
135 		inout_format->u.raw_audio = media_multi_audio_format::wildcard;
136 	}
137 	if ((fWorkaroundFlags & FORCE_RAW_VIDEO) || ((fWorkaroundFlags & IGNORE_ENCODED_VIDEO) && inout_format->type == B_MEDIA_ENCODED_VIDEO)) {
138 		inout_format->type = B_MEDIA_RAW_VIDEO;
139 		inout_format->u.raw_video = media_raw_video_format::wildcard;
140 	}
141 	if (inout_format->type == B_MEDIA_RAW_AUDIO) {
142 		if (fWorkaroundFlags & FORCE_RAW_AUDIO_HOST_ENDIAN)
143 			inout_format->u.raw_audio.byte_order = B_MEDIA_HOST_ENDIAN;
144 		if (fWorkaroundFlags & FORCE_RAW_AUDIO_INT16_FORMAT)
145 			inout_format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_SHORT;
146 		if (fWorkaroundFlags & FORCE_RAW_AUDIO_INT32_FORMAT)
147 			inout_format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_INT;
148 		if (fWorkaroundFlags & FORCE_RAW_AUDIO_FLOAT_FORMAT)
149 			inout_format->u.raw_audio.format = media_raw_audio_format::B_AUDIO_FLOAT;
150 	}
151 
152 	string_for_format(*inout_format, s, sizeof(s));
153 	printf("BMediaTrack::DecodedFormat: req2: %s\n", s);
154 
155 	media_format requested_format = *inout_format;
156 
157 	status_t res;
158 
159 	res = fDecoder->NegotiateOutputFormat(inout_format);
160 
161 	string_for_format(*inout_format, s, sizeof(s));
162 	printf("BMediaTrack::DecodedFormat: nego: %s\n", s);
163 
164 	if (inout_format->type == 0)
165 		debugger("Decoder didn't set output format type");
166 	if (inout_format->type == B_MEDIA_RAW_AUDIO) {
167 		if (inout_format->u.raw_audio.byte_order == 0)
168 			debugger("Decoder didn't set raw audio output byte order");
169 		if (inout_format->u.raw_audio.format == 0)
170 			debugger("Decoder didn't set raw audio output sample format");
171 		if (inout_format->u.raw_audio.buffer_size <= 0)
172 			debugger("Decoder didn't set raw audio output buffer size");
173 	}
174 	if (inout_format->type == B_MEDIA_RAW_VIDEO) {
175 		if (inout_format->u.raw_video.display.format == 0)
176 			debugger("Decoder didn't set raw video output color space");
177 		if (inout_format->u.raw_video.display.line_width == 0)
178 			debugger("Decoder didn't set raw video output line_width");
179 		if (inout_format->u.raw_video.display.line_count == 0)
180 			debugger("Decoder didn't set raw video output line_count");
181 		if (inout_format->u.raw_video.display.bytes_per_row == 0)
182 			debugger("Decoder didn't set raw video output bytes_per_row");
183 	}
184 
185 	if (0 == (flags & B_MEDIA_DISABLE_FORMAT_TRANSLATION)) {
186 		if (requested_format.type == B_MEDIA_RAW_AUDIO
187 			&& inout_format->type == B_MEDIA_RAW_AUDIO
188 			&& requested_format.u.raw_audio.format != 0
189 			&& requested_format.u.raw_audio.format != inout_format->u.raw_audio.format) {
190 				if (SetupFormatTranslation(*inout_format, &requested_format)) {
191 					*inout_format = requested_format;
192 				}
193 		}
194 	}
195 
196 //	string_for_format(*inout_format, s, sizeof(s));
197 //	printf("BMediaTrack::DecodedFormat: res: %s\n", s);
198 
199 	return res;
200 }
201 
202 
203 int64
204 BMediaTrack::CountFrames() const
205 {
206 	CALLED();
207 	int64 frames = fExtractor ? fExtractor->CountFrames(fStream) : 0;
208 	printf("BMediaTrack::CountFrames: %Ld\n", frames);
209 	return frames;
210 }
211 
212 
213 bigtime_t
214 BMediaTrack::Duration() const
215 {
216 	CALLED();
217 	bigtime_t duration = fExtractor ? fExtractor->Duration(fStream) : 0;
218 	printf("BMediaTrack::Duration: %Ld\n", duration);
219 	return duration;
220 }
221 
222 
223 int64
224 BMediaTrack::CurrentFrame() const
225 {
226 	return fCurFrame;
227 }
228 
229 
230 bigtime_t
231 BMediaTrack::CurrentTime() const
232 {
233 	return fCurTime;
234 }
235 
236 
237 status_t
238 BMediaTrack::ReadFrames(void *out_buffer,
239 						int64 *out_frameCount,
240 						media_header *mh)
241 {
242 	return ReadFrames(out_buffer, out_frameCount, mh, 0);
243 }
244 
245 
246 status_t
247 BMediaTrack::ReadFrames(void *out_buffer,
248 						int64 *out_frameCount,
249 						media_header *mh /* = 0 */,
250 						media_decode_info *info /* = 0 */)
251 {
252 //	CALLED();
253 	if (!fDecoder)
254 		return B_NO_INIT;
255 	if (!out_buffer || !out_frameCount)
256 		return B_BAD_VALUE;
257 
258 	status_t result;
259 	media_header header;
260 
261 	memset(&header, 0, sizeof(header)); // always clear it first, as the decoder doesn't set all fields
262 
263 	if (fRawDecoder)
264 		result = fRawDecoder->Decode(out_buffer, out_frameCount, &header, info);
265 	else
266 		result = fDecoder->Decode(out_buffer, out_frameCount, &header, info);
267 	if (result == B_OK) {
268 		fCurFrame += *out_frameCount;
269 		fCurTime = header.start_time;
270 	} else {
271 		printf("BMediaTrack::ReadFrames: decoder returned error 0x%08lx (%s)\n", result, strerror(result));
272 		*out_frameCount = 0;
273 	}
274 	if (mh)
275 		*mh = header;
276 
277 //	printf("BMediaTrack::ReadFrames: %Ld frames, start-time %Ld\n", *out_frameCount, header.start_time);
278 
279 	return result;
280 }
281 
282 
283 status_t
284 BMediaTrack::ReplaceFrames(const void *in_buffer,
285 						   int64 *io_frameCount,
286 						   const media_header *mh)
287 {
288 	UNIMPLEMENTED();
289 
290 	return B_OK;
291 }
292 
293 
294 status_t
295 BMediaTrack::SeekToTime(bigtime_t *inout_time,
296 						int32 flags)
297 {
298 	CALLED();
299 	if (!fDecoder || !fExtractor)
300 		return B_NO_INIT;
301 	if (!inout_time)
302 		return B_BAD_VALUE;
303 
304 	status_t result;
305 	uint32 seekTo;
306 	bigtime_t seekTime;
307 
308 	int64 frame;
309 	bigtime_t time;
310 
311 	seekTo = (flags & B_MEDIA_SEEK_DIRECTION_MASK) | B_MEDIA_SEEK_TO_TIME;
312 	seekTime = *inout_time;
313 
314 	time = seekTime;
315 	result = fExtractor->Seek(fStream, seekTo, &frame, &time);
316 	if (result != B_OK) {
317 		printf("BMediaTrack::SeekToTime: extractor seek failed\n");
318 		return result;
319 	}
320 
321 	result = fDecoder->Seek(seekTo, 0, &frame, seekTime, &time);
322 	if (result != B_OK) {
323 		printf("BMediaTrack::SeekToTime: decoder seek failed\n");
324 		return result;
325 	}
326 
327 	if (fRawDecoder) {
328 		result = fRawDecoder->Seek(seekTo, 0, &frame, seekTime, &time);
329 		if (result != B_OK) {
330 			printf("BMediaTrack::SeekToTime: raw decoder seek failed\n");
331 			return result;
332 		}
333 	}
334 
335 	*inout_time = time;
336 	fCurFrame = frame;
337 	fCurTime = time;
338 
339 	printf("BMediaTrack::SeekToTime finished, requested %.6f, result %.6f\n", seekTime / 1000000.0, *inout_time / 1000000.0);
340 
341 	return B_OK;
342 }
343 
344 
345 status_t
346 BMediaTrack::SeekToFrame(int64 *inout_frame,
347 						 int32 flags)
348 {
349 	CALLED();
350 	if (!fDecoder || !fExtractor)
351 		return B_NO_INIT;
352 	if (!inout_frame)
353 		return B_BAD_VALUE;
354 
355 	status_t result;
356 	uint32 seekTo;
357 	int64 seekFrame;
358 
359 	int64 frame;
360 	bigtime_t time;
361 
362 	seekTo = (flags & B_MEDIA_SEEK_DIRECTION_MASK) | B_MEDIA_SEEK_TO_FRAME;
363 	seekFrame = *inout_frame;
364 
365 	frame = seekFrame;
366 	result = fExtractor->Seek(fStream, seekTo, &frame, &time);
367 	if (result != B_OK) {
368 		printf("BMediaTrack::SeekToFrame: extractor seek failed\n");
369 		return result;
370 	}
371 
372 	result = fDecoder->Seek(seekTo, seekFrame, &frame, 0, &time);
373 	if (result != B_OK) {
374 		return result;
375 		printf("BMediaTrack::SeekToFrame: decoder seek failed\n");
376 	}
377 
378 	if (fRawDecoder) {
379 		result = fRawDecoder->Seek(seekTo, seekFrame, &frame, 0, &time);
380 		if (result != B_OK) {
381 			printf("BMediaTrack::SeekToFrame: raw decoder seek failed\n");
382 			return result;
383 		}
384 	}
385 
386 	*inout_frame = frame;
387 	fCurFrame = frame;
388 	fCurTime = time;
389 
390 	printf("BMediaTrack::SeekToTime SeekToFrame, requested %Ld, result %Ld\n", seekFrame, *inout_frame);
391 
392 	return B_OK;
393 }
394 
395 
396 status_t
397 BMediaTrack::FindKeyFrameForTime(bigtime_t *inout_time,
398 								 int32 flags) const
399 {
400 	UNIMPLEMENTED();
401 
402 	return B_OK;
403 }
404 
405 
406 status_t
407 BMediaTrack::FindKeyFrameForFrame(int64 *inout_frame,
408 								  int32 flags) const
409 {
410 	UNIMPLEMENTED();
411 
412 	return B_OK;
413 }
414 
415 
416 status_t
417 BMediaTrack::ReadChunk(char **out_buffer,
418 					   int32 *out_size,
419 					   media_header *mh /* = 0 */)
420 {
421 	CALLED();
422 	if (!fExtractor)
423 		return B_NO_INIT;
424 	if (!out_buffer || !out_size)
425 		return B_BAD_VALUE;
426 
427 	status_t result;
428 	media_header header;
429 
430 	memset(&header, 0, sizeof(header)); // always clear it first, as the reader doesn't set all fields
431 
432 	result = fExtractor->GetNextChunk(fStream, (void **)out_buffer, out_size, &header);
433 
434 	fCurTime = header.start_time;
435 	if (mh)
436 		*mh = header;
437 
438 	return result;
439 }
440 
441 
442 status_t
443 BMediaTrack::AddCopyright(const char *data)
444 {
445 	UNIMPLEMENTED();
446 
447 	return B_OK;
448 }
449 
450 
451 status_t
452 BMediaTrack::AddTrackInfo(uint32 code,
453 						  const void *data,
454 						  size_t size,
455 						  uint32 flags)
456 {
457 	UNIMPLEMENTED();
458 
459 	return B_OK;
460 }
461 
462 
463 status_t
464 BMediaTrack::WriteFrames(const void *data,
465 						 int32 num_frames,
466 						 int32 flags)
467 {
468 	UNIMPLEMENTED();
469 
470 	return B_OK;
471 }
472 
473 
474 status_t
475 BMediaTrack::WriteFrames(const void *data,
476 						 int64 num_frames,
477 						 media_encode_info *info)
478 {
479 	UNIMPLEMENTED();
480 
481 	return B_OK;
482 }
483 
484 
485 status_t
486 BMediaTrack::WriteChunk(const void *data,
487 						size_t size,
488 						uint32 flags)
489 {
490 	UNIMPLEMENTED();
491 
492 	return B_OK;
493 }
494 
495 
496 status_t
497 BMediaTrack::WriteChunk(const void *data,
498 						size_t size,
499 						media_encode_info *info)
500 {
501 	UNIMPLEMENTED();
502 
503 	return B_OK;
504 }
505 
506 
507 status_t
508 BMediaTrack::Flush()
509 {
510 	UNIMPLEMENTED();
511 
512 	return B_OK;
513 }
514 
515 
516 BParameterWeb *
517 BMediaTrack::Web()
518 {
519 	UNIMPLEMENTED();
520 	return NULL;
521 }
522 
523 
524 status_t
525 BMediaTrack::GetParameterValue(int32 id,
526 							   void *valu,
527 							   size_t *size)
528 {
529 	UNIMPLEMENTED();
530 
531 	return B_ERROR;
532 }
533 
534 
535 status_t
536 BMediaTrack::SetParameterValue(int32 id,
537 							   const void *valu,
538 							   size_t size)
539 {
540 	UNIMPLEMENTED();
541 
542 	return B_ERROR;
543 }
544 
545 
546 BView *
547 BMediaTrack::GetParameterView()
548 {
549 	UNIMPLEMENTED();
550 	return NULL;
551 }
552 
553 
554 status_t
555 BMediaTrack::GetQuality(float *quality)
556 {
557 	UNIMPLEMENTED();
558 
559 	return B_ERROR;
560 }
561 
562 
563 status_t
564 BMediaTrack::SetQuality(float quality)
565 {
566 	UNIMPLEMENTED();
567 
568 	return B_ERROR;
569 }
570 
571 
572 status_t
573 BMediaTrack::GetEncodeParameters(encode_parameters *parameters) const
574 {
575 	UNIMPLEMENTED();
576 
577 	return B_ERROR;
578 }
579 
580 
581 status_t
582 BMediaTrack::SetEncodeParameters(encode_parameters *parameters)
583 {
584 	UNIMPLEMENTED();
585 
586 	return B_ERROR;
587 }
588 
589 
590 status_t
591 BMediaTrack::Perform(int32 selector,
592 					 void *data)
593 {
594 	UNIMPLEMENTED();
595 
596 	return B_ERROR;
597 }
598 
599 /*************************************************************
600  * private BMediaTrack
601  *************************************************************/
602 
603 BMediaTrack::BMediaTrack(BPrivate::media::MediaExtractor *extractor,
604 						 int32 stream)
605 {
606 	CALLED();
607 	fWorkaroundFlags = 0;
608 	fRawDecoder = 0;
609 	fExtractor = extractor;
610 	fStream = stream;
611 	fErr = B_OK;
612 
613 	SetupWorkaround();
614 
615 	if (fExtractor->CreateDecoder(fStream, &fDecoder, &fMCI) != B_OK) {
616 		ERROR("BMediaTrack::BMediaTrack: Error: creating decoder failed\n");
617 		// we do not set fErr here, because ReadChunk should still work
618 		fDecoder = 0;
619 		return;
620 	}
621 
622 	fCurFrame = 0;
623 	fCurTime = 0;
624 
625 	// not used:
626 	fEncoder = 0;
627 	fEncoderID = 0;
628 	fWriter = 0;
629 }
630 
631 
632 BMediaTrack::BMediaTrack(BPrivate::MediaWriter *writer,
633 						 int32 stream_num,
634 						 media_format *in_format,
635 						 BPrivate::media::Encoder *encoder,
636 						 media_codec_info *mci)
637 {
638 	UNIMPLEMENTED();
639 }
640 
641 void
642 BMediaTrack::SetupWorkaround()
643 {
644 	app_info	ainfo;
645 	thread_info	tinfo;
646 
647 	get_thread_info(find_thread(0), &tinfo);
648 	be_roster->GetRunningAppInfo(tinfo.team, &ainfo);
649 
650 	if (strcmp(ainfo.signature, "application/x-vnd.marcone-soundplay") == 0) {
651 		fWorkaroundFlags = FORCE_RAW_AUDIO | FORCE_RAW_AUDIO_INT16_FORMAT | FORCE_RAW_AUDIO_HOST_ENDIAN;
652 		printf("BMediaTrack::SetupWorkaround: SoundPlay workaround active\n");
653 	}
654 	if (strcmp(ainfo.signature, "application/x-vnd.Be.MediaPlayer") == 0) {
655 		fWorkaroundFlags = IGNORE_ENCODED_AUDIO | IGNORE_ENCODED_VIDEO;
656 		printf("BMediaTrack::SetupWorkaround: MediaPlayer workaround active\n");
657 	}
658 
659 #if CONVERT_TO_INT32 // XXX test
660 	if (!(fWorkaroundFlags & FORCE_RAW_AUDIO_INT16_FORMAT))
661 		fWorkaroundFlags |= FORCE_RAW_AUDIO_INT32_FORMAT;
662 #endif
663 }
664 
665 bool
666 BMediaTrack::SetupFormatTranslation(const media_format &from, media_format *to)
667 {
668 	char s[200];
669 	status_t res;
670 
671 	string_for_format(from, s, sizeof(s));
672 	printf("BMediaTrack::SetupFormatTranslation: from: %s\n", s);
673 
674 	res = _CreateDecoder(&fRawDecoder, from);
675 	if (res != B_OK) {
676 		printf("BMediaTrack::SetupFormatTranslation: _CreateDecoder failed\n");
677 		return false;
678 	}
679 
680 	// XXX video?
681 	int buffer_size = from.u.raw_audio.buffer_size;
682 	int frame_size = (from.u.raw_audio.format & 15) * from.u.raw_audio.channel_count;
683 
684 	fRawDecoder->Setup(new RawDecoderChunkProvider(fDecoder, buffer_size, frame_size));
685 
686 	media_format from_temp = from;
687 	res = fRawDecoder->Setup(&from_temp, 0, 0);
688 	if (res != B_OK) {
689 		printf("BMediaTrack::SetupFormatTranslation: Setup failed\n");
690 		goto error;
691 	}
692 
693 	string_for_format(*to, s, sizeof(s));
694 	printf("BMediaTrack::SetupFormatTranslation:   to: %s\n", s);
695 
696 	res = fRawDecoder->NegotiateOutputFormat(to);
697 	if (res != B_OK) {
698 		printf("BMediaTrack::SetupFormatTranslation: NegotiateOutputFormat failed\n");
699 		goto error;
700 	}
701 
702 	string_for_format(*to, s, sizeof(s));
703 	printf("BMediaTrack::SetupFormatTranslation:  res: %s\n", s);
704 
705 	return true;
706 
707 error:
708 	_DestroyDecoder(fRawDecoder);
709 	fRawDecoder = 0;
710 	return false;
711 }
712 
713 /*
714 // unimplemented
715 BMediaTrack::BMediaTrack()
716 BMediaTrack::BMediaTrack(const BMediaTrack &)
717 BMediaTrack &BMediaTrack::operator=(const BMediaTrack &)
718 */
719 
720 status_t BMediaTrack::_Reserved_BMediaTrack_0(int32 arg, ...) { return B_ERROR; }
721 status_t BMediaTrack::_Reserved_BMediaTrack_1(int32 arg, ...) { return B_ERROR; }
722 status_t BMediaTrack::_Reserved_BMediaTrack_2(int32 arg, ...) { return B_ERROR; }
723 status_t BMediaTrack::_Reserved_BMediaTrack_3(int32 arg, ...) { return B_ERROR; }
724 status_t BMediaTrack::_Reserved_BMediaTrack_4(int32 arg, ...) { return B_ERROR; }
725 status_t BMediaTrack::_Reserved_BMediaTrack_5(int32 arg, ...) { return B_ERROR; }
726 status_t BMediaTrack::_Reserved_BMediaTrack_6(int32 arg, ...) { return B_ERROR; }
727 status_t BMediaTrack::_Reserved_BMediaTrack_7(int32 arg, ...) { return B_ERROR; }
728 status_t BMediaTrack::_Reserved_BMediaTrack_8(int32 arg, ...) { return B_ERROR; }
729 status_t BMediaTrack::_Reserved_BMediaTrack_9(int32 arg, ...) { return B_ERROR; }
730 status_t BMediaTrack::_Reserved_BMediaTrack_10(int32 arg, ...) { return B_ERROR; }
731 status_t BMediaTrack::_Reserved_BMediaTrack_11(int32 arg, ...) { return B_ERROR; }
732 status_t BMediaTrack::_Reserved_BMediaTrack_12(int32 arg, ...) { return B_ERROR; }
733 status_t BMediaTrack::_Reserved_BMediaTrack_13(int32 arg, ...) { return B_ERROR; }
734 status_t BMediaTrack::_Reserved_BMediaTrack_14(int32 arg, ...) { return B_ERROR; }
735 status_t BMediaTrack::_Reserved_BMediaTrack_15(int32 arg, ...) { return B_ERROR; }
736 status_t BMediaTrack::_Reserved_BMediaTrack_16(int32 arg, ...) { return B_ERROR; }
737 status_t BMediaTrack::_Reserved_BMediaTrack_17(int32 arg, ...) { return B_ERROR; }
738 status_t BMediaTrack::_Reserved_BMediaTrack_18(int32 arg, ...) { return B_ERROR; }
739 status_t BMediaTrack::_Reserved_BMediaTrack_19(int32 arg, ...) { return B_ERROR; }
740 status_t BMediaTrack::_Reserved_BMediaTrack_20(int32 arg, ...) { return B_ERROR; }
741 status_t BMediaTrack::_Reserved_BMediaTrack_21(int32 arg, ...) { return B_ERROR; }
742 status_t BMediaTrack::_Reserved_BMediaTrack_22(int32 arg, ...) { return B_ERROR; }
743 status_t BMediaTrack::_Reserved_BMediaTrack_23(int32 arg, ...) { return B_ERROR; }
744 status_t BMediaTrack::_Reserved_BMediaTrack_24(int32 arg, ...) { return B_ERROR; }
745 status_t BMediaTrack::_Reserved_BMediaTrack_25(int32 arg, ...) { return B_ERROR; }
746 status_t BMediaTrack::_Reserved_BMediaTrack_26(int32 arg, ...) { return B_ERROR; }
747 status_t BMediaTrack::_Reserved_BMediaTrack_27(int32 arg, ...) { return B_ERROR; }
748 status_t BMediaTrack::_Reserved_BMediaTrack_28(int32 arg, ...) { return B_ERROR; }
749 status_t BMediaTrack::_Reserved_BMediaTrack_29(int32 arg, ...) { return B_ERROR; }
750 status_t BMediaTrack::_Reserved_BMediaTrack_30(int32 arg, ...) { return B_ERROR; }
751 status_t BMediaTrack::_Reserved_BMediaTrack_31(int32 arg, ...) { return B_ERROR; }
752 status_t BMediaTrack::_Reserved_BMediaTrack_32(int32 arg, ...) { return B_ERROR; }
753 status_t BMediaTrack::_Reserved_BMediaTrack_33(int32 arg, ...) { return B_ERROR; }
754 status_t BMediaTrack::_Reserved_BMediaTrack_34(int32 arg, ...) { return B_ERROR; }
755 status_t BMediaTrack::_Reserved_BMediaTrack_35(int32 arg, ...) { return B_ERROR; }
756 status_t BMediaTrack::_Reserved_BMediaTrack_36(int32 arg, ...) { return B_ERROR; }
757 status_t BMediaTrack::_Reserved_BMediaTrack_37(int32 arg, ...) { return B_ERROR; }
758 status_t BMediaTrack::_Reserved_BMediaTrack_38(int32 arg, ...) { return B_ERROR; }
759 status_t BMediaTrack::_Reserved_BMediaTrack_39(int32 arg, ...) { return B_ERROR; }
760 status_t BMediaTrack::_Reserved_BMediaTrack_40(int32 arg, ...) { return B_ERROR; }
761 status_t BMediaTrack::_Reserved_BMediaTrack_41(int32 arg, ...) { return B_ERROR; }
762 status_t BMediaTrack::_Reserved_BMediaTrack_42(int32 arg, ...) { return B_ERROR; }
763 status_t BMediaTrack::_Reserved_BMediaTrack_43(int32 arg, ...) { return B_ERROR; }
764 status_t BMediaTrack::_Reserved_BMediaTrack_44(int32 arg, ...) { return B_ERROR; }
765 status_t BMediaTrack::_Reserved_BMediaTrack_45(int32 arg, ...) { return B_ERROR; }
766 status_t BMediaTrack::_Reserved_BMediaTrack_46(int32 arg, ...) { return B_ERROR; }
767 status_t BMediaTrack::_Reserved_BMediaTrack_47(int32 arg, ...) { return B_ERROR; }
768 
769 
770 RawDecoderChunkProvider::RawDecoderChunkProvider(Decoder *decoder, int buffer_size, int frame_size)
771 {
772 //	printf("RawDecoderChunkProvider: buffer_size %d, frame_size %d\n", buffer_size, frame_size);
773 	fDecoder = decoder;
774 	fFrameSize = frame_size;
775 	fBufferSize = buffer_size;
776 	fBuffer = malloc(buffer_size);
777 }
778 
779 RawDecoderChunkProvider::~RawDecoderChunkProvider()
780 {
781 	free(fBuffer);
782 }
783 
784 status_t
785 RawDecoderChunkProvider::GetNextChunk(void **chunkBuffer, int32 *chunkSize,
786                                       media_header *mediaHeader)
787 {
788 	int64 frames;
789 	media_decode_info info;
790 	status_t res = fDecoder->Decode(fBuffer, &frames, mediaHeader, &info);
791 	if (res == B_OK) {
792 		*chunkBuffer = fBuffer;
793 		*chunkSize = frames * fFrameSize;
794 //		printf("RawDecoderChunkProvider::GetNextChunk, %Ld frames, %ld bytes, start-time %Ld\n", frames, *chunkSize, mediaHeader->start_time);
795 	} else {
796 		printf("RawDecoderChunkProvider::GetNextChunk failed\n");
797 	}
798 	return res;
799 }
800