// Copyright 1999, Be Incorporated. All Rights Reserved. // Copyright 2000-2004, Jun Suzuki. All Rights Reserved. // Copyright 2007, Stephan Aßmus. All Rights Reserved. // Copyright 2010, Haiku, Inc. All Rights Reserved. // This file may be used under the terms of the Be Sample Code License. #include "MediaFileInfo.h" #include #include #include #include #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(""); }