1 // Copyright 1999, Be Incorporated. All Rights Reserved. 2 // Copyright 2000-2004, Jun Suzuki. All Rights Reserved. 3 // Copyright 2007, Stephan Aßmus. All Rights Reserved. 4 // Copyright 2010, Haiku, Inc. All Rights Reserved. 5 // This file may be used under the terms of the Be Sample Code License. 6 7 8 #include "MediaFileInfo.h" 9 10 #include <Catalog.h> 11 #include <MediaTrack.h> 12 #include <stdio.h> 13 14 #undef B_TRANSLATE_CONTEXT 15 #define B_TRANSLATE_CONTEXT "MediaFileInfo" 16 17 MediaFileInfo::MediaFileInfo(BMediaFile* file) 18 { 19 LoadInfo(file); 20 } 21 22 23 status_t 24 MediaFileInfo::LoadInfo(BMediaFile* file) 25 { 26 _Reset(); 27 if (!file) 28 return B_BAD_VALUE; 29 30 BMediaTrack* track; 31 media_format format; 32 memset(&format, 0, sizeof(format)); 33 media_codec_info codecInfo; 34 bool audioDone(false), videoDone(false); 35 bigtime_t audioDuration = 0; 36 bigtime_t videoDuration = 0; 37 int32 tracks = file->CountTracks(); 38 int64 videoFrames = 0; 39 int64 audioFrames = 0; 40 status_t ret = B_OK; 41 42 for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) { 43 track = file->TrackAt(i); 44 ret = track->InitCheck(); 45 if (ret != B_OK) 46 return ret; 47 48 if (track != NULL) { 49 ret = track->EncodedFormat(&format); 50 if (ret != B_OK) 51 return ret; 52 53 if (format.IsVideo()) { 54 memset(&format, 0, sizeof(format)); 55 format.type = B_MEDIA_RAW_VIDEO; 56 57 ret = track->DecodedFormat(&format); 58 if (ret != B_OK) 59 return ret; 60 61 media_raw_video_format *rvf = &(format.u.raw_video); 62 63 ret = track->GetCodecInfo(&codecInfo); 64 if (ret != B_OK) 65 return ret; 66 67 video.format << codecInfo.pretty_name; 68 videoDuration = track->Duration(); 69 videoFrames = track->CountFrames(); 70 71 BString details; 72 snprintf(details.LockBuffer(256), 256, 73 B_TRANSLATE_COMMENT("%u x %u, %.2ffps / %Ld frames", 74 "Width x Height, fps / frames"), 75 format.Width(), format.Height(), 76 rvf->field_rate / rvf->interlace, videoFrames); 77 details.UnlockBuffer(); 78 video.details << details; 79 videoDone = true; 80 81 } else if (format.IsAudio()) { 82 memset(&format, 0, sizeof(format)); 83 format.type = B_MEDIA_RAW_AUDIO; 84 ret = track->DecodedFormat(&format); 85 if (ret != B_OK) 86 return ret; 87 88 media_raw_audio_format *raf = &(format.u.raw_audio); 89 char bytesPerSample = (char)(raf->format & 0xf); 90 91 BString details; 92 if (bytesPerSample == 1 || bytesPerSample == 2) { 93 snprintf(details.LockBuffer(16), 16, 94 B_TRANSLATE("%d bit "), bytesPerSample * 8); 95 } else { 96 snprintf(details.LockBuffer(16), 16, 97 B_TRANSLATE("%d byte "), bytesPerSample); 98 } 99 details.UnlockBuffer(); 100 audio.details << details; 101 102 ret = track->GetCodecInfo(&codecInfo); 103 if (ret != B_OK) 104 return ret; 105 106 audio.format << codecInfo.pretty_name; 107 audioDuration = track->Duration(); 108 audioFrames = track->CountFrames(); 109 110 BString channels; 111 if (raf->channel_count == 1) { 112 snprintf(channels.LockBuffer(64), 64, 113 B_TRANSLATE("%.1f kHz mono / %lld frames"), 114 raf->frame_rate / 1000.f, audioFrames); 115 } else if (raf->channel_count == 2) { 116 snprintf(channels.LockBuffer(64), 64, 117 B_TRANSLATE("%.1f kHz stereo / %lld frames"), 118 raf->frame_rate / 1000.f, audioFrames); 119 } else { 120 snprintf(channels.LockBuffer(64), 64, 121 B_TRANSLATE("%.1f kHz %ld channel / %lld frames"), 122 raf->frame_rate / 1000.f, raf->channel_count, audioFrames); 123 } 124 channels.UnlockBuffer(); 125 audio.details << channels; 126 127 audioDone = true; 128 } 129 ret = file->ReleaseTrack(track); 130 if (ret != B_OK) 131 return ret; 132 } 133 } 134 135 useconds = MAX(audioDuration, videoDuration); 136 duration << (int32)(useconds / 1000000) 137 << B_TRANSLATE(" seconds"); 138 139 return B_OK; 140 } 141 142 143 void 144 MediaFileInfo::_Reset() 145 { 146 audio.details.SetTo(""); 147 audio.format.SetTo(""); 148 video.details.SetTo(""); 149 video.format.SetTo(""); 150 useconds = 0; 151 duration.SetTo(""); 152 } 153