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 // This file may be used under the terms of the Be Sample Code License. 5 #include "MediaFileInfoView.h" 6 7 #include <string.h> 8 9 #include <MediaFile.h> 10 #include <MediaTrack.h> 11 #include <String.h> 12 13 #include "Strings.h" 14 15 16 MediaFileInfoView::MediaFileInfoView(BRect frame, uint32 resizingMode) 17 : BView(frame, "MediaFileInfoView", resizingMode, 18 B_FULL_UPDATE_ON_RESIZE | B_WILL_DRAW) 19 , fRef() 20 , fMediaFile(NULL) 21 , fDuration(0) 22 { 23 } 24 25 26 MediaFileInfoView::~MediaFileInfoView() 27 { 28 } 29 30 31 void 32 MediaFileInfoView::Draw(BRect /*update*/) 33 { 34 font_height fh; 35 GetFontHeight(&fh); 36 BPoint p(2, fh.ascent + fh.leading); 37 BFont font; 38 GetFont(&font); 39 font.SetFace(B_BOLD_FACE); 40 font.SetSize(12); 41 SetFont(&font); 42 43 if (fMediaFile == NULL) { 44 DrawString(NO_FILE_LABEL, p); 45 return; 46 } 47 48 BString aFmt, vFmt, aDetails, vDetails, duration; 49 _GetFileInfo(&aFmt, &vFmt, &aDetails, &vDetails, &duration); 50 51 // draw filename 52 DrawString(fRef.name, p); 53 float lineHeight = fh.ascent + fh.descent + fh.leading; 54 p.y += (float)ceil(lineHeight * 1.5); 55 56 float durLen = StringWidth(DURATION_LABEL) + 5; 57 float audLen = StringWidth(AUDIO_INFO_LABEL) + 5; 58 float vidLen = StringWidth(VIDEO_INFO_LABEL) + 5; 59 float maxLen = MAX(durLen, audLen); 60 maxLen = MAX(maxLen, vidLen); 61 62 // draw labels 63 DrawString(AUDIO_INFO_LABEL, p + BPoint(maxLen - audLen, 0)); 64 BPoint p2 = p; 65 p2.x += maxLen + 4; 66 p.y += lineHeight * 2; 67 DrawString(VIDEO_INFO_LABEL, p + BPoint(maxLen - vidLen, 0)); 68 p.y += lineHeight * 2; 69 DrawString(DURATION_LABEL, p + BPoint(maxLen - durLen, 0)); 70 71 // draw audio/video/duration info 72 font.SetFace(B_REGULAR_FACE); 73 font.SetSize(10); 74 SetFont(&font); 75 76 DrawString(aFmt.String(), p2); 77 p2.y += lineHeight; 78 DrawString(aDetails.String(), p2); 79 p2.y += lineHeight; 80 DrawString(vFmt.String(), p2); 81 p2.y += lineHeight; 82 DrawString(vDetails.String(), p2); 83 p2.y += lineHeight; 84 DrawString(duration.String(), p2); 85 } 86 87 88 void 89 MediaFileInfoView::AttachedToWindow() 90 { 91 rgb_color c = Parent()->LowColor(); 92 SetViewColor(c); 93 SetLowColor(c); 94 } 95 96 97 void 98 MediaFileInfoView::Update(BMediaFile* file, entry_ref* ref) 99 { 100 if (fMediaFile == file) 101 return; 102 103 fMediaFile = file; 104 105 if (file != NULL && ref != NULL) 106 fRef = *ref; 107 else 108 fRef = entry_ref(); 109 110 Invalidate(); 111 } 112 113 114 // #pragma mark - 115 116 117 void 118 MediaFileInfoView::_GetFileInfo(BString* audioFormat, BString* videoFormat, 119 BString* audioDetails, BString* videoDetails, BString* duration) 120 { 121 fDuration = 0; 122 if (fMediaFile == NULL) 123 return; 124 125 BMediaTrack* track; 126 media_format format; 127 memset(&format, 0, sizeof(format)); 128 media_codec_info codecInfo; 129 bool audioDone(false), videoDone(false); 130 bigtime_t audioDuration = 0; 131 bigtime_t videoDuration = 0; 132 int32 tracks = fMediaFile->CountTracks(); 133 int64 videoFrames = 0; 134 int64 audioFrames = 0; 135 for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) { 136 track = fMediaFile->TrackAt(i); 137 if (track != NULL) { 138 track->EncodedFormat(&format); 139 if (format.IsVideo()) { 140 memset(&format, 0, sizeof(format)); 141 format.type = B_MEDIA_RAW_VIDEO; 142 track->DecodedFormat(&format); 143 media_raw_video_format *rvf = &(format.u.raw_video); 144 145 track->GetCodecInfo(&codecInfo); 146 *videoFormat << codecInfo.pretty_name; 147 videoDuration = track->Duration(); 148 videoFrames = track->CountFrames(); 149 150 *videoDetails << (int32)format.Width() << "x" << (int32)format.Height() 151 << " " << (int32)(rvf->field_rate / rvf->interlace) 152 << " fps / " << videoFrames << " frames"; 153 154 videoDone = true; 155 156 } else if (format.IsAudio()) { 157 memset(&format, 0, sizeof(format)); 158 format.type = B_MEDIA_RAW_AUDIO; 159 track->DecodedFormat(&format); 160 media_raw_audio_format *raf = &(format.u.raw_audio); 161 char bytesPerSample = (char)(raf->format & 0xf); 162 if (bytesPerSample == 1) { 163 *audioDetails << "8 bit "; 164 } else if (bytesPerSample == 2) { 165 *audioDetails << "16 bit "; 166 } else { 167 *audioDetails << bytesPerSample << "byte "; 168 } 169 170 track->GetCodecInfo(&codecInfo); 171 *audioFormat << codecInfo.pretty_name; 172 audioDuration = track->Duration(); 173 audioFrames = track->CountFrames(); 174 175 *audioDetails << (float)(raf->frame_rate / 1000.0f) << " kHz"; 176 if (raf->channel_count == 1) { 177 *audioDetails << " mono / "; 178 } else if (raf->channel_count == 2) { 179 *audioDetails << " stereo / "; 180 } else { 181 *audioDetails << (int32)raf->channel_count << " channel / " ; 182 } 183 *audioDetails << audioFrames << " frames"; 184 audioDone = true; 185 } 186 fMediaFile->ReleaseTrack(track); 187 } 188 } 189 190 fDuration = MAX(audioDuration, videoDuration); 191 *duration << (int32)(fDuration / 1000000) 192 << " seconds"; 193 } 194 195 196