* Flesh out attribute support in PlaylistItem/FilePlaylistItem
some more. * Finish refactoring and abstracting BMediaFile/BMediaTrack out of the Controller. There is TrackSupplier now and MediaFileTrackSupplier. One could now implement another PlaylistItem class besides FilePlaylistItem, which provides other implementations for TrackSupplier (i.e. for testing DVD playback). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38722 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -30,8 +30,6 @@
|
||||
#include <Autolock.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Debug.h>
|
||||
#include <MediaFile.h>
|
||||
#include <MediaTrack.h>
|
||||
#include <Path.h>
|
||||
#include <Window.h> // for debugging only
|
||||
|
||||
@@ -48,6 +46,7 @@
|
||||
#include "MediaTrackVideoSupplier.h"
|
||||
#include "ProxyAudioSupplier.h"
|
||||
#include "ProxyVideoSupplier.h"
|
||||
#include "TrackSupplier.h"
|
||||
#include "VideoTrackSupplier.h"
|
||||
|
||||
using std::nothrow;
|
||||
@@ -99,16 +98,13 @@ Controller::Controller()
|
||||
fMuted(false),
|
||||
|
||||
fItem(NULL),
|
||||
fMediaFile(NULL),
|
||||
fTrackSupplier(NULL),
|
||||
|
||||
fVideoSupplier(new ProxyVideoSupplier()),
|
||||
fAudioSupplier(new ProxyAudioSupplier(this)),
|
||||
fVideoTrackSupplier(NULL),
|
||||
fAudioTrackSupplier(NULL),
|
||||
|
||||
fAudioTrackList(4),
|
||||
fVideoTrackList(2),
|
||||
|
||||
fCurrentFrame(0),
|
||||
fDuration(0),
|
||||
fVideoFrameRate(25.0),
|
||||
@@ -240,12 +236,8 @@ Controller::SetTo(const PlaylistItemRef& item)
|
||||
fAudioSupplier->SetSupplier(NULL, fVideoFrameRate);
|
||||
fVideoSupplier->SetSupplier(NULL);
|
||||
|
||||
fAudioTrackList.MakeEmpty();
|
||||
fVideoTrackList.MakeEmpty();
|
||||
|
||||
ObjectDeleter<BMediaFile> oldMediaFileDeleter(fMediaFile);
|
||||
// BMediaFile destructor will call ReleaseAllTracks()
|
||||
fMediaFile = NULL;
|
||||
ObjectDeleter<TrackSupplier> oldTrackSupplierDeleter(fTrackSupplier);
|
||||
fTrackSupplier = NULL;
|
||||
|
||||
// Do not delete the supplier chain until after we called
|
||||
// NodeManager::Init() to setup a new media node chain
|
||||
@@ -268,55 +260,27 @@ Controller::SetTo(const PlaylistItemRef& item)
|
||||
if (fItem.Get() == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
BMediaFile* mf = fItem->CreateMediaFile();
|
||||
ObjectDeleter<BMediaFile> mediaFileDeleter(mf);
|
||||
TrackSupplier* trackSupplier = fItem->CreateTrackSupplier();
|
||||
if (trackSupplier == NULL) {
|
||||
_NotifyFileChanged(item.Get(), B_NO_MEMORY);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
ObjectDeleter<TrackSupplier> trackSupplierDeleter(trackSupplier);
|
||||
|
||||
status_t err = mf->InitCheck();
|
||||
status_t err = trackSupplier->InitCheck();
|
||||
if (err != B_OK) {
|
||||
printf("Controller::SetTo: initcheck failed\n");
|
||||
_NotifyFileChanged(item.Get(), err);
|
||||
return err;
|
||||
}
|
||||
|
||||
int trackcount = mf->CountTracks();
|
||||
if (trackcount <= 0) {
|
||||
printf("Controller::SetTo: trackcount %d\n", trackcount);
|
||||
if (trackSupplier->CountAudioTracks() == 0
|
||||
&& trackSupplier->CountVideoTracks() == 0) {
|
||||
_NotifyFileChanged(item.Get(), B_MEDIA_NO_HANDLER);
|
||||
return B_MEDIA_NO_HANDLER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < trackcount; i++) {
|
||||
BMediaTrack* t = mf->TrackAt(i);
|
||||
media_format f;
|
||||
err = t->EncodedFormat(&f);
|
||||
if (err != B_OK) {
|
||||
printf("Controller::SetTo: EncodedFormat failed for track index %d, error 0x%08lx (%s)\n",
|
||||
i, err, strerror(err));
|
||||
mf->ReleaseTrack(t);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->Duration() <= 0) {
|
||||
printf("Controller::SetTo: warning! track index %d has no duration\n", i);
|
||||
}
|
||||
|
||||
if (f.IsAudio()) {
|
||||
if (!fAudioTrackList.AddItem(t))
|
||||
return B_NO_MEMORY;
|
||||
} else if (f.IsVideo()) {
|
||||
if (!fVideoTrackList.AddItem(t))
|
||||
return B_NO_MEMORY;
|
||||
} else {
|
||||
printf("Controller::SetTo: track index %d has unknown type\n", i);
|
||||
mf->ReleaseTrack(t);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Controller::SetTo: %d audio track, %d video track\n",
|
||||
// AudioTrackCount(), VideoTrackCount());
|
||||
|
||||
fMediaFile = mf;
|
||||
mediaFileDeleter.Detach();
|
||||
fTrackSupplier = trackSupplier;
|
||||
|
||||
SelectAudioTrack(0);
|
||||
SelectVideoTrack(0);
|
||||
@@ -324,12 +288,13 @@ Controller::SetTo(const PlaylistItemRef& item)
|
||||
if (fAudioTrackSupplier == NULL && fVideoTrackSupplier == NULL) {
|
||||
printf("Controller::SetTo: no audio or video tracks found or "
|
||||
"no decoders\n");
|
||||
fTrackSupplier = NULL;
|
||||
_NotifyFileChanged(item.Get(), B_MEDIA_NO_HANDLER);
|
||||
delete fMediaFile;
|
||||
fMediaFile = NULL;
|
||||
return B_MEDIA_NO_HANDLER;
|
||||
}
|
||||
|
||||
trackSupplierDeleter.Detach();
|
||||
|
||||
// prevent blocking the creation of new overlay buffers
|
||||
fVideoView->DisableOverlay();
|
||||
|
||||
@@ -451,7 +416,9 @@ Controller::AudioTrackCount()
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
return fAudioTrackList.CountItems();
|
||||
if (fTrackSupplier != NULL)
|
||||
return fTrackSupplier->CountAudioTracks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +427,9 @@ Controller::VideoTrackCount()
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
return fVideoTrackList.CountItems();
|
||||
if (fTrackSupplier != NULL)
|
||||
return fTrackSupplier->CountVideoTracks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -468,16 +437,17 @@ status_t
|
||||
Controller::SelectAudioTrack(int n)
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
BMediaTrack* track = (BMediaTrack *)fAudioTrackList.ItemAt(n);
|
||||
if (!track)
|
||||
return B_ERROR;
|
||||
if (fTrackSupplier == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
ObjectDeleter<AudioTrackSupplier> deleter(fAudioTrackSupplier);
|
||||
fAudioTrackSupplier = new MediaTrackAudioSupplier(track, n);
|
||||
fAudioTrackSupplier = fTrackSupplier->CreateAudioTrackForIndex(n);
|
||||
if (fAudioTrackSupplier == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
bigtime_t a = fAudioTrackSupplier->Duration();
|
||||
bigtime_t v = fVideoTrackSupplier ? fVideoTrackSupplier->Duration() : 0;;
|
||||
bigtime_t v = fVideoTrackSupplier != NULL
|
||||
? fVideoTrackSupplier->Duration() : 0;
|
||||
fDuration = max_c(a, v);
|
||||
DurationChanged();
|
||||
// TODO: notify duration changed!
|
||||
@@ -517,18 +487,13 @@ Controller::SelectVideoTrack(int n)
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
BMediaTrack* track = (BMediaTrack *)fVideoTrackList.ItemAt(n);
|
||||
if (!track)
|
||||
return B_ERROR;
|
||||
if (fTrackSupplier == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
status_t initStatus;
|
||||
ObjectDeleter<VideoTrackSupplier> deleter(fVideoTrackSupplier);
|
||||
fVideoTrackSupplier = new MediaTrackVideoSupplier(track, n, initStatus);
|
||||
if (initStatus < B_OK) {
|
||||
delete fVideoTrackSupplier;
|
||||
fVideoTrackSupplier = NULL;
|
||||
return initStatus;
|
||||
}
|
||||
fVideoTrackSupplier = fTrackSupplier->CreateVideoTrackForIndex(n);
|
||||
if (fVideoTrackSupplier == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
bigtime_t a = fAudioTrackSupplier ? fAudioTrackSupplier->Duration() : 0;
|
||||
bigtime_t v = fVideoTrackSupplier->Duration();
|
||||
@@ -765,7 +730,7 @@ bool
|
||||
Controller::HasFile()
|
||||
{
|
||||
// you need to hold the data lock
|
||||
return fMediaFile != NULL;
|
||||
return fTrackSupplier != NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -773,9 +738,9 @@ status_t
|
||||
Controller::GetFileFormatInfo(media_file_format* fileFormat)
|
||||
{
|
||||
// you need to hold the data lock
|
||||
if (!fMediaFile)
|
||||
if (!fTrackSupplier)
|
||||
return B_NO_INIT;
|
||||
return fMediaFile->GetFileFormatInfo(fileFormat);
|
||||
return fTrackSupplier->GetFileFormatInfo(fileFormat);
|
||||
}
|
||||
|
||||
|
||||
@@ -783,10 +748,9 @@ status_t
|
||||
Controller::GetCopyright(BString* copyright)
|
||||
{
|
||||
// you need to hold the data lock
|
||||
if (!fMediaFile)
|
||||
if (!fTrackSupplier)
|
||||
return B_NO_INIT;
|
||||
*copyright = fMediaFile->Copyright();
|
||||
return B_OK;
|
||||
return fTrackSupplier->GetCopyright(copyright);
|
||||
}
|
||||
|
||||
|
||||
@@ -855,35 +819,30 @@ Controller::GetAudioCodecInfo(media_codec_info* info)
|
||||
status_t
|
||||
Controller::GetMetaData(BMessage* metaData)
|
||||
{
|
||||
// TODO: Move API into supplier classes
|
||||
if (fMediaFile == NULL)
|
||||
// you need to hold the data lock
|
||||
if (fTrackSupplier == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
return fMediaFile->GetMetaData(metaData);
|
||||
return fTrackSupplier->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Controller::GetVideoMetaData(int32 index, BMessage* metaData)
|
||||
{
|
||||
// TODO: Move API into supplier classes
|
||||
BMediaTrack* track = (BMediaTrack*)fVideoTrackList.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return track->GetMetaData(metaData);
|
||||
// you need to hold the data lock
|
||||
if (fTrackSupplier == NULL)
|
||||
return B_NO_INIT;
|
||||
return fTrackSupplier->GetVideoMetaData(index, metaData);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Controller::GetAudioMetaData(int32 index, BMessage* metaData)
|
||||
{
|
||||
// TODO: Move API into supplier classes
|
||||
BMediaTrack* track = (BMediaTrack*)fAudioTrackList.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return track->GetMetaData(metaData);
|
||||
// you need to hold the data lock
|
||||
if (fTrackSupplier == NULL)
|
||||
return B_NO_INIT;
|
||||
return fTrackSupplier->GetAudioMetaData(index, metaData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,13 +36,10 @@
|
||||
|
||||
|
||||
class AudioTrackSupplier;
|
||||
class BBitmap;
|
||||
class BMediaFile;
|
||||
class BMediaTrack;
|
||||
class TrackSupplier;
|
||||
class PlaylistItem;
|
||||
class ProxyAudioSupplier;
|
||||
class ProxyVideoSupplier;
|
||||
class SoundOutput;
|
||||
class VideoTrackSupplier;
|
||||
class VideoView;
|
||||
|
||||
@@ -186,22 +183,20 @@ private:
|
||||
virtual void NotifySeekHandled(int64 seekedFrame) const;
|
||||
|
||||
|
||||
private:
|
||||
VideoView* fVideoView;
|
||||
float fVolume;
|
||||
float fActiveVolume;
|
||||
bool fMuted;
|
||||
|
||||
PlaylistItemRef fItem;
|
||||
BMediaFile* fMediaFile;
|
||||
TrackSupplier* fTrackSupplier;
|
||||
|
||||
ProxyVideoSupplier* fVideoSupplier;
|
||||
ProxyAudioSupplier* fAudioSupplier;
|
||||
VideoTrackSupplier* fVideoTrackSupplier;
|
||||
AudioTrackSupplier* fAudioTrackSupplier;
|
||||
|
||||
BList fAudioTrackList;
|
||||
BList fVideoTrackList;
|
||||
|
||||
mutable int64 fCurrentFrame;
|
||||
bigtime_t fDuration;
|
||||
float fVideoFrameRate;
|
||||
|
||||
@@ -77,10 +77,12 @@ Application MediaPlayer :
|
||||
|
||||
# supplier
|
||||
AudioTrackSupplier.cpp
|
||||
MediaFileTrackSupplier.cpp
|
||||
MediaTrackAudioSupplier.cpp
|
||||
MediaTrackVideoSupplier.cpp
|
||||
ProxyAudioSupplier.cpp
|
||||
ProxyVideoSupplier.cpp
|
||||
TrackSupplier.cpp
|
||||
VideoTrackSupplier.cpp
|
||||
|
||||
# support
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2009 Stephan Aßmus <[email protected]>
|
||||
* Copyright 2009-2010 Stephan Aßmus <[email protected]>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <MediaFile.h>
|
||||
#include <Path.h>
|
||||
|
||||
#include "MediaFileTrackSupplier.h"
|
||||
|
||||
|
||||
static const char* kPathKey = "path";
|
||||
|
||||
@@ -91,7 +93,39 @@ status_t
|
||||
FilePlaylistItem::SetAttribute(const Attribute& attribute,
|
||||
const BString& string)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
switch (attribute) {
|
||||
case ATTR_STRING_NAME:
|
||||
{
|
||||
BEntry entry(&fRef, false);
|
||||
return entry.Rename(string.String(), false);
|
||||
}
|
||||
|
||||
case ATTR_STRING_KEYWORDS:
|
||||
return _SetAttribute("Meta:Keywords", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
|
||||
case ATTR_STRING_ARTIST:
|
||||
return _SetAttribute("Audio:Artist", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
case ATTR_STRING_AUTHOR:
|
||||
return _SetAttribute("Media:Author", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
case ATTR_STRING_ALBUM:
|
||||
return _SetAttribute("Audio:Album", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
case ATTR_STRING_TITLE:
|
||||
return _SetAttribute("Media:Title", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
case ATTR_STRING_AUDIO_BITRATE:
|
||||
return _SetAttribute("Audio:Bitrate", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
case ATTR_STRING_VIDEO_BITRATE:
|
||||
return _SetAttribute("Video:Bitrate", B_STRING_TYPE,
|
||||
string.String(), string.Length());
|
||||
|
||||
default:
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +137,7 @@ FilePlaylistItem::GetAttribute(const Attribute& attribute,
|
||||
string = fRef.name;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
@@ -111,7 +146,20 @@ status_t
|
||||
FilePlaylistItem::SetAttribute(const Attribute& attribute,
|
||||
const int32& value)
|
||||
{
|
||||
return B_NOT_SUPPORTED;
|
||||
switch (attribute) {
|
||||
case ATTR_INT32_TRACK:
|
||||
return _SetAttribute("Audio:Track", B_INT32_TYPE, &value,
|
||||
sizeof(int32));
|
||||
case ATTR_INT32_YEAR:
|
||||
return _SetAttribute("Media:Year", B_INT32_TYPE, &value,
|
||||
sizeof(int32));
|
||||
case ATTR_INT32_RATING:
|
||||
return _SetAttribute("Media:Rating", B_INT32_TYPE, &value,
|
||||
sizeof(int32));
|
||||
|
||||
default:
|
||||
return B_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -292,9 +340,55 @@ BEntry entry(path.Path());
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
BMediaFile*
|
||||
FilePlaylistItem::CreateMediaFile() const
|
||||
TrackSupplier*
|
||||
FilePlaylistItem::CreateTrackSupplier() const
|
||||
{
|
||||
return new (std::nothrow) BMediaFile(&fRef);
|
||||
BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRef);
|
||||
if (mediaFile == NULL)
|
||||
return NULL;
|
||||
TrackSupplier* supplier
|
||||
= new(std::nothrow) MediaFileTrackSupplier(mediaFile);
|
||||
if (supplier == NULL)
|
||||
delete mediaFile;
|
||||
|
||||
return supplier;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::_SetAttribute(const char* attrName, type_code type,
|
||||
const void* data, size_t size)
|
||||
{
|
||||
BEntry entry(&fRef, true);
|
||||
BNode node(&entry);
|
||||
if (node.InitCheck() != B_OK)
|
||||
return node.InitCheck();
|
||||
|
||||
ssize_t written = node.WriteAttr(attrName, type, 0, data, size);
|
||||
if (written != (ssize_t)size) {
|
||||
if (written < 0)
|
||||
return (status_t)written;
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::_GetAttribute(const char* attrName, type_code type,
|
||||
void* data, size_t size)
|
||||
{
|
||||
BEntry entry(&fRef, true);
|
||||
BNode node(&entry);
|
||||
if (node.InitCheck() != B_OK)
|
||||
return node.InitCheck();
|
||||
|
||||
ssize_t read = node.ReadAttr(attrName, type, 0, data, size);
|
||||
if (read != (ssize_t)size) {
|
||||
if (read < 0)
|
||||
return (status_t)read;
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright © 2009 Stephan Aßmus <[email protected]>
|
||||
* Copyright 2009-2010 Stephan Aßmus <[email protected]>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef FILE_PLAYLIST_ITEM_H
|
||||
@@ -48,10 +48,18 @@ public:
|
||||
virtual status_t RestoreFromTrash();
|
||||
|
||||
// playback
|
||||
virtual BMediaFile* CreateMediaFile() const;
|
||||
virtual TrackSupplier* CreateTrackSupplier() const;
|
||||
|
||||
const entry_ref& Ref() const { return fRef; }
|
||||
|
||||
private:
|
||||
status_t _SetAttribute(const char* attrName,
|
||||
type_code type, const void* data,
|
||||
size_t size);
|
||||
status_t _GetAttribute(const char* attrName,
|
||||
type_code type, void* data,
|
||||
size_t size);
|
||||
|
||||
private:
|
||||
entry_ref fRef;
|
||||
BString fNameInTrash;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009 Stephan Aßmus <[email protected]>
|
||||
* Copyright 2009-2010 Stephan Aßmus <[email protected]>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
@@ -100,26 +100,6 @@ PlaylistItem::TrackNumber() const
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
PlaylistItem::BitRate() const
|
||||
{
|
||||
int32 bitrate;
|
||||
if (GetAttribute(ATTR_INT32_BIT_RATE, bitrate) != B_OK)
|
||||
bitrate = 0;
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
|
||||
bigtime_t
|
||||
PlaylistItem::Duration() const
|
||||
{
|
||||
bigtime_t duration;
|
||||
if (GetAttribute(ATTR_INT64_DURATION, duration) != B_OK)
|
||||
duration = 0;
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItem::SetPlaybackFailed()
|
||||
{
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/*
|
||||
* Copyright 2009 Stephan Aßmus <[email protected]>
|
||||
* Copyright 2009-2010 Stephan Aßmus <[email protected]>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef PLAYLIST_ITEM_H
|
||||
#define PLAYLIST_ITEM_H
|
||||
|
||||
|
||||
#include <Archivable.h>
|
||||
#include <List.h>
|
||||
#include <NodeInfo.h>
|
||||
#include <Referenceable.h>
|
||||
#include <String.h>
|
||||
|
||||
class BBitmap;
|
||||
class BDataIO;
|
||||
class BMediaFile;
|
||||
class BMessage;
|
||||
|
||||
class PlaylistItem : public BArchivable, public Referenceable {
|
||||
class BBitmap;
|
||||
class BMessage;
|
||||
class TrackSupplier;
|
||||
|
||||
|
||||
class PlaylistItem : public BArchivable, public BReferenceable {
|
||||
public:
|
||||
class Listener {
|
||||
public:
|
||||
@@ -38,19 +40,20 @@ public:
|
||||
|
||||
// attributes
|
||||
typedef enum {
|
||||
ATTR_STRING_NAME = 'name',
|
||||
ATTR_STRING_KEYWORDS = 'kwrd',
|
||||
ATTR_STRING_NAME = 'name',
|
||||
ATTR_STRING_KEYWORDS = 'kwrd',
|
||||
|
||||
ATTR_STRING_AUTHOR = 'auth',
|
||||
ATTR_STRING_ALBUM = 'albm',
|
||||
ATTR_STRING_TITLE = 'titl',
|
||||
ATTR_STRING_ARTIST = 'arst',
|
||||
ATTR_STRING_AUTHOR = 'auth',
|
||||
ATTR_STRING_ALBUM = 'albm',
|
||||
ATTR_STRING_TITLE = 'titl',
|
||||
ATTR_STRING_AUDIO_BITRATE = 'abtr',
|
||||
ATTR_STRING_VIDEO_BITRATE = 'vbtr',
|
||||
ATTR_STRING_DURATION = 'drtn',
|
||||
|
||||
ATTR_INT32_TRACK = 'trck',
|
||||
ATTR_INT32_YEAR = 'year',
|
||||
ATTR_INT32_RATING = 'rtng',
|
||||
ATTR_INT32_BIT_RATE = 'btrt',
|
||||
|
||||
ATTR_INT64_DURATION = 'drtn'
|
||||
ATTR_INT32_TRACK = 'trck',
|
||||
ATTR_INT32_YEAR = 'year',
|
||||
ATTR_INT32_RATING = 'rtng'
|
||||
} Attribute;
|
||||
|
||||
virtual status_t SetAttribute(const Attribute& attribute,
|
||||
@@ -75,9 +78,6 @@ public:
|
||||
BString Title() const;
|
||||
|
||||
int32 TrackNumber() const;
|
||||
int32 BitRate() const;
|
||||
|
||||
bigtime_t Duration() const;
|
||||
|
||||
// methods
|
||||
virtual BString LocationURI() const = 0;
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
virtual status_t RestoreFromTrash() = 0;
|
||||
|
||||
// playback
|
||||
virtual BMediaFile* CreateMediaFile() const = 0;
|
||||
virtual TrackSupplier* CreateTrackSupplier() const = 0;
|
||||
|
||||
void SetPlaybackFailed();
|
||||
bool PlaybackFailed() const
|
||||
@@ -106,6 +106,6 @@ private:
|
||||
bool fPlaybackFailed;
|
||||
};
|
||||
|
||||
typedef Reference<PlaylistItem> PlaylistItemRef;
|
||||
typedef BReference<PlaylistItem> PlaylistItemRef;
|
||||
|
||||
#endif // PLAYLIST_ITEM_H
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2010, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "MediaFileTrackSupplier.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <MediaFile.h>
|
||||
#include <MediaTrack.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "MediaTrackAudioSupplier.h"
|
||||
#include "MediaTrackVideoSupplier.h"
|
||||
|
||||
|
||||
MediaFileTrackSupplier::MediaFileTrackSupplier(BMediaFile* mediaFile)
|
||||
:
|
||||
TrackSupplier(),
|
||||
fMediaFile(mediaFile)
|
||||
{
|
||||
if (fMediaFile->InitCheck() != B_OK)
|
||||
return;
|
||||
int trackCount = fMediaFile->CountTracks();
|
||||
if (trackCount <= 0)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < trackCount; i++) {
|
||||
BMediaTrack* track = fMediaFile->TrackAt(i);
|
||||
media_format format;
|
||||
status_t status = track->EncodedFormat(&format);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for "
|
||||
"track index %d, error: %s\n", i, strerror(status));
|
||||
fMediaFile->ReleaseTrack(track);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (track->Duration() <= 0) {
|
||||
fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "
|
||||
"has no duration\n", i);
|
||||
}
|
||||
|
||||
if (format.IsAudio()) {
|
||||
if (!fAudioTracks.AddItem(track)) {
|
||||
fMediaFile->ReleaseTrack(track);
|
||||
return;
|
||||
}
|
||||
} else if (format.IsVideo()) {
|
||||
if (!fVideoTracks.AddItem(track)) {
|
||||
fMediaFile->ReleaseTrack(track);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
printf("MediaFileTrackSupplier: track index %d has unknown "
|
||||
"type\n", i);
|
||||
fMediaFile->ReleaseTrack(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MediaFileTrackSupplier::~MediaFileTrackSupplier()
|
||||
{
|
||||
delete fMediaFile;
|
||||
// BMediaFile destructor will call ReleaseAllTracks()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::InitCheck()
|
||||
{
|
||||
return fMediaFile->InitCheck();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetFileFormatInfo(media_file_format* fileFormat)
|
||||
{
|
||||
return fMediaFile->GetFileFormatInfo(fileFormat);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetCopyright(BString* copyright)
|
||||
{
|
||||
*copyright = fMediaFile->Copyright();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetMetaData(BMessage* metaData)
|
||||
{
|
||||
return fMediaFile->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MediaFileTrackSupplier::CountAudioTracks()
|
||||
{
|
||||
return fAudioTracks.CountItems();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
MediaFileTrackSupplier::CountVideoTracks()
|
||||
{
|
||||
return fVideoTracks.CountItems();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetAudioMetaData(int32 index, BMessage* metaData)
|
||||
{
|
||||
BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return track->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetVideoMetaData(int32 index, BMessage* metaData)
|
||||
{
|
||||
BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return B_BAD_INDEX;
|
||||
|
||||
return track->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
|
||||
AudioTrackSupplier*
|
||||
MediaFileTrackSupplier::CreateAudioTrackForIndex(int32 index)
|
||||
{
|
||||
BMediaTrack* track = (BMediaTrack*)fAudioTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return NULL;
|
||||
|
||||
return new(std::nothrow) MediaTrackAudioSupplier(track, index);
|
||||
}
|
||||
|
||||
|
||||
VideoTrackSupplier*
|
||||
MediaFileTrackSupplier::CreateVideoTrackForIndex(int32 index)
|
||||
{
|
||||
BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return NULL;
|
||||
|
||||
status_t initStatus;
|
||||
MediaTrackVideoSupplier* supplier
|
||||
= new(std::nothrow) MediaTrackVideoSupplier(track, index, initStatus);
|
||||
if (initStatus != B_OK) {
|
||||
delete supplier;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return supplier;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef MEDIA_FILE_TRACK_SUPPLIER_H
|
||||
#define MEDIA_FILE_TRACK_SUPPLIER_H
|
||||
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include "TrackSupplier.h"
|
||||
|
||||
|
||||
class BMediaFile;
|
||||
|
||||
|
||||
class MediaFileTrackSupplier : public TrackSupplier {
|
||||
public:
|
||||
MediaFileTrackSupplier(BMediaFile* mediaFile);
|
||||
virtual ~MediaFileTrackSupplier();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
|
||||
virtual status_t GetFileFormatInfo(
|
||||
media_file_format* fileFormat);
|
||||
virtual status_t GetCopyright(BString* copyright);
|
||||
virtual status_t GetMetaData(BMessage* metaData);
|
||||
|
||||
virtual int32 CountAudioTracks();
|
||||
virtual int32 CountVideoTracks();
|
||||
|
||||
virtual status_t GetAudioMetaData(int32 index,
|
||||
BMessage* metaData);
|
||||
virtual status_t GetVideoMetaData(int32 index,
|
||||
BMessage* metaData);
|
||||
|
||||
virtual AudioTrackSupplier* CreateAudioTrackForIndex(int32 index);
|
||||
virtual VideoTrackSupplier* CreateVideoTrackForIndex(int32 index);
|
||||
|
||||
private:
|
||||
BMediaFile* fMediaFile;
|
||||
BList fAudioTracks;
|
||||
BList fVideoTracks;
|
||||
};
|
||||
|
||||
|
||||
#endif // MEDIA_FILE_TRACK_SUPPLIER_H
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "TrackSupplier.h"
|
||||
|
||||
|
||||
TrackSupplier::TrackSupplier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TrackSupplier::~TrackSupplier()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010, Stephan Aßmus <[email protected]>. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef TRACK_SUPPLIER_H
|
||||
#define TRACK_SUPPLIER_H
|
||||
|
||||
|
||||
#include <MediaDefs.h>
|
||||
#include <MediaFormats.h>
|
||||
|
||||
#include "AudioTrackSupplier.h"
|
||||
#include "VideoTrackSupplier.h"
|
||||
|
||||
|
||||
class BMessage;
|
||||
class BString;
|
||||
|
||||
|
||||
class TrackSupplier {
|
||||
public:
|
||||
TrackSupplier();
|
||||
virtual ~TrackSupplier();
|
||||
|
||||
virtual status_t InitCheck() = 0;
|
||||
|
||||
virtual status_t GetFileFormatInfo(
|
||||
media_file_format* fileFormat) = 0;
|
||||
virtual status_t GetCopyright(BString* copyright) = 0;
|
||||
virtual status_t GetMetaData(BMessage* metaData) = 0;
|
||||
|
||||
virtual int32 CountAudioTracks() = 0;
|
||||
virtual int32 CountVideoTracks() = 0;
|
||||
|
||||
virtual status_t GetAudioMetaData(int32 index,
|
||||
BMessage* metaData) = 0;
|
||||
virtual status_t GetVideoMetaData(int32 index,
|
||||
BMessage* metaData) = 0;
|
||||
|
||||
virtual AudioTrackSupplier* CreateAudioTrackForIndex(int32 index) = 0;
|
||||
virtual VideoTrackSupplier* CreateVideoTrackForIndex(int32 index) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // TRACK_SUPPLIER_H
|
||||
Reference in New Issue
Block a user