#include "MediaFileInfo.h"
#include <Catalog.h>
#include <MediaTrack.h>
#include <StringFormat.h>
#include <stdio.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "MediaFileInfo"
MediaFileInfo::MediaFileInfo(BMediaFile* file)
{
LoadInfo(file);
}
status_t
MediaFileInfo::LoadInfo(BMediaFile* file)
{
_Reset();
if (!file)
return B_BAD_VALUE;
BMediaTrack* track;
media_format format;
format.Clear();
media_codec_info codecInfo;
bool audioDone(false), videoDone(false);
bigtime_t audioDuration = 0;
bigtime_t videoDuration = 0;
int32 tracks = file->CountTracks();
int64 videoFrames = 0;
int64 audioFrames = 0;
status_t ret = B_OK;
for (int32 i = 0; i < tracks && (!audioDone || !videoDone); i++) {
track = file->TrackAt(i);
if (track == NULL)
return B_ERROR;
ret = track->InitCheck();
if (ret != B_OK)
return ret;
ret = track->EncodedFormat(&format);
if (ret != B_OK)
return ret;
static BStringFormat frameFormat(B_TRANSLATE(
"{0, plural, one{# frame} other{# frames}}"));
if (format.IsVideo()) {
format.Clear();
format.type = B_MEDIA_RAW_VIDEO;
ret = track->DecodedFormat(&format);
if (ret != B_OK)
return ret;
media_raw_video_format *rvf = &(format.u.raw_video);
ret = track->GetCodecInfo(&codecInfo);
if (ret != B_OK)
return ret;
video.format << codecInfo.pretty_name;
videoDuration = track->Duration();
videoFrames = track->CountFrames();
BString details;
details.SetToFormat(
B_TRANSLATE_COMMENT("%u × %u, %.2ffps", "Width × Height, fps;"
"The '×' is the Unicode multiplication sign U+00D7"),
(unsigned)format.Width(), (unsigned)format.Height(),
rvf->field_rate / rvf->interlace);
details << " / ";
frameFormat.Format(details, videoFrames);
video.details << details;
videoDone = true;
} else if (format.IsAudio()) {
format.Clear();
format.type = B_MEDIA_RAW_AUDIO;
ret = track->DecodedFormat(&format);
if (ret != B_OK)
return ret;
media_raw_audio_format *raf = &(format.u.raw_audio);
char bytesPerSample = (char)(raf->format & 0xf);
BString details;
if (bytesPerSample == 1 || bytesPerSample == 2) {
static BStringFormat bitFormat(
B_TRANSLATE("{0, plural, one{# bit} other{# bits}}"));
bitFormat.Format(details, bytesPerSample * 8);
details.SetToFormat(B_TRANSLATE("%d bit "), bytesPerSample * 8);
} else {
static BStringFormat bitFormat(
B_TRANSLATE("{0, plural, one{# byte} other{# bytes}}"));
bitFormat.Format(details, bytesPerSample);
}
audio.details << details;
audio.details << " ";
ret = track->GetCodecInfo(&codecInfo);
if (ret != B_OK)
return ret;
audio.format << codecInfo.pretty_name;
audioDuration = track->Duration();
audioFrames = track->CountFrames();
BString channels;
if (raf->channel_count == 1) {
channels.SetToFormat(B_TRANSLATE("%.1f kHz mono"),
raf->frame_rate / 1000.f);
} else if (raf->channel_count == 2) {
channels.SetToFormat(B_TRANSLATE("%.1f kHz stereo"),
raf->frame_rate / 1000.f);
} else {
channels.SetToFormat(B_TRANSLATE("%.1f kHz %ld channel"),
raf->frame_rate / 1000.f, (long int)raf->channel_count);
}
channels << " / ";
frameFormat.Format(channels, audioFrames);
audio.details << channels;
audioDone = true;
}
ret = file->ReleaseTrack(track);
if (ret != B_OK)
return ret;
}
useconds = MAX(audioDuration, videoDuration);
duration << (int32)(useconds / 1000000)
<< B_TRANSLATE(" seconds");
return B_OK;
}
void
MediaFileInfo::_Reset()
{
audio.details.SetTo("");
audio.format.SetTo("");
video.details.SetTo("");
video.format.SetTo("");
useconds = 0;
duration.SetTo("");
}