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