Patch by SHINTA: add MediaPlayer cover image/artwork support.
This implemented #7430 enhancement. Arigato gozaimasu! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41271 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bf3381e771
commit
ec2878c3cf
@ -77,6 +77,7 @@ Application MediaPlayer :
|
||||
|
||||
# supplier
|
||||
AudioTrackSupplier.cpp
|
||||
ImageTrackVideoSupplier.cpp
|
||||
MediaFileTrackSupplier.cpp
|
||||
MediaTrackAudioSupplier.cpp
|
||||
MediaTrackVideoSupplier.cpp
|
||||
|
@ -14,39 +14,48 @@
|
||||
#include <FindDirectory.h>
|
||||
#include <MediaFile.h>
|
||||
#include <Path.h>
|
||||
#include <TranslationUtils.h>
|
||||
|
||||
#include "MediaFileTrackSupplier.h"
|
||||
#include "SubTitlesSRT.h"
|
||||
|
||||
|
||||
static const char* kPathKey = "path";
|
||||
|
||||
|
||||
FilePlaylistItem::FilePlaylistItem(const entry_ref& ref)
|
||||
:
|
||||
fRef(ref),
|
||||
fNameInTrash("")
|
||||
{
|
||||
fRefs.push_back(ref);
|
||||
fNamesInTrash.push_back("");
|
||||
}
|
||||
|
||||
|
||||
FilePlaylistItem::FilePlaylistItem(const FilePlaylistItem& other)
|
||||
:
|
||||
fRef(other.fRef),
|
||||
fNameInTrash(other.fNameInTrash)
|
||||
fRefs(other.fRefs),
|
||||
fNamesInTrash(other.fNamesInTrash),
|
||||
fImageRefs(other.fImageRefs),
|
||||
fImageNamesInTrash(other.fImageNamesInTrash)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FilePlaylistItem::FilePlaylistItem(const BMessage* archive)
|
||||
:
|
||||
fRef(),
|
||||
fNameInTrash("")
|
||||
{
|
||||
const char* path;
|
||||
if (archive != NULL && archive->FindString(kPathKey, &path) == B_OK) {
|
||||
if (get_ref_for_path(path, &fRef) != B_OK)
|
||||
fRef = entry_ref();
|
||||
entry_ref ref;
|
||||
if (archive != NULL) {
|
||||
int32 i = 0;
|
||||
while (archive->FindString(kPathKey, i, &path) == B_OK) {
|
||||
if (get_ref_for_path(path, &ref) == B_OK) {
|
||||
fRefs.push_back(ref);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (fRefs.empty()) {
|
||||
fRefs.push_back(entry_ref());
|
||||
}
|
||||
for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
|
||||
fNamesInTrash.push_back("");
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,11 +91,16 @@ FilePlaylistItem::Archive(BMessage* into, bool deep) const
|
||||
status_t ret = BArchivable::Archive(into, deep);
|
||||
if (ret != B_OK)
|
||||
return ret;
|
||||
BPath path(&fRef);
|
||||
ret = path.InitCheck();
|
||||
if (ret == B_OK)
|
||||
for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
|
||||
BPath path(&fRefs[i]);
|
||||
ret = path.InitCheck();
|
||||
if (ret != B_OK)
|
||||
return ret;
|
||||
ret = into->AddString(kPathKey, path.Path());
|
||||
return ret;
|
||||
if (ret != B_OK)
|
||||
return ret;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -97,7 +111,7 @@ FilePlaylistItem::SetAttribute(const Attribute& attribute,
|
||||
switch (attribute) {
|
||||
case ATTR_STRING_NAME:
|
||||
{
|
||||
BEntry entry(&fRef, false);
|
||||
BEntry entry(&fRefs[0], false);
|
||||
return entry.Rename(string.String(), false);
|
||||
}
|
||||
|
||||
@ -135,7 +149,7 @@ FilePlaylistItem::GetAttribute(const Attribute& attribute,
|
||||
BString& string) const
|
||||
{
|
||||
if (attribute == ATTR_STRING_NAME) {
|
||||
string = fRef.name;
|
||||
string = fRefs[0].name;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -194,7 +208,7 @@ FilePlaylistItem::GetAttribute(const Attribute& attribute,
|
||||
BString
|
||||
FilePlaylistItem::LocationURI() const
|
||||
{
|
||||
BPath path(&fRef);
|
||||
BPath path(&fRefs[0]);
|
||||
BString locationURI("file://");
|
||||
locationURI << path.Path();
|
||||
return locationURI;
|
||||
@ -204,7 +218,7 @@ FilePlaylistItem::LocationURI() const
|
||||
status_t
|
||||
FilePlaylistItem::GetIcon(BBitmap* bitmap, icon_size iconSize) const
|
||||
{
|
||||
BNode node(&fRef);
|
||||
BNode node(&fRefs[0]);
|
||||
BNodeInfo info(&node);
|
||||
return info.GetTrackerIcon(bitmap, iconSize);
|
||||
}
|
||||
@ -213,150 +227,82 @@ FilePlaylistItem::GetIcon(BBitmap* bitmap, icon_size iconSize) const
|
||||
status_t
|
||||
FilePlaylistItem::MoveIntoTrash()
|
||||
{
|
||||
if (fNameInTrash.Length() != 0) {
|
||||
if (fNamesInTrash[0].Length() != 0) {
|
||||
// Already in the trash!
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
char trashPath[B_PATH_NAME_LENGTH];
|
||||
status_t err = find_directory(B_TRASH_DIRECTORY, fRef.device,
|
||||
true /*create it*/, trashPath, B_PATH_NAME_LENGTH);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
|
||||
status_t err;
|
||||
err = _MoveIntoTrash(&fRefs, &fNamesInTrash);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (fImageRefs.empty())
|
||||
return B_OK;
|
||||
|
||||
BEntry entry(&fRef);
|
||||
err = entry.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BEntry for %s: %s\n",
|
||||
fRef.name, strerror(err));
|
||||
err = _MoveIntoTrash(&fImageRefs, &fImageNamesInTrash);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
}
|
||||
BDirectory trashDir(trashPath);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BDirectory for %s: %s\n",
|
||||
trashPath, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Find a unique name for the entry in the trash
|
||||
fNameInTrash = fRef.name;
|
||||
int32 uniqueNameIndex = 1;
|
||||
while (true) {
|
||||
BEntry test(&trashDir, fNameInTrash.String());
|
||||
if (!test.Exists())
|
||||
break;
|
||||
fNameInTrash = fRef.name;
|
||||
fNameInTrash << ' ' << uniqueNameIndex;
|
||||
uniqueNameIndex++;
|
||||
}
|
||||
|
||||
// Remember the original path
|
||||
BPath originalPath;
|
||||
entry.GetPath(&originalPath);
|
||||
|
||||
// Finally, move the entry into the trash
|
||||
err = entry.MoveTo(&trashDir, fNameInTrash.String());
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to move entry into trash %s: %s\n",
|
||||
trashPath, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Allow Tracker to restore this entry
|
||||
BNode node(&entry);
|
||||
BString originalPathString(originalPath.Path());
|
||||
node.WriteAttrString("_trk/original_path", &originalPathString);
|
||||
|
||||
return err;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::RestoreFromTrash()
|
||||
{
|
||||
if (fNameInTrash.Length() <= 0) {
|
||||
if (fNamesInTrash[0].Length() <= 0) {
|
||||
// Not in the trash!
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
char trashPath[B_PATH_NAME_LENGTH];
|
||||
status_t err = find_directory(B_TRASH_DIRECTORY, fRef.device,
|
||||
false /*create it*/, trashPath, B_PATH_NAME_LENGTH);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
|
||||
status_t err;
|
||||
err = _RestoreFromTrash(&fRefs, &fNamesInTrash);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
}
|
||||
// construct the entry to the file in the trash
|
||||
// TODO: BEntry(const BDirectory* directory, const char* path) is broken!
|
||||
// BEntry entry(trashPath, fNamesInTrash[i].String());
|
||||
BPath path(trashPath, fNameInTrash.String());
|
||||
BEntry entry(path.Path());
|
||||
err = entry.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BEntry for %s: %s\n",
|
||||
fNameInTrash.String(), strerror(err));
|
||||
|
||||
if (fImageRefs.empty())
|
||||
return B_OK;
|
||||
|
||||
err = _RestoreFromTrash(&fImageRefs, &fImageNamesInTrash);
|
||||
if (err != B_OK)
|
||||
return err;
|
||||
}
|
||||
//entry.GetPath(&path);
|
||||
//printf("moving '%s'\n", path.Path());
|
||||
|
||||
// construct the folder of the original entry_ref
|
||||
node_ref nodeRef;
|
||||
nodeRef.device = fRef.device;
|
||||
nodeRef.node = fRef.directory;
|
||||
BDirectory originalDir(&nodeRef);
|
||||
err = originalDir.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init original BDirectory for "
|
||||
"%s: %s\n", fRef.name, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
//path.SetTo(&originalDir, fItems[i].name);
|
||||
//printf("as '%s'\n", path.Path());
|
||||
|
||||
// Reset the name here, the user may have already moved the entry
|
||||
// out of the trash via Tracker for example.
|
||||
fNameInTrash = "";
|
||||
|
||||
// Finally, move the entry back into the original folder
|
||||
err = entry.MoveTo(&originalDir, fRef.name);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to restore entry from trash "
|
||||
"%s: %s\n", fRef.name, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Remove the attribute that helps Tracker restore the entry.
|
||||
BNode node(&entry);
|
||||
node.RemoveAttr("_trk/original_path");
|
||||
|
||||
return err;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
TrackSupplier*
|
||||
FilePlaylistItem::CreateTrackSupplier() const
|
||||
{
|
||||
BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRef);
|
||||
if (mediaFile == NULL)
|
||||
return NULL;
|
||||
MediaFileTrackSupplier* supplier
|
||||
= new(std::nothrow) MediaFileTrackSupplier(mediaFile);
|
||||
if (supplier == NULL) {
|
||||
delete mediaFile;
|
||||
= new(std::nothrow) MediaFileTrackSupplier();
|
||||
if (supplier == NULL)
|
||||
return NULL;
|
||||
|
||||
for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
|
||||
BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRefs[i]);
|
||||
if (mediaFile == NULL) {
|
||||
delete supplier;
|
||||
return NULL;
|
||||
}
|
||||
if (supplier->AddMediaFile(mediaFile) != B_OK)
|
||||
delete mediaFile;
|
||||
}
|
||||
|
||||
for (vector<entry_ref>::size_type i = 0; i < fImageRefs.size(); i++) {
|
||||
BBitmap* bitmap = BTranslationUtils::GetBitmap(&fImageRefs[i]);
|
||||
if (bitmap == NULL)
|
||||
continue;
|
||||
if (supplier->AddBitmap(bitmap) != B_OK)
|
||||
delete bitmap;
|
||||
}
|
||||
|
||||
// Search for subtitle files in the same folder
|
||||
// TODO: Error checking
|
||||
BEntry entry(&fRef, true);
|
||||
BEntry entry(&fRefs[0], true);
|
||||
|
||||
char originalName[B_FILE_NAME_LENGTH];
|
||||
entry.GetName(originalName);
|
||||
@ -410,11 +356,41 @@ FilePlaylistItem::CreateTrackSupplier() const
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::AddRef(const entry_ref& ref)
|
||||
{
|
||||
fRefs.push_back(ref);
|
||||
fNamesInTrash.push_back("");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::AddImageRef(const entry_ref& ref)
|
||||
{
|
||||
fImageRefs.push_back(ref);
|
||||
fImageNamesInTrash.push_back("");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
const entry_ref&
|
||||
FilePlaylistItem::ImageRef() const
|
||||
{
|
||||
static entry_ref ref;
|
||||
|
||||
if (fImageRefs.empty())
|
||||
return ref;
|
||||
|
||||
return fImageRefs[0];
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::_SetAttribute(const char* attrName, type_code type,
|
||||
const void* data, size_t size)
|
||||
{
|
||||
BEntry entry(&fRef, true);
|
||||
BEntry entry(&fRefs[0], true);
|
||||
BNode node(&entry);
|
||||
if (node.InitCheck() != B_OK)
|
||||
return node.InitCheck();
|
||||
@ -433,7 +409,7 @@ status_t
|
||||
FilePlaylistItem::_GetAttribute(const char* attrName, type_code type,
|
||||
void* data, size_t size)
|
||||
{
|
||||
BEntry entry(&fRef, true);
|
||||
BEntry entry(&fRefs[0], true);
|
||||
BNode node(&entry);
|
||||
if (node.InitCheck() != B_OK)
|
||||
return node.InitCheck();
|
||||
@ -447,3 +423,128 @@ FilePlaylistItem::_GetAttribute(const char* attrName, type_code type,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs,
|
||||
vector<BString>* namesInTrash)
|
||||
{
|
||||
char trashPath[B_PATH_NAME_LENGTH];
|
||||
status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device,
|
||||
true /*create it*/, trashPath, B_PATH_NAME_LENGTH);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
BDirectory trashDir(trashPath);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BDirectory for %s: %s\n",
|
||||
trashPath, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) {
|
||||
BEntry entry(&(*refs)[i]);
|
||||
err = entry.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BEntry for %s: %s\n",
|
||||
(*refs)[i].name, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Find a unique name for the entry in the trash
|
||||
(*namesInTrash)[i] = (*refs)[i].name;
|
||||
int32 uniqueNameIndex = 1;
|
||||
while (true) {
|
||||
BEntry test(&trashDir, (*namesInTrash)[i].String());
|
||||
if (!test.Exists())
|
||||
break;
|
||||
(*namesInTrash)[i] = (*refs)[i].name;
|
||||
(*namesInTrash)[i] << ' ' << uniqueNameIndex;
|
||||
uniqueNameIndex++;
|
||||
}
|
||||
|
||||
// Remember the original path
|
||||
BPath originalPath;
|
||||
entry.GetPath(&originalPath);
|
||||
|
||||
// Finally, move the entry into the trash
|
||||
err = entry.MoveTo(&trashDir, (*namesInTrash)[i].String());
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to move entry into trash %s: %s\n",
|
||||
trashPath, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Allow Tracker to restore this entry
|
||||
BNode node(&entry);
|
||||
BString originalPathString(originalPath.Path());
|
||||
node.WriteAttrString("_trk/original_path", &originalPathString);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs,
|
||||
vector<BString>* namesInTrash)
|
||||
{
|
||||
char trashPath[B_PATH_NAME_LENGTH];
|
||||
status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device,
|
||||
false /*create it*/, trashPath, B_PATH_NAME_LENGTH);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) {
|
||||
// construct the entry to the file in the trash
|
||||
// TODO: BEntry(const BDirectory* directory, const char* path) is broken!
|
||||
// BEntry entry(trashPath, (*namesInTrash)[i].String());
|
||||
BPath path(trashPath, (*namesInTrash)[i].String());
|
||||
BEntry entry(path.Path());
|
||||
err = entry.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init BEntry for %s: %s\n",
|
||||
(*namesInTrash)[i].String(), strerror(err));
|
||||
return err;
|
||||
}
|
||||
//entry.GetPath(&path);
|
||||
//printf("moving '%s'\n", path.Path());
|
||||
|
||||
// construct the folder of the original entry_ref
|
||||
node_ref nodeRef;
|
||||
nodeRef.device = (*refs)[i].device;
|
||||
nodeRef.node = (*refs)[i].directory;
|
||||
BDirectory originalDir(&nodeRef);
|
||||
err = originalDir.InitCheck();
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to init original BDirectory for "
|
||||
"%s: %s\n", (*refs)[i].name, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
//path.SetTo(&originalDir, fItems[i].name);
|
||||
//printf("as '%s'\n", path.Path());
|
||||
|
||||
// Reset the name here, the user may have already moved the entry
|
||||
// out of the trash via Tracker for example.
|
||||
(*namesInTrash)[i] = "";
|
||||
|
||||
// Finally, move the entry back into the original folder
|
||||
err = entry.MoveTo(&originalDir, (*refs)[i].name);
|
||||
if (err != B_OK) {
|
||||
fprintf(stderr, "failed to restore entry from trash "
|
||||
"%s: %s\n", (*refs)[i].name, strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
// Remove the attribute that helps Tracker restore the entry.
|
||||
BNode node(&entry);
|
||||
node.RemoveAttr("_trk/original_path");
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,13 @@
|
||||
|
||||
#include "PlaylistItem.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Entry.h>
|
||||
|
||||
using std::vector;
|
||||
|
||||
|
||||
class FilePlaylistItem : public PlaylistItem {
|
||||
public:
|
||||
FilePlaylistItem(const entry_ref& ref);
|
||||
@ -50,7 +55,11 @@ public:
|
||||
// playback
|
||||
virtual TrackSupplier* CreateTrackSupplier() const;
|
||||
|
||||
const entry_ref& Ref() const { return fRef; }
|
||||
status_t AddRef(const entry_ref& ref);
|
||||
const entry_ref& Ref() const { return fRefs[0]; }
|
||||
|
||||
status_t AddImageRef(const entry_ref& ref);
|
||||
const entry_ref& ImageRef() const;
|
||||
|
||||
private:
|
||||
status_t _SetAttribute(const char* attrName,
|
||||
@ -59,10 +68,18 @@ private:
|
||||
status_t _GetAttribute(const char* attrName,
|
||||
type_code type, void* data,
|
||||
size_t size);
|
||||
status_t _MoveIntoTrash(vector<entry_ref>* refs,
|
||||
vector<BString>* namesInTrash);
|
||||
status_t _RestoreFromTrash(vector<entry_ref>* refs,
|
||||
vector<BString>* namesInTrash);
|
||||
|
||||
private:
|
||||
entry_ref fRef;
|
||||
BString fNameInTrash;
|
||||
// always fRefs.size() == fNamesInTrash.size()
|
||||
vector<entry_ref> fRefs;
|
||||
vector<BString> fNamesInTrash;
|
||||
// always fImageRefs.size() == fImageNamesInTrash.size()
|
||||
vector<entry_ref> fImageRefs;
|
||||
vector<BString> fImageNamesInTrash;
|
||||
};
|
||||
|
||||
#endif // FILE_PLAYLIST_ITEM_H
|
||||
|
@ -57,14 +57,20 @@ ImportPLItemsCommand::ImportPLItemsCommand(Playlist* playlist,
|
||||
memset(fNewItems, 0, fNewCount * sizeof(PlaylistItem*));
|
||||
|
||||
// init new entries
|
||||
int32 added = 0;
|
||||
for (int32 i = 0; i < fNewCount; i++) {
|
||||
fNewItems[i] = temp.ItemAtFast(i)->Clone();
|
||||
if (fNewItems[i] == NULL) {
|
||||
// indicate bad object init
|
||||
_CleanUp(fNewItems, fNewCount, true);
|
||||
return;
|
||||
FilePlaylistItem* fileItem = dynamic_cast<FilePlaylistItem*>(temp.ItemAtFast(i));
|
||||
if (fileItem && !Playlist::ExtraMediaExists(playlist, fileItem->Ref())) {
|
||||
fNewItems[added] = temp.ItemAtFast(i)->Clone();
|
||||
if (fNewItems[added] == NULL) {
|
||||
// indicate bad object init
|
||||
_CleanUp(fNewItems, fNewCount, true);
|
||||
return;
|
||||
}
|
||||
added++;
|
||||
}
|
||||
}
|
||||
fNewCount = added;
|
||||
|
||||
fPlaylingIndex = fPlaylist->CurrentItemIndex();
|
||||
|
||||
|
@ -456,8 +456,11 @@ Playlist::AppendRefs(const BMessage* refsReceivedMessage, int32 appendIndex)
|
||||
} else {
|
||||
if (_IsQuery(type))
|
||||
AppendQueryToPlaylist(ref, &subPlaylist);
|
||||
else
|
||||
AppendToPlaylistRecursive(ref, &subPlaylist);
|
||||
else {
|
||||
if ( !ExtraMediaExists(this, ref) ) {
|
||||
AppendToPlaylistRecursive(ref, &subPlaylist);
|
||||
}
|
||||
}
|
||||
|
||||
// At least sort this subsection of the playlist
|
||||
// if the whole playlist is not sorted anymore.
|
||||
@ -510,7 +513,11 @@ Playlist::AppendToPlaylistRecursive(const entry_ref& ref, Playlist* playlist)
|
||||
BString mimeString = _MIMEString(&ref);
|
||||
if (_IsMediaFile(mimeString)) {
|
||||
PlaylistItem* item = new (std::nothrow) FilePlaylistItem(ref);
|
||||
if (item != NULL && !playlist->AddItem(item))
|
||||
if (!ExtraMediaExists(playlist, ref)) {
|
||||
_BindExtraMedia(item);
|
||||
if (item != NULL && !playlist->AddItem(item))
|
||||
delete item;
|
||||
} else
|
||||
delete item;
|
||||
} else
|
||||
printf("MIME Type = %s\n", mimeString.String());
|
||||
@ -584,9 +591,42 @@ Playlist::NotifyImportFailed()
|
||||
}
|
||||
|
||||
|
||||
/*static*/ bool
|
||||
Playlist::ExtraMediaExists(Playlist* playlist, const entry_ref& ref)
|
||||
{
|
||||
BString exceptExtension = _GetExceptExtension(BPath(&ref).Path());
|
||||
|
||||
for (int32 i = 0; i < playlist->CountItems(); i++) {
|
||||
FilePlaylistItem* compare = dynamic_cast<FilePlaylistItem*>(playlist->ItemAt(i));
|
||||
if (compare == NULL)
|
||||
continue;
|
||||
if (compare->Ref() != ref
|
||||
&& _GetExceptExtension(BPath(&compare->Ref()).Path()) == exceptExtension )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - private
|
||||
|
||||
|
||||
/*static*/ bool
|
||||
Playlist::_IsImageFile(const BString& mimeString)
|
||||
{
|
||||
BMimeType superType;
|
||||
BMimeType fileType(mimeString.String());
|
||||
|
||||
if (fileType.GetSupertype(&superType) != B_OK)
|
||||
return false;
|
||||
|
||||
if (superType == "image")
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ bool
|
||||
Playlist::_IsMediaFile(const BString& mimeString)
|
||||
{
|
||||
@ -668,6 +708,62 @@ Playlist::_MIMEString(const entry_ref* ref)
|
||||
}
|
||||
|
||||
|
||||
// _BindExtraMedia() searches additional videos and audios
|
||||
// and addes them as extra medias.
|
||||
/*static*/ void
|
||||
Playlist::_BindExtraMedia(PlaylistItem* item)
|
||||
{
|
||||
FilePlaylistItem* fileItem = dynamic_cast<FilePlaylistItem*>(item);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
// If the media file is foo.mp3, _BindExtraMedia() searches foo.avi.
|
||||
BPath mediaFilePath(&fileItem->Ref());
|
||||
BString mediaFilePathString = mediaFilePath.Path();
|
||||
BPath dirPath;
|
||||
mediaFilePath.GetParent(&dirPath);
|
||||
BDirectory dir(dirPath.Path());
|
||||
if (dir.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
BEntry entry;
|
||||
BString entryPathString;
|
||||
while (dir.GetNextEntry(&entry, true) == B_OK) {
|
||||
if (!entry.IsFile())
|
||||
continue;
|
||||
entryPathString = BPath(&entry).Path();
|
||||
if (entryPathString != mediaFilePathString
|
||||
&& _GetExceptExtension(entryPathString) == _GetExceptExtension(mediaFilePathString)) {
|
||||
_BindExtraMedia(fileItem, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
Playlist::_BindExtraMedia(FilePlaylistItem* fileItem, const BEntry& entry)
|
||||
{
|
||||
entry_ref ref;
|
||||
entry.GetRef(&ref);
|
||||
BString mimeString = _MIMEString(&ref);
|
||||
if (_IsMediaFile(mimeString)) {
|
||||
fileItem->AddRef(ref);
|
||||
} else if (_IsImageFile(mimeString)) {
|
||||
fileItem->AddImageRef(ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ BString
|
||||
Playlist::_GetExceptExtension(const BString& path)
|
||||
{
|
||||
int32 periodPos = path.FindLast('.');
|
||||
if (periodPos <= path.FindLast('/'))
|
||||
return path;
|
||||
return BString(path.String(), periodPos);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - notifications
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <List.h>
|
||||
#include <Locker.h>
|
||||
|
||||
#include "FilePlaylistItem.h"
|
||||
#include "PlaylistItem.h"
|
||||
|
||||
class BDataIO;
|
||||
@ -113,17 +114,23 @@ public:
|
||||
|
||||
void NotifyImportFailed();
|
||||
|
||||
static bool ExtraMediaExists(Playlist* playlist, const entry_ref& ref);
|
||||
|
||||
private:
|
||||
Playlist(const Playlist& other);
|
||||
Playlist& operator=(const Playlist& other);
|
||||
// unimplemented
|
||||
|
||||
static bool _IsImageFile(const BString& mimeString);
|
||||
static bool _IsMediaFile(const BString& mimeString);
|
||||
static bool _IsTextPlaylist(const BString& mimeString);
|
||||
static bool _IsBinaryPlaylist(const BString& mimeString);
|
||||
static bool _IsPlaylist(const BString& mimeString);
|
||||
static bool _IsQuery(const BString& mimeString);
|
||||
static BString _MIMEString(const entry_ref* ref);
|
||||
static void _BindExtraMedia(PlaylistItem* item);
|
||||
static void _BindExtraMedia(FilePlaylistItem* fileItem, const BEntry& entry);
|
||||
static BString _GetExceptExtension(const BString& path);
|
||||
|
||||
void _NotifyItemAdded(PlaylistItem*,
|
||||
int32 index) const;
|
||||
|
117
src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp
Normal file
117
src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* SHINTA
|
||||
*/
|
||||
#include "ImageTrackVideoSupplier.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
ImageTrackVideoSupplier::ImageTrackVideoSupplier(BBitmap* bitmap,
|
||||
int32 trackIndex, status_t& initStatus)
|
||||
:
|
||||
VideoTrackSupplier(),
|
||||
fPerformanceTime(0),
|
||||
fDuration(0),
|
||||
fCurrentFrame(0),
|
||||
fBitmap(bitmap),
|
||||
fTrackIndex(trackIndex)
|
||||
{
|
||||
fFormat.type = B_MEDIA_ENCODED_VIDEO;
|
||||
fFormat.u.encoded_video.output.field_rate = 0.0;
|
||||
fFormat.u.encoded_video.output.interlace = 1;
|
||||
fFormat.u.encoded_video.output.first_active = 0;
|
||||
fFormat.u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
|
||||
fFormat.u.encoded_video.output.display.format = B_RGB32;
|
||||
fFormat.u.encoded_video.output.pixel_width_aspect
|
||||
= fFormat.u.raw_video.display.line_width
|
||||
= static_cast<int32>(fBitmap->Bounds().right) + 1;
|
||||
fFormat.u.encoded_video.output.pixel_height_aspect
|
||||
= fFormat.u.raw_video.display.line_count
|
||||
= static_cast<int32>(fBitmap->Bounds().bottom) + 1;
|
||||
fFormat.u.encoded_video.output.display.bytes_per_row
|
||||
= fFormat.u.raw_video.display.line_width * sizeof(int32);
|
||||
fFormat.u.encoded_video.output.display.pixel_offset = 0;
|
||||
fFormat.u.encoded_video.output.display.line_offset = 0;
|
||||
fFormat.u.encoded_video.output.display.flags = 0;
|
||||
fFormat.u.encoded_video.output.last_active
|
||||
= fFormat.u.raw_video.display.line_count - 1;
|
||||
fFormat.u.encoded_video.avg_bit_rate = 0.0;
|
||||
fFormat.u.encoded_video.max_bit_rate = 0.0;
|
||||
fFormat.u.encoded_video.encoding = media_encoded_video_format::B_ANY;
|
||||
fFormat.u.encoded_video.frame_size
|
||||
= fFormat.u.encoded_video.output.display.bytes_per_row *
|
||||
fFormat.u.raw_video.display.line_count;
|
||||
fFormat.u.encoded_video.forward_history = 0;
|
||||
fFormat.u.encoded_video.backward_history = 0;
|
||||
|
||||
initStatus = B_OK;
|
||||
}
|
||||
|
||||
|
||||
ImageTrackVideoSupplier::~ImageTrackVideoSupplier()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const media_format&
|
||||
ImageTrackVideoSupplier::Format() const
|
||||
{
|
||||
return fFormat;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::GetEncodedFormat(media_format* format) const
|
||||
{
|
||||
*format = fFormat;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::GetCodecInfo(media_codec_info* info) const
|
||||
{
|
||||
strlcpy(info->pretty_name, "Artwork (static image)",
|
||||
sizeof(info->pretty_name));
|
||||
strlcpy(info->short_name, "Artwork", sizeof(info->short_name));
|
||||
info->id = info->sub_id = 0;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::ReadFrame(void* buffer, bigtime_t* performanceTime,
|
||||
const media_raw_video_format& format, bool& wasCached)
|
||||
{
|
||||
uint32 size = format.display.bytes_per_row * format.display.line_count;
|
||||
memcpy(buffer, fBitmap->Bits(), size);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::FindKeyFrameForFrame(int64* frame)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::SeekToTime(bigtime_t* performanceTime)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ImageTrackVideoSupplier::SeekToFrame(int64* frame)
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
63
src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h
Normal file
63
src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2011, Haiku. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* SHINTA
|
||||
*/
|
||||
#ifndef IMAGE_TRACK_VIDEO_SUPPLIER_H
|
||||
#define IMAGE_TRACK_VIDEO_SUPPLIER_H
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <MediaFormats.h>
|
||||
|
||||
#include "VideoTrackSupplier.h"
|
||||
|
||||
|
||||
class ImageTrackVideoSupplier : public VideoTrackSupplier {
|
||||
public:
|
||||
ImageTrackVideoSupplier(BBitmap* bitmap,
|
||||
int32 trackIndex, status_t& initStatus);
|
||||
virtual ~ImageTrackVideoSupplier();
|
||||
|
||||
virtual const media_format& Format() const;
|
||||
virtual status_t GetEncodedFormat(media_format* format) const;
|
||||
virtual status_t GetCodecInfo(media_codec_info* info) const;
|
||||
|
||||
virtual status_t ReadFrame(void* buffer,
|
||||
bigtime_t* performanceTime,
|
||||
const media_raw_video_format& format,
|
||||
bool& wasCached);
|
||||
virtual status_t FindKeyFrameForFrame(int64* frame);
|
||||
virtual status_t SeekToTime(bigtime_t* performanceTime);
|
||||
virtual status_t SeekToFrame(int64* frame);
|
||||
|
||||
virtual bigtime_t Position() const
|
||||
{ return fPerformanceTime; }
|
||||
virtual bigtime_t Duration() const
|
||||
{ return fDuration; }
|
||||
virtual int64 CurrentFrame() const
|
||||
{ return fCurrentFrame; }
|
||||
|
||||
#if 0
|
||||
virtual BRect Bounds() const;
|
||||
virtual color_space ColorSpace() const;
|
||||
virtual uint32 BytesPerRow() const;
|
||||
#endif
|
||||
|
||||
virtual int32 TrackIndex() const
|
||||
{ return fTrackIndex; }
|
||||
|
||||
private:
|
||||
media_format fFormat;
|
||||
|
||||
bigtime_t fPerformanceTime;
|
||||
bigtime_t fDuration;
|
||||
int64 fCurrentFrame;
|
||||
|
||||
BBitmap* fBitmap;
|
||||
int32 fTrackIndex;
|
||||
};
|
||||
|
||||
|
||||
#endif // IMAGE_TRACK_VIDEO_SUPPLIER_H
|
@ -1,9 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010, Stephan Aßmus <superstippi@gmx.de>. All rights reserved.
|
||||
* Copyright 2010-2011, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* SHINTA
|
||||
*/
|
||||
|
||||
|
||||
#include "MediaFileTrackSupplier.h"
|
||||
|
||||
#include <new>
|
||||
@ -17,58 +19,29 @@
|
||||
|
||||
#include "MediaTrackAudioSupplier.h"
|
||||
#include "MediaTrackVideoSupplier.h"
|
||||
#include "ImageTrackVideoSupplier.h"
|
||||
|
||||
|
||||
MediaFileTrackSupplier::MediaFileTrackSupplier(BMediaFile* mediaFile)
|
||||
MediaFileTrackSupplier::MediaFileTrackSupplier()
|
||||
:
|
||||
TrackSupplier(),
|
||||
fMediaFile(mediaFile)
|
||||
TrackSupplier()
|
||||
{
|
||||
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;
|
||||
for (vector<BMediaFile*>::size_type i = fMediaFiles.size() - 1;
|
||||
static_cast<int32>(i) >= 0; i--) {
|
||||
delete fMediaFiles[i];
|
||||
// BMediaFile destructor will call ReleaseAllTracks()
|
||||
}
|
||||
|
||||
for (vector<BBitmap*>::size_type i = fBitmaps.size() - 1;
|
||||
static_cast<int32>(i) >= 0; i--) {
|
||||
delete fBitmaps[i];
|
||||
}
|
||||
|
||||
for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--)
|
||||
delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i));
|
||||
}
|
||||
@ -77,21 +50,30 @@ MediaFileTrackSupplier::~MediaFileTrackSupplier()
|
||||
status_t
|
||||
MediaFileTrackSupplier::InitCheck()
|
||||
{
|
||||
return fMediaFile->InitCheck();
|
||||
if (fMediaFiles.empty())
|
||||
return B_ERROR;
|
||||
|
||||
return fMediaFiles[0]->InitCheck();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetFileFormatInfo(media_file_format* fileFormat)
|
||||
{
|
||||
return fMediaFile->GetFileFormatInfo(fileFormat);
|
||||
if (fMediaFiles.empty())
|
||||
return B_ERROR;
|
||||
|
||||
return fMediaFiles[0]->GetFileFormatInfo(fileFormat);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetCopyright(BString* copyright)
|
||||
{
|
||||
*copyright = fMediaFile->Copyright();
|
||||
if (fMediaFiles.empty())
|
||||
return B_ERROR;
|
||||
|
||||
*copyright = fMediaFiles[0]->Copyright();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -99,7 +81,10 @@ MediaFileTrackSupplier::GetCopyright(BString* copyright)
|
||||
status_t
|
||||
MediaFileTrackSupplier::GetMetaData(BMessage* metaData)
|
||||
{
|
||||
return fMediaFile->GetMetaData(metaData);
|
||||
if (fMediaFiles.empty())
|
||||
return B_ERROR;
|
||||
|
||||
return fMediaFiles[0]->GetMetaData(metaData);
|
||||
}
|
||||
|
||||
|
||||
@ -113,7 +98,7 @@ MediaFileTrackSupplier::CountAudioTracks()
|
||||
int32
|
||||
MediaFileTrackSupplier::CountVideoTracks()
|
||||
{
|
||||
return fVideoTracks.CountItems();
|
||||
return fVideoTracks.CountItems() + fBitmaps.size();
|
||||
}
|
||||
|
||||
|
||||
@ -160,18 +145,26 @@ MediaFileTrackSupplier::CreateAudioTrackForIndex(int32 index)
|
||||
VideoTrackSupplier*
|
||||
MediaFileTrackSupplier::CreateVideoTrackForIndex(int32 index)
|
||||
{
|
||||
BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return NULL;
|
||||
|
||||
VideoTrackSupplier* supplier;
|
||||
status_t initStatus;
|
||||
MediaTrackVideoSupplier* supplier
|
||||
= new(std::nothrow) MediaTrackVideoSupplier(track, index, initStatus);
|
||||
|
||||
if (fVideoTracks.CountItems() <= index
|
||||
&& index < fVideoTracks.CountItems() + static_cast<int32>(fBitmaps.size())) {
|
||||
supplier = new(std::nothrow) ImageTrackVideoSupplier(
|
||||
fBitmaps[index - fVideoTracks.CountItems()], index, initStatus);
|
||||
} else {
|
||||
BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index);
|
||||
if (track == NULL)
|
||||
return NULL;
|
||||
|
||||
supplier = new(std::nothrow) MediaTrackVideoSupplier(track, index,
|
||||
initStatus);
|
||||
}
|
||||
|
||||
if (initStatus != B_OK) {
|
||||
delete supplier;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return supplier;
|
||||
}
|
||||
|
||||
@ -189,3 +182,62 @@ MediaFileTrackSupplier::AddSubTitles(SubTitles* subTitles)
|
||||
return fSubTitleTracks.AddItem(subTitles);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::AddMediaFile(BMediaFile* mediaFile)
|
||||
{
|
||||
if (mediaFile->InitCheck() != B_OK)
|
||||
return B_ERROR;
|
||||
int trackCount = mediaFile->CountTracks();
|
||||
if (trackCount <= 0)
|
||||
return B_ERROR;
|
||||
|
||||
status_t funcStatus = B_ERROR;
|
||||
for (int i = 0; i < trackCount; i++) {
|
||||
BMediaTrack* track = mediaFile->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));
|
||||
mediaFile->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)) {
|
||||
funcStatus = B_OK;
|
||||
} else {
|
||||
mediaFile->ReleaseTrack(track);
|
||||
}
|
||||
} else if (format.IsVideo()) {
|
||||
if (fVideoTracks.AddItem(track)) {
|
||||
funcStatus = B_OK;
|
||||
} else {
|
||||
mediaFile->ReleaseTrack(track);
|
||||
}
|
||||
} else {
|
||||
printf("MediaFileTrackSupplier: track index %d has unknown "
|
||||
"type\n", i);
|
||||
mediaFile->ReleaseTrack(track);
|
||||
}
|
||||
}
|
||||
if (funcStatus == B_OK)
|
||||
fMediaFiles.push_back(mediaFile);
|
||||
return funcStatus;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MediaFileTrackSupplier::AddBitmap(BBitmap* bitmap)
|
||||
{
|
||||
fBitmaps.push_back(bitmap);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,18 +5,21 @@
|
||||
#ifndef MEDIA_FILE_TRACK_SUPPLIER_H
|
||||
#define MEDIA_FILE_TRACK_SUPPLIER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <List.h>
|
||||
|
||||
#include "TrackSupplier.h"
|
||||
|
||||
|
||||
class BMediaFile;
|
||||
using std::vector;
|
||||
|
||||
|
||||
class MediaFileTrackSupplier : public TrackSupplier {
|
||||
public:
|
||||
MediaFileTrackSupplier(BMediaFile* mediaFile);
|
||||
MediaFileTrackSupplier();
|
||||
virtual ~MediaFileTrackSupplier();
|
||||
|
||||
virtual status_t InitCheck();
|
||||
@ -41,8 +44,13 @@ public:
|
||||
|
||||
bool AddSubTitles(SubTitles* subTitles);
|
||||
|
||||
status_t AddMediaFile(BMediaFile* mediaFile);
|
||||
|
||||
status_t AddBitmap(BBitmap* bitmap);
|
||||
|
||||
private:
|
||||
BMediaFile* fMediaFile;
|
||||
vector<BMediaFile*> fMediaFiles;
|
||||
vector<BBitmap*> fBitmaps;
|
||||
BList fAudioTracks;
|
||||
BList fVideoTracks;
|
||||
BList fSubTitleTracks;
|
||||
|
Loading…
Reference in New Issue
Block a user