* The window would not reset the audio/video track to 0 on a new file if
the Controller would keep the last audio/video track index across files (which would be nice for certain situations). * Better error message for unsupported files, especially for the B_MEDIA_NO_HANDLER error. * In the Controller, try to obtain the track duration and ignore tracks that return a bogus duration. I have some MP3 files on ZETA that are obviously not handled correctly by the ZETA mp3 decoder. Previously, the player would just sit there and appeared to have some other internal error. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26261 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
9b74b9cda8
commit
e6ac2ec43e
@ -125,6 +125,10 @@ Controller::~Controller()
|
||||
int64
|
||||
Controller::Duration()
|
||||
{
|
||||
// TODO: It is not so nice that the MediaPlayer still measures
|
||||
// in video frames if only playing audio. Here for example, it will
|
||||
// return a duration of 0 if the audio clip happens to be shorter than
|
||||
// one video frame at 25 fps.
|
||||
return (int64)((double)fDuration * fVideoFrameRate / 1000000.0);
|
||||
}
|
||||
|
||||
@ -195,7 +199,7 @@ Controller::SetTo(const entry_ref &ref)
|
||||
|
||||
status_t err;
|
||||
|
||||
BMediaFile *mf = new BMediaFile(&ref);
|
||||
BMediaFile* mf = new BMediaFile(&ref);
|
||||
ObjectDeleter<BMediaFile> mediaFileDeleter(mf);
|
||||
|
||||
err = mf->InitCheck();
|
||||
@ -213,19 +217,21 @@ Controller::SetTo(const entry_ref &ref)
|
||||
}
|
||||
|
||||
for (int i = 0; i < trackcount; i++) {
|
||||
BMediaTrack *t = mf->TrackAt(i);
|
||||
BMediaTrack* t = mf->TrackAt(i);
|
||||
media_format f;
|
||||
err = t->EncodedFormat(&f);
|
||||
if (err != B_OK) {
|
||||
if (err != B_OK || t->Duration() <= 0) {
|
||||
printf("Controller::SetTo: EncodedFormat failed for track index %d, error 0x%08lx (%s)\n",
|
||||
i, err, strerror(err));
|
||||
mf->ReleaseTrack(t);
|
||||
continue;
|
||||
}
|
||||
if (f.IsAudio()) {
|
||||
fAudioTrackList.AddItem(t);
|
||||
if (!fAudioTrackList.AddItem(t))
|
||||
return B_NO_MEMORY;
|
||||
} else if (f.IsVideo()) {
|
||||
fVideoTrackList.AddItem(t);
|
||||
if (!fVideoTrackList.AddItem(t))
|
||||
return B_NO_MEMORY;
|
||||
} else {
|
||||
printf("Controller::SetTo: track index %d has unknown type\n", i);
|
||||
mf->ReleaseTrack(t);
|
||||
@ -326,7 +332,7 @@ Controller::SelectAudioTrack(int n)
|
||||
return B_ERROR;
|
||||
|
||||
ObjectDeleter<AudioTrackSupplier> deleter(fAudioTrackSupplier);
|
||||
fAudioTrackSupplier = new MediaTrackAudioSupplier(track);
|
||||
fAudioTrackSupplier = new MediaTrackAudioSupplier(track, n);
|
||||
|
||||
bigtime_t a = fAudioTrackSupplier->Duration();
|
||||
bigtime_t v = fVideoTrackSupplier ? fVideoTrackSupplier->Duration() : 0;;
|
||||
@ -334,10 +340,6 @@ Controller::SelectAudioTrack(int n)
|
||||
DurationChanged();
|
||||
// TODO: notify duration changed!
|
||||
|
||||
// TODO: Not good, because the ProxyAudioSupplier currently
|
||||
// uses the supplier without locking the Controller!
|
||||
// This is only a problem when selecting a different audio track
|
||||
// from the interface menu.
|
||||
fAudioSupplier->SetSupplier(fAudioTrackSupplier, fVideoFrameRate);
|
||||
|
||||
_NotifyAudioTrackChanged(n);
|
||||
@ -345,6 +347,18 @@ Controller::SelectAudioTrack(int n)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Controller::CurrentAudioTrack()
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
if (fAudioTrackSupplier == NULL)
|
||||
return -1;
|
||||
|
||||
return fAudioTrackSupplier->TrackIndex();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Controller::SelectVideoTrack(int n)
|
||||
{
|
||||
@ -356,7 +370,7 @@ Controller::SelectVideoTrack(int n)
|
||||
|
||||
status_t initStatus;
|
||||
ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier);
|
||||
fVideoTrackSupplier = new MediaTrackVideoSupplier(track, initStatus);
|
||||
fVideoTrackSupplier = new MediaTrackVideoSupplier(track, n, initStatus);
|
||||
if (initStatus < B_OK) {
|
||||
delete fVideoTrackSupplier;
|
||||
fVideoTrackSupplier = NULL;
|
||||
@ -383,6 +397,18 @@ Controller::SelectVideoTrack(int n)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Controller::CurrentVideoTrack()
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
if (fVideoTrackSupplier == NULL)
|
||||
return -1;
|
||||
|
||||
return fVideoTrackSupplier->TrackIndex();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
@ -83,7 +83,9 @@ public:
|
||||
int VideoTrackCount();
|
||||
|
||||
status_t SelectAudioTrack(int n);
|
||||
int CurrentAudioTrack();
|
||||
status_t SelectVideoTrack(int n);
|
||||
int CurrentVideoTrack();
|
||||
|
||||
void Stop();
|
||||
void Play();
|
||||
|
@ -709,10 +709,21 @@ MainWin::OpenFile(const entry_ref &ref)
|
||||
if (err != B_OK) {
|
||||
if (fPlaylist->CountItems() == 1) {
|
||||
// display error if this is the only file we're supposed to play
|
||||
char s[300];
|
||||
sprintf(s, "Can't open file\n\n%s\n\nError 0x%08lx\n(%s)\n",
|
||||
ref.name, err, strerror(err));
|
||||
(new BAlert("error", s, "OK"))->Go();
|
||||
BString message;
|
||||
message << "The file '";
|
||||
message << ref.name;
|
||||
message << "' could not be opened.\n\n";
|
||||
|
||||
if (err == B_MEDIA_NO_HANDLER) {
|
||||
// give a more detailed message for the most likely of all
|
||||
// errors
|
||||
message << "There is no decoder installed to handle the "
|
||||
"file format, or the decoder has trouble with the specific "
|
||||
"version of the format.";
|
||||
} else {
|
||||
message << "Error: " << strerror(err);
|
||||
}
|
||||
(new BAlert("error", message.String(), "OK"))->Go();
|
||||
} else {
|
||||
// just go to the next file and don't bother user
|
||||
fPlaylist->SetCurrentRefIndex(fPlaylist->CurrentRefIndex() + 1);
|
||||
@ -828,9 +839,6 @@ MainWin::_SetupWindow()
|
||||
// Enable both if a file was loaded
|
||||
fAudioTrackMenu->SetEnabled(fHasFile);
|
||||
fVideoTrackMenu->SetEnabled(fHasFile);
|
||||
// Select first track (might be "none") in both
|
||||
fAudioTrackMenu->ItemAt(0)->SetMarked(true);
|
||||
fVideoTrackMenu->ItemAt(0)->SetMarked(true);
|
||||
|
||||
fVideoMenu->SetEnabled(fHasVideo);
|
||||
fAudioMenu->SetEnabled(fHasAudio);
|
||||
@ -847,6 +855,8 @@ MainWin::_SetupWindow()
|
||||
}
|
||||
_UpdateControlsEnabledStatus();
|
||||
|
||||
// TODO: Don't if the video size did not change! Also don't
|
||||
// exit full screen mode.
|
||||
_ResizeWindow(100);
|
||||
|
||||
fVideoView->MakeFocus();
|
||||
@ -958,26 +968,36 @@ MainWin::_SetupTrackMenus()
|
||||
fAudioTrackMenu->RemoveItems(0, fAudioTrackMenu->CountItems(), true);
|
||||
fVideoTrackMenu->RemoveItems(0, fVideoTrackMenu->CountItems(), true);
|
||||
|
||||
int c, i;
|
||||
char s[100];
|
||||
|
||||
c = fController->AudioTrackCount();
|
||||
for (i = 0; i < c; i++) {
|
||||
int count = fController->AudioTrackCount();
|
||||
int current = fController->CurrentAudioTrack();
|
||||
for (int i = 0; i < count; i++) {
|
||||
sprintf(s, "Track %d", i + 1);
|
||||
fAudioTrackMenu->AddItem(new BMenuItem(s,
|
||||
new BMessage(M_SELECT_AUDIO_TRACK + i)));
|
||||
BMenuItem* item = new BMenuItem(s,
|
||||
new BMessage(M_SELECT_AUDIO_TRACK + i));
|
||||
item->SetMarked(i == current);
|
||||
fAudioTrackMenu->AddItem(item);
|
||||
}
|
||||
if (!c)
|
||||
if (!count) {
|
||||
fAudioTrackMenu->AddItem(new BMenuItem("none", new BMessage(M_DUMMY)));
|
||||
|
||||
c = fController->VideoTrackCount();
|
||||
for (i = 0; i < c; i++) {
|
||||
sprintf(s, "Track %d", i + 1);
|
||||
fVideoTrackMenu->AddItem(new BMenuItem(s,
|
||||
new BMessage(M_SELECT_VIDEO_TRACK + i)));
|
||||
fAudioTrackMenu->ItemAt(0)->SetMarked(true);
|
||||
}
|
||||
if (!c)
|
||||
|
||||
|
||||
count = fController->VideoTrackCount();
|
||||
current = fController->CurrentVideoTrack();
|
||||
for (int i = 0; i < count; i++) {
|
||||
sprintf(s, "Track %d", i + 1);
|
||||
BMenuItem* item = new BMenuItem(s,
|
||||
new BMessage(M_SELECT_VIDEO_TRACK + i));
|
||||
item->SetMarked(i == current);
|
||||
fVideoTrackMenu->AddItem(item);
|
||||
}
|
||||
if (!count) {
|
||||
fVideoTrackMenu->AddItem(new BMenuItem("none", new BMessage(M_DUMMY)));
|
||||
fVideoTrackMenu->ItemAt(0)->SetMarked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,8 @@ class AudioTrackSupplier : public AudioReader {
|
||||
const = 0;
|
||||
virtual status_t GetCodecInfo(media_codec_info* info) const = 0;
|
||||
virtual bigtime_t Duration() const = 0;
|
||||
|
||||
virtual int32 TrackIndex() const = 0;
|
||||
};
|
||||
|
||||
#endif // AUDIO_TRACK_SUPPLIER_H
|
||||
|
@ -54,7 +54,8 @@ MediaTrackAudioSupplier::Buffer::CompareOffset(const void* a, const void* b)
|
||||
// #pragma mark - MediaTrackAudioSupplier
|
||||
|
||||
|
||||
MediaTrackAudioSupplier::MediaTrackAudioSupplier(BMediaTrack* mediaTrack)
|
||||
MediaTrackAudioSupplier::MediaTrackAudioSupplier(BMediaTrack* mediaTrack,
|
||||
int32 trackIndex)
|
||||
: AudioTrackSupplier(),
|
||||
fMediaTrack(mediaTrack),
|
||||
fBuffer(NULL),
|
||||
@ -63,7 +64,8 @@ MediaTrackAudioSupplier::MediaTrackAudioSupplier(BMediaTrack* mediaTrack)
|
||||
fBuffers(10),
|
||||
fHasKeyFrames(false),
|
||||
fCountFrames(0),
|
||||
fReportSeekError(true)
|
||||
fReportSeekError(true),
|
||||
fTrackIndex(trackIndex)
|
||||
{
|
||||
_InitFromTrack();
|
||||
}
|
||||
@ -104,6 +106,7 @@ MediaTrackAudioSupplier::GetCodecInfo(media_codec_info* info) const
|
||||
bigtime_t
|
||||
MediaTrackAudioSupplier::Duration() const
|
||||
{
|
||||
fMediaTrack, fMediaTrack ? fMediaTrack->Duration() : 0LL, fCountFrames);
|
||||
if (!fMediaTrack)
|
||||
return 0;
|
||||
|
||||
@ -199,6 +202,9 @@ MediaTrackAudioSupplier::_InitFromTrack()
|
||||
|
||||
// get the length of the track
|
||||
fCountFrames = fMediaTrack->CountFrames();
|
||||
|
||||
TRACE("MediaTrackAudioSupplier: keyframes: %d, frame count: %lld\n",
|
||||
fHasKeyFrames, fCountFrames);
|
||||
} else
|
||||
fMediaTrack = NULL;
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ struct media_format;
|
||||
|
||||
class MediaTrackAudioSupplier : public AudioTrackSupplier {
|
||||
public:
|
||||
MediaTrackAudioSupplier(BMediaTrack* track);
|
||||
MediaTrackAudioSupplier(BMediaTrack* track,
|
||||
int32 trackIndex);
|
||||
virtual ~MediaTrackAudioSupplier();
|
||||
|
||||
virtual const media_format& Format() const;
|
||||
@ -30,6 +31,9 @@ class MediaTrackAudioSupplier : public AudioTrackSupplier {
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
virtual int32 TrackIndex() const
|
||||
{ return fTrackIndex; }
|
||||
|
||||
private:
|
||||
struct Buffer;
|
||||
void _InitFromTrack();
|
||||
@ -84,6 +88,7 @@ class MediaTrackAudioSupplier : public AudioTrackSupplier {
|
||||
bool fHasKeyFrames;
|
||||
int64 fCountFrames;
|
||||
bool fReportSeekError;
|
||||
int32 fTrackIndex;
|
||||
};
|
||||
|
||||
#endif // MEDIA_TRACK_AUDIO_SUPPLIER_H
|
||||
|
@ -24,13 +24,15 @@ using std::nothrow;
|
||||
|
||||
// constructor
|
||||
MediaTrackVideoSupplier::MediaTrackVideoSupplier(BMediaTrack* track,
|
||||
status_t& initStatus)
|
||||
int32 trackIndex, status_t& initStatus)
|
||||
: VideoTrackSupplier()
|
||||
, fVideoTrack(track)
|
||||
|
||||
, fPerformanceTime(0)
|
||||
, fDuration(0)
|
||||
, fCurrentFrame(0)
|
||||
|
||||
, fTrackIndex(trackIndex)
|
||||
{
|
||||
if (!fVideoTrack) {
|
||||
printf("MediaTrackVideoSupplier() - no video track\n");
|
||||
|
@ -17,7 +17,7 @@ class BMediaTrack;
|
||||
class MediaTrackVideoSupplier : public VideoTrackSupplier {
|
||||
public:
|
||||
MediaTrackVideoSupplier(BMediaTrack* track,
|
||||
status_t& initStatus);
|
||||
int32 trackIndex, status_t& initStatus);
|
||||
virtual ~MediaTrackVideoSupplier();
|
||||
|
||||
virtual const media_format& Format() const;
|
||||
@ -42,6 +42,9 @@ class MediaTrackVideoSupplier : public VideoTrackSupplier {
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual uint32 BytesPerRow() const;
|
||||
|
||||
virtual int32 TrackIndex() const
|
||||
{ return fTrackIndex; }
|
||||
|
||||
private:
|
||||
status_t _SwitchFormat(color_space format,
|
||||
uint32 bytesPerRow);
|
||||
@ -55,6 +58,8 @@ class MediaTrackVideoSupplier : public VideoTrackSupplier {
|
||||
bigtime_t fPerformanceTime;
|
||||
bigtime_t fDuration;
|
||||
int64 fCurrentFrame;
|
||||
|
||||
int32 fTrackIndex;
|
||||
};
|
||||
|
||||
#endif // MEDIA_TRACK_VIDEO_SUPPLIER_H
|
||||
|
@ -31,6 +31,8 @@ class VideoTrackSupplier {
|
||||
virtual bigtime_t Position() const = 0;
|
||||
virtual bigtime_t Duration() const = 0;
|
||||
virtual int64 CurrentFrame() const = 0;
|
||||
|
||||
virtual int32 TrackIndex() const = 0;
|
||||
};
|
||||
|
||||
#endif // VIDEO_TRACK_SUPPLIER_H
|
||||
|
Loading…
Reference in New Issue
Block a user