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 <StringFormat.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 format.Clear(); 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 BStringFormat frameFormat(B_TRANSLATE( 57 "{0, plural, one{# frame} other{# frames}}")); 58 59 if (format.IsVideo()) { 60 format.Clear(); 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 × %u, %.2ffps", "Width × Height, fps;" 80 "The '×' is the Unicode multiplication sign U+00D7"), 81 (unsigned)format.Width(), (unsigned)format.Height(), 82 rvf->field_rate / rvf->interlace); 83 84 details << " / "; 85 frameFormat.Format(details, videoFrames); 86 87 video.details << details; 88 videoDone = true; 89 90 } else if (format.IsAudio()) { 91 format.Clear(); 92 format.type = B_MEDIA_RAW_AUDIO; 93 ret = track->DecodedFormat(&format); 94 if (ret != B_OK) 95 return ret; 96 media_raw_audio_format *raf = &(format.u.raw_audio); 97 char bytesPerSample = (char)(raf->format & 0xf); 98 99 BString details; 100 if (bytesPerSample == 1 || bytesPerSample == 2) { 101 static BStringFormat bitFormat( 102 B_TRANSLATE("{0, plural, one{# bit} other{# bits}}")); 103 bitFormat.Format(details, bytesPerSample * 8); 104 details.SetToFormat(B_TRANSLATE("%d bit "), bytesPerSample * 8); 105 } else { 106 static BStringFormat bitFormat( 107 B_TRANSLATE("{0, plural, one{# byte} other{# bytes}}")); 108 bitFormat.Format(details, bytesPerSample); 109 } 110 audio.details << details; 111 audio.details << " "; 112 113 ret = track->GetCodecInfo(&codecInfo); 114 if (ret != B_OK) 115 return ret; 116 117 audio.format << codecInfo.pretty_name; 118 audioDuration = track->Duration(); 119 audioFrames = track->CountFrames(); 120 BString channels; 121 if (raf->channel_count == 1) { 122 channels.SetToFormat(B_TRANSLATE("%.1f kHz mono"), 123 raf->frame_rate / 1000.f); 124 } else if (raf->channel_count == 2) { 125 channels.SetToFormat(B_TRANSLATE("%.1f kHz stereo"), 126 raf->frame_rate / 1000.f); 127 } else { 128 channels.SetToFormat(B_TRANSLATE("%.1f kHz %ld channel"), 129 raf->frame_rate / 1000.f, (long int)raf->channel_count); 130 } 131 132 channels << " / "; 133 frameFormat.Format(channels, audioFrames); 134 135 audio.details << channels; 136 137 audioDone = true; 138 } 139 ret = file->ReleaseTrack(track); 140 if (ret != B_OK) 141 return ret; 142 } 143 144 useconds = MAX(audioDuration, videoDuration); 145 duration << (int32)(useconds / 1000000) 146 << B_TRANSLATE(" seconds"); 147 148 return B_OK; 149 } 150 151 152 void 153 MediaFileInfo::_Reset() 154 { 155 audio.details.SetTo(""); 156 audio.format.SetTo(""); 157 video.details.SetTo(""); 158 video.format.SetTo(""); 159 useconds = 0; 160 duration.SetTo(""); 161 } 162