xref: /haiku/src/apps/mediaconverter/MediaFileInfoView.cpp (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
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