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_TRANSLATION_CONTEXT 15 #define B_TRANSLATION_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 if (track == NULL) 45 return B_ERROR; 46 47 ret = track->InitCheck(); 48 if (ret != B_OK) 49 return ret; 50 51 ret = track->EncodedFormat(&format); 52 if (ret != B_OK) 53 return ret; 54 55 if (format.IsVideo()) { 56 memset(&format, 0, sizeof(format)); 57 format.type = B_MEDIA_RAW_VIDEO; 58 59 ret = track->DecodedFormat(&format); 60 if (ret != B_OK) 61 return ret; 62 63 media_raw_video_format *rvf = &(format.u.raw_video); 64 65 ret = track->GetCodecInfo(&codecInfo); 66 if (ret != B_OK) 67 return ret; 68 69 video.format << codecInfo.pretty_name; 70 videoDuration = track->Duration(); 71 videoFrames = track->CountFrames(); 72 73 BString details; 74 snprintf(details.LockBuffer(256), 256, 75 B_TRANSLATE_COMMENT("%u x %u, %.2ffps / %Ld frames", 76 "Width x Height, fps / frames"), 77 format.Width(), format.Height(), 78 rvf->field_rate / rvf->interlace, videoFrames); 79 details.UnlockBuffer(); 80 video.details << details; 81 videoDone = true; 82 83 } else if (format.IsAudio()) { 84 memset(&format, 0, sizeof(format)); 85 format.type = B_MEDIA_RAW_AUDIO; 86 ret = track->DecodedFormat(&format); 87 if (ret != B_OK) 88 return ret; 89 media_raw_audio_format *raf = &(format.u.raw_audio); 90 char bytesPerSample = (char)(raf->format & 0xf); 91 92 BString details; 93 if (bytesPerSample == 1 || bytesPerSample == 2) { 94 snprintf(details.LockBuffer(16), 16, 95 B_TRANSLATE("%d bit "), bytesPerSample * 8); 96 } else { 97 snprintf(details.LockBuffer(16), 16, 98 B_TRANSLATE("%d byte "), bytesPerSample); 99 } 100 details.UnlockBuffer(); 101 audio.details << details; 102 103 ret = track->GetCodecInfo(&codecInfo); 104 if (ret != B_OK) 105 return ret; 106 107 audio.format << codecInfo.pretty_name; 108 audioDuration = track->Duration(); 109 audioFrames = track->CountFrames(); 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 useconds = MAX(audioDuration, videoDuration); 135 duration << (int32)(useconds / 1000000) 136 << B_TRANSLATE(" seconds"); 137 138 return B_OK; 139 } 140 141 142 void 143 MediaFileInfo::_Reset() 144 { 145 audio.details.SetTo(""); 146 audio.format.SetTo(""); 147 video.details.SetTo(""); 148 video.format.SetTo(""); 149 useconds = 0; 150 duration.SetTo(""); 151 } 152