xref: /haiku/src/apps/mediaplayer/supplier/MediaTrackAudioSupplier.cpp (revision f09ba8ea46ba2f4e482d7cd03e8eb77f37a60663)
1 /*
2  * Copyright 2007, Haiku. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Stephan Aßmus <superstippi@gmx.de>
7  */
8 #include "MediaTrackAudioSupplier.h"
9 
10 #include <new>
11 #include <stdio.h>
12 #include <string.h>
13 
14 #include <MediaTrack.h>
15 
16 using std::nothrow;
17 
18 // constructor
19 MediaTrackAudioSupplier::MediaTrackAudioSupplier(BMediaTrack* track)
20 	: AudioSupplier()
21 	, fMediaTrack(track)
22 
23 	, fPerformanceTime(0)
24 	, fDuration(0)
25 {
26 	if (!fMediaTrack) {
27 		printf("MediaTrackAudioSupplier() - no media track\n");
28 		return;
29 	}
30 
31 	fFormat.u.raw_audio = media_multi_audio_format::wildcard;
32 	#ifdef __HAIKU__
33 	  fFormat.u.raw_audio.format = media_multi_audio_format::B_AUDIO_FLOAT;
34 	#endif
35 	status_t ret = fMediaTrack->DecodedFormat(&fFormat);
36 	if (ret < B_OK) {
37 		printf("MediaTrackAudioSupplier() - "
38 			"fMediaTrack->DecodedFormat(): %s\n", strerror(ret));
39 		return;
40 	}
41 
42 	fDuration = fMediaTrack->Duration();
43 //
44 //	for (bigtime_t time = 0; time < fDuration; time += 10000) {
45 //		bigtime_t keyFrameTime = time;
46 //		fMediaTrack->FindKeyFrameForTime(&keyFrameTime,
47 //			B_MEDIA_SEEK_CLOSEST_BACKWARD);
48 //		printf("audio keyframe time for time: %lld -> %lld\n", time, keyFrameTime);
49 //	}
50 }
51 
52 // destructor
53 MediaTrackAudioSupplier::~MediaTrackAudioSupplier()
54 {
55 }
56 
57 
58 media_format
59 MediaTrackAudioSupplier::Format() const
60 {
61 	return fFormat;
62 }
63 
64 
65 status_t
66 MediaTrackAudioSupplier::GetEncodedFormat(media_format* format) const
67 {
68 	if (!fMediaTrack)
69 		return B_NO_INIT;
70 	return fMediaTrack->EncodedFormat(format);
71 }
72 
73 
74 status_t
75 MediaTrackAudioSupplier::GetCodecInfo(media_codec_info* info) const
76 {
77 	if (!fMediaTrack)
78 		return B_NO_INIT;
79 	return fMediaTrack->GetCodecInfo(info);
80 }
81 
82 
83 status_t
84 MediaTrackAudioSupplier::ReadFrames(void* buffer, int64* framesRead,
85 	bigtime_t* performanceTime)
86 {
87 	if (!fMediaTrack)
88 		return B_NO_INIT;
89 	if (!buffer || !framesRead)
90 		return B_BAD_VALUE;
91 
92 	media_header mediaHeader;
93 	status_t ret = fMediaTrack->ReadFrames(buffer, framesRead, &mediaHeader);
94 
95 	if (ret < B_OK) {
96 		// further analyse the error
97 		if (fDuration == 0 || (double)fPerformanceTime / fDuration > 0.95) {
98 			// some codecs don't behave well, or maybe somes files are bad,
99 			// they don't report the end of the stream correctly
100 			// NOTE: "more than 95% of the stream" is of course pure guess,
101 			// but it fixed the problem I had with some files
102 			ret = B_LAST_BUFFER_ERROR;
103 		}
104 		printf("MediaTrackAudioSupplier::ReadFrame() - "
105 			"error while reading frames: %s\n", strerror(ret));
106 	} else {
107 		fPerformanceTime = mediaHeader.start_time;
108 	}
109 
110 	if (performanceTime)
111 		*performanceTime = fPerformanceTime;
112 
113 	return ret;
114 }
115 
116 
117 status_t
118 MediaTrackAudioSupplier::SeekToTime(bigtime_t* performanceTime)
119 {
120 	if (!fMediaTrack)
121 		return B_NO_INIT;
122 
123 bigtime_t _performanceTime = *performanceTime;
124 	status_t ret = fMediaTrack->SeekToTime(performanceTime);
125 	if (ret == B_OK) {
126 printf("seeked: %lld -> %lld\n", _performanceTime, *performanceTime);
127 		fPerformanceTime = *performanceTime;
128 	}
129 
130 	return ret;
131 }
132 
133