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 <MessageFormat.h> 13 #include <stdio.h> 14 15 #undef B_TRANSLATION_CONTEXT 16 #define B_TRANSLATION_CONTEXT "MediaFileInfo" 17 18 MediaFileInfo::MediaFileInfo(BMediaFile* file) 19 { 20 LoadInfo(file); 21 } 22 23 24 status_t 25 MediaFileInfo::LoadInfo(BMediaFile* file) 26 { 27 _Reset(); 28 if (!file) 29 return B_BAD_VALUE; 30 31 BMediaTrack* track; 32 media_format format; 33 memset(&format, 0, sizeof(format)); 34 media_codec_info codecInfo; 35 bool audioDone(false), videoDone(false); 36 bigtime_t audioDuration = 0; 37 bigtime_t videoDuration = 0; 38 int32 tracks = file->CountTracks(); 39 int64 videoFrames = 0; 40 int64 audioFrames = 0; 41 status_t ret = B_OK; 42 43 for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) { 44 track = file->TrackAt(i); 45 if (track == NULL) 46 return B_ERROR; 47 48 ret = track->InitCheck(); 49 if (ret != B_OK) 50 return ret; 51 52 ret = track->EncodedFormat(&format); 53 if (ret != B_OK) 54 return ret; 55 56 static BMessageFormat frameFormat(B_TRANSLATE( 57 "{0, plural, one{# frame} other{# frames}}")); 58 59 if (format.IsVideo()) { 60 memset(&format, 0, sizeof(format)); 61 format.type = B_MEDIA_RAW_VIDEO; 62 63 ret = track->DecodedFormat(&format); 64 if (ret != B_OK) 65 return ret; 66 67 media_raw_video_format *rvf = &(format.u.raw_video); 68 69 ret = track->GetCodecInfo(&codecInfo); 70 if (ret != B_OK) 71 return ret; 72 73 video.format << codecInfo.pretty_name; 74 videoDuration = track->Duration(); 75 videoFrames = track->CountFrames(); 76 77 BString details; 78 details.SetToFormat( 79 B_TRANSLATE_COMMENT("%u x %u, %.2ffps", "Width x Height, fps"), 80 format.Width(), format.Height(), 81 rvf->field_rate / rvf->interlace); 82 83 details << " / "; 84 frameFormat.Format(details, videoFrames); 85 86 video.details << details; 87 videoDone = true; 88 89 } else if (format.IsAudio()) { 90 memset(&format, 0, sizeof(format)); 91 format.type = B_MEDIA_RAW_AUDIO; 92 ret = track->DecodedFormat(&format); 93 if (ret != B_OK) 94 return ret; 95 media_raw_audio_format *raf = &(format.u.raw_audio); 96 char bytesPerSample = (char)(raf->format & 0xf); 97 98 BString details; 99 if (bytesPerSample == 1 || bytesPerSample == 2) { 100 static BMessageFormat bitFormat( 101 B_TRANSLATE("{0, plural, one{# bit} other{# bits}}")); 102 bitFormat.Format(details, bytesPerSample * 8); 103 details.SetToFormat(B_TRANSLATE("%d bit "), bytesPerSample * 8); 104 } else { 105 static BMessageFormat bitFormat( 106 B_TRANSLATE("{0, plural, one{# byte} other{# bytes}}")); 107 bitFormat.Format(details, bytesPerSample); 108 } 109 audio.details << details; 110 audio.details << " "; 111 112 ret = track->GetCodecInfo(&codecInfo); 113 if (ret != B_OK) 114 return ret; 115 116 audio.format << codecInfo.pretty_name; 117 audioDuration = track->Duration(); 118 audioFrames = track->CountFrames(); 119 BString channels; 120 if (raf->channel_count == 1) { 121 channels.SetToFormat(B_TRANSLATE("%.1f kHz mono"), 122 raf->frame_rate / 1000.f); 123 } else if (raf->channel_count == 2) { 124 channels.SetToFormat(B_TRANSLATE("%.1f kHz stereo"), 125 raf->frame_rate / 1000.f); 126 } else { 127 channels.SetToFormat(B_TRANSLATE("%.1f kHz %ld channel"), 128 raf->frame_rate / 1000.f, raf->channel_count); 129 } 130 131 channels << " / "; 132 frameFormat.Format(channels, audioFrames); 133 134 audio.details << channels; 135 136 audioDone = true; 137 } 138 ret = file->ReleaseTrack(track); 139 if (ret != B_OK) 140 return ret; 141 } 142 143 useconds = MAX(audioDuration, videoDuration); 144 duration << (int32)(useconds / 1000000) 145 << B_TRANSLATE(" seconds"); 146 147 return B_OK; 148 } 149 150 151 void 152 MediaFileInfo::_Reset() 153 { 154 audio.details.SetTo(""); 155 audio.format.SetTo(""); 156 video.details.SetTo(""); 157 video.format.SetTo(""); 158 useconds = 0; 159 duration.SetTo(""); 160 } 161