Author: phoudoin Date: 2011-04-20 19:58:07 +0200 (Wed, 20 Apr 2011) New Revision: 41271 Changeset: https://dev.haiku-os.org/changeset/41271 Ticket: https://dev.haiku-os.org/ticket/7430 Added: haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h Modified: haiku/trunk/src/apps/mediaplayer/Jamfile haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.h haiku/trunk/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp haiku/trunk/src/apps/mediaplayer/playlist/Playlist.cpp haiku/trunk/src/apps/mediaplayer/playlist/Playlist.h haiku/trunk/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp haiku/trunk/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.h Log: Patch by SHINTA: add MediaPlayer cover image/artwork support. This implemented #7430 enhancement. Arigato gozaimasu! Modified: haiku/trunk/src/apps/mediaplayer/Jamfile =================================================================== --- haiku/trunk/src/apps/mediaplayer/Jamfile 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/Jamfile 2011-04-20 17:58:07 UTC (rev 41271) @@ -77,6 +77,7 @@ # supplier AudioTrackSupplier.cpp + ImageTrackVideoSupplier.cpp MediaFileTrackSupplier.cpp MediaTrackAudioSupplier.cpp MediaTrackVideoSupplier.cpp Modified: haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp 2011-04-20 17:58:07 UTC (rev 41271) @@ -14,40 +14,49 @@ #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 @@ 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 @@ 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 @@ BString& string) const { if (attribute == ATTR_STRING_NAME) { - string = fRef.name; + string = fRefs[0].name; return B_OK; } @@ -194,7 +208,7 @@ BString FilePlaylistItem::LocationURI() const { - BPath path(&fRef); + BPath path(&fRefs[0]); BString locationURI("file://"); locationURI << path.Path(); return locationURI; @@ -204,7 +218,7 @@ 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 @@ 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)); - return err; - } -//entry.GetPath(&path); -//printf("moving '%s'\n", path.Path()); + + if (fImageRefs.empty()) + return B_OK; - // 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)); + err = _RestoreFromTrash(&fImageRefs, &fImageNamesInTrash); + if (err != B_OK) 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); @@ -411,10 +357,40 @@ 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 @@ 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 @@ 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; +} + Modified: haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.h 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/playlist/FilePlaylistItem.h 2011-04-20 17:58:07 UTC (rev 41271) @@ -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,8 +55,12 @@ // 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, type_code type, const void* data, @@ -59,10 +68,18 @@ 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 Modified: haiku/trunk/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/playlist/ImportPLItemsCommand.cpp 2011-04-20 17:58:07 UTC (rev 41271) @@ -57,14 +57,20 @@ 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(); Modified: haiku/trunk/src/apps/mediaplayer/playlist/Playlist.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/playlist/Playlist.cpp 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/playlist/Playlist.cpp 2011-04-20 17:58:07 UTC (rev 41271) @@ -456,8 +456,11 @@ } 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 @@ 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,10 +591,43 @@ } +/*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) { BMimeType superType; @@ -668,6 +708,62 @@ } +// _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 Modified: haiku/trunk/src/apps/mediaplayer/playlist/Playlist.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/playlist/Playlist.h 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/playlist/Playlist.h 2011-04-20 17:58:07 UTC (rev 41271) @@ -25,6 +25,7 @@ #include <List.h> #include <Locker.h> +#include "FilePlaylistItem.h" #include "PlaylistItem.h" class BDataIO; @@ -113,17 +114,23 @@ 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; Added: haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp (rev 0) +++ haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.cpp 2011-04-20 17:58:07 UTC (rev 41271) @@ -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; +} + + Added: haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h =================================================================== --- haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h (rev 0) +++ haiku/trunk/src/apps/mediaplayer/supplier/ImageTrackVideoSupplier.h 2011-04-20 17:58:07 UTC (rev 41271) @@ -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 Modified: haiku/trunk/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp =================================================================== --- haiku/trunk/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp 2011-04-19 21:25:00 UTC (rev 41270) +++ haiku/trunk/src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp 2011-04-20 17:58:07 UTC (rev 41271) @@ -1,9 +1,11 @@ /* - * Copyright 2010, Stephan Aßmus <superstippi@xxxxxx>. All rights reserved. + * Copyright 2010-2011, Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus <superstippi@xxxxxx> + * 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; [... truncated: 249 lines follow ...]