Ticket #7430: mediaplayer_artwork.diff
File mediaplayer_artwork.diff, 26.2 KB (added by , 13 years ago) |
---|
-
playlist/Playlist.cpp
456 456 } else { 457 457 if (_IsQuery(type)) 458 458 AppendQueryToPlaylist(ref, &subPlaylist); 459 else 460 AppendToPlaylistRecursive(ref, &subPlaylist); 459 else { 460 if ( !ExtraMediaExists(this, ref) ) { 461 AppendToPlaylistRecursive(ref, &subPlaylist); 462 } 463 } 461 464 462 465 // At least sort this subsection of the playlist 463 466 // if the whole playlist is not sorted anymore. … … 510 513 BString mimeString = _MIMEString(&ref); 511 514 if (_IsMediaFile(mimeString)) { 512 515 PlaylistItem* item = new (std::nothrow) FilePlaylistItem(ref); 513 if (item != NULL && !playlist->AddItem(item)) 516 if (!ExtraMediaExists(playlist, ref)) { 517 _BindExtraMedia(item); 518 if (item != NULL && !playlist->AddItem(item)) 519 delete item; 520 } else 514 521 delete item; 515 522 } else 516 523 printf("MIME Type = %s\n", mimeString.String()); … … 584 591 } 585 592 586 593 594 /*static*/ bool 595 Playlist::ExtraMediaExists(Playlist* playlist, const entry_ref& ref) 596 { 597 BString exceptExtension = _GetExceptExtension(BPath(&ref).Path()); 598 599 for (int32 i = 0; i < playlist->CountItems(); i++) { 600 FilePlaylistItem* compare = dynamic_cast<FilePlaylistItem*>(playlist->ItemAt(i)); 601 if (compare == NULL) 602 continue; 603 if (compare->Ref() != ref 604 && _GetExceptExtension(BPath(&compare->Ref()).Path()) == exceptExtension ) 605 return true; 606 } 607 return false; 608 } 609 610 587 611 // #pragma mark - private 588 612 589 613 590 614 /*static*/ bool 615 Playlist::_IsImageFile(const BString& mimeString) 616 { 617 BMimeType superType; 618 BMimeType fileType(mimeString.String()); 619 620 if (fileType.GetSupertype(&superType) != B_OK) 621 return false; 622 623 if (superType == "image") 624 return true; 625 626 return false; 627 } 628 629 630 /*static*/ bool 591 631 Playlist::_IsMediaFile(const BString& mimeString) 592 632 { 593 633 BMimeType superType; … … 668 708 } 669 709 670 710 711 // _BindExtraMedia() searches additional videos and audios 712 // and addes them as extra medias. 713 /*static*/ void 714 Playlist::_BindExtraMedia(PlaylistItem* item) 715 { 716 FilePlaylistItem* fileItem = dynamic_cast<FilePlaylistItem*>(item); 717 if (!item) 718 return; 719 720 // If the media file is foo.mp3, _BindExtraMedia() searches foo.avi. 721 BPath mediaFilePath(&fileItem->Ref()); 722 BString mediaFilePathString = mediaFilePath.Path(); 723 BPath dirPath; 724 mediaFilePath.GetParent(&dirPath); 725 BDirectory dir(dirPath.Path()); 726 if (dir.InitCheck() != B_OK) 727 return; 728 729 BEntry entry; 730 BString entryPathString; 731 while (dir.GetNextEntry(&entry, true) == B_OK) { 732 if (!entry.IsFile()) 733 continue; 734 entryPathString = BPath(&entry).Path(); 735 if (entryPathString != mediaFilePathString 736 && _GetExceptExtension(entryPathString) == _GetExceptExtension(mediaFilePathString)) { 737 _BindExtraMedia(fileItem, entry); 738 } 739 } 740 } 741 742 743 /*static*/ void 744 Playlist::_BindExtraMedia(FilePlaylistItem* fileItem, const BEntry& entry) 745 { 746 entry_ref ref; 747 entry.GetRef(&ref); 748 BString mimeString = _MIMEString(&ref); 749 if (_IsMediaFile(mimeString)) { 750 fileItem->AddRef(ref); 751 } else if (_IsImageFile(mimeString)) { 752 fileItem->AddImageRef(ref); 753 } 754 } 755 756 757 /*static*/ BString 758 Playlist::_GetExceptExtension(const BString& path) 759 { 760 int32 periodPos = path.FindLast('.'); 761 if (periodPos <= path.FindLast('/')) 762 return path; 763 return BString(path.String(), periodPos); 764 } 765 766 671 767 // #pragma mark - notifications 672 768 673 769 -
playlist/Playlist.h
25 25 #include <List.h> 26 26 #include <Locker.h> 27 27 28 #include "FilePlaylistItem.h" 28 29 #include "PlaylistItem.h" 29 30 30 31 class BDataIO; … … 113 114 114 115 void NotifyImportFailed(); 115 116 117 static bool ExtraMediaExists(Playlist* playlist, const entry_ref& ref); 118 116 119 private: 117 120 Playlist(const Playlist& other); 118 121 Playlist& operator=(const Playlist& other); 119 122 // unimplemented 120 123 124 static bool _IsImageFile(const BString& mimeString); 121 125 static bool _IsMediaFile(const BString& mimeString); 122 126 static bool _IsTextPlaylist(const BString& mimeString); 123 127 static bool _IsBinaryPlaylist(const BString& mimeString); 124 128 static bool _IsPlaylist(const BString& mimeString); 125 129 static bool _IsQuery(const BString& mimeString); 126 130 static BString _MIMEString(const entry_ref* ref); 131 static void _BindExtraMedia(PlaylistItem* item); 132 static void _BindExtraMedia(FilePlaylistItem* fileItem, const BEntry& entry); 133 static BString _GetExceptExtension(const BString& path); 127 134 128 135 void _NotifyItemAdded(PlaylistItem*, 129 136 int32 index) const; -
playlist/ImportPLItemsCommand.cpp
57 57 memset(fNewItems, 0, fNewCount * sizeof(PlaylistItem*)); 58 58 59 59 // init new entries 60 int32 added = 0; 60 61 for (int32 i = 0; i < fNewCount; i++) { 61 fNewItems[i] = temp.ItemAtFast(i)->Clone(); 62 if (fNewItems[i] == NULL) { 63 // indicate bad object init 64 _CleanUp(fNewItems, fNewCount, true); 65 return; 62 FilePlaylistItem* fileItem = dynamic_cast<FilePlaylistItem*>(temp.ItemAtFast(i)); 63 if (fileItem && !Playlist::ExtraMediaExists(playlist, fileItem->Ref())) { 64 fNewItems[added] = temp.ItemAtFast(i)->Clone(); 65 if (fNewItems[added] == NULL) { 66 // indicate bad object init 67 _CleanUp(fNewItems, fNewCount, true); 68 return; 69 } 70 added++; 66 71 } 67 72 } 73 fNewCount = added; 68 74 69 75 fPlaylingIndex = fPlaylist->CurrentItemIndex(); 70 76 -
playlist/FilePlaylistItem.cpp
14 14 #include <FindDirectory.h> 15 15 #include <MediaFile.h> 16 16 #include <Path.h> 17 #include <TranslationUtils.h> 17 18 18 19 #include "MediaFileTrackSupplier.h" 19 20 #include "SubTitlesSRT.h" 20 21 21 22 22 static const char* kPathKey = "path"; 23 23 24 25 24 FilePlaylistItem::FilePlaylistItem(const entry_ref& ref) 26 :27 fRef(ref),28 fNameInTrash("")29 25 { 26 fRefs.push_back(ref); 27 fNamesInTrash.push_back(""); 30 28 } 31 29 32 30 33 31 FilePlaylistItem::FilePlaylistItem(const FilePlaylistItem& other) 34 32 : 35 fRef(other.fRef), 36 fNameInTrash(other.fNameInTrash) 33 fRefs(other.fRefs), 34 fNamesInTrash(other.fNamesInTrash), 35 fImageRefs(other.fImageRefs), 36 fImageNamesInTrash(other.fImageNamesInTrash) 37 37 { 38 38 } 39 39 40 40 41 41 FilePlaylistItem::FilePlaylistItem(const BMessage* archive) 42 :43 fRef(),44 fNameInTrash("")45 42 { 46 43 const char* path; 47 if (archive != NULL && archive->FindString(kPathKey, &path) == B_OK) { 48 if (get_ref_for_path(path, &fRef) != B_OK) 49 fRef = entry_ref(); 44 entry_ref ref; 45 if (archive != NULL) { 46 int32 i = 0; 47 while (archive->FindString(kPathKey, i, &path) == B_OK) { 48 if (get_ref_for_path(path, &ref) == B_OK) { 49 fRefs.push_back(ref); 50 } 51 i++; 52 } 50 53 } 54 if (fRefs.empty()) { 55 fRefs.push_back(entry_ref()); 56 } 57 for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) { 58 fNamesInTrash.push_back(""); 59 } 51 60 } 52 61 53 62 … … 82 91 status_t ret = BArchivable::Archive(into, deep); 83 92 if (ret != B_OK) 84 93 return ret; 85 BPath path(&fRef); 86 ret = path.InitCheck(); 87 if (ret == B_OK) 94 for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) { 95 BPath path(&fRefs[i]); 96 ret = path.InitCheck(); 97 if (ret != B_OK) 98 return ret; 88 99 ret = into->AddString(kPathKey, path.Path()); 89 return ret; 100 if (ret != B_OK) 101 return ret; 102 } 103 return B_OK; 90 104 } 91 105 92 106 … … 97 111 switch (attribute) { 98 112 case ATTR_STRING_NAME: 99 113 { 100 BEntry entry(&fRef , false);114 BEntry entry(&fRefs[0], false); 101 115 return entry.Rename(string.String(), false); 102 116 } 103 117 … … 135 149 BString& string) const 136 150 { 137 151 if (attribute == ATTR_STRING_NAME) { 138 string = fRef .name;152 string = fRefs[0].name; 139 153 return B_OK; 140 154 } 141 155 … … 194 208 BString 195 209 FilePlaylistItem::LocationURI() const 196 210 { 197 BPath path(&fRef );211 BPath path(&fRefs[0]); 198 212 BString locationURI("file://"); 199 213 locationURI << path.Path(); 200 214 return locationURI; … … 204 218 status_t 205 219 FilePlaylistItem::GetIcon(BBitmap* bitmap, icon_size iconSize) const 206 220 { 207 BNode node(&fRef );221 BNode node(&fRefs[0]); 208 222 BNodeInfo info(&node); 209 223 return info.GetTrackerIcon(bitmap, iconSize); 210 224 } … … 213 227 status_t 214 228 FilePlaylistItem::MoveIntoTrash() 215 229 { 216 if (fName InTrash.Length() != 0) {230 if (fNamesInTrash[0].Length() != 0) { 217 231 // Already in the trash! 218 232 return B_ERROR; 219 233 } 220 234 221 char trashPath[B_PATH_NAME_LENGTH]; 222 status_t err = find_directory(B_TRASH_DIRECTORY, fRef.device, 223 true /*create it*/, trashPath, B_PATH_NAME_LENGTH); 224 if (err != B_OK) { 225 fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); 235 status_t err; 236 err = _MoveIntoTrash(&fRefs, &fNamesInTrash); 237 if (err != B_OK) 226 238 return err; 227 } 239 240 if (fImageRefs.empty()) 241 return B_OK; 228 242 229 BEntry entry(&fRef); 230 err = entry.InitCheck(); 231 if (err != B_OK) { 232 fprintf(stderr, "failed to init BEntry for %s: %s\n", 233 fRef.name, strerror(err)); 243 err = _MoveIntoTrash(&fImageRefs, &fImageNamesInTrash); 244 if (err != B_OK) 234 245 return err; 235 }236 BDirectory trashDir(trashPath);237 if (err != B_OK) {238 fprintf(stderr, "failed to init BDirectory for %s: %s\n",239 trashPath, strerror(err));240 return err;241 }242 246 243 // Find a unique name for the entry in the trash 244 fNameInTrash = fRef.name; 245 int32 uniqueNameIndex = 1; 246 while (true) { 247 BEntry test(&trashDir, fNameInTrash.String()); 248 if (!test.Exists()) 249 break; 250 fNameInTrash = fRef.name; 251 fNameInTrash << ' ' << uniqueNameIndex; 252 uniqueNameIndex++; 253 } 254 255 // Remember the original path 256 BPath originalPath; 257 entry.GetPath(&originalPath); 258 259 // Finally, move the entry into the trash 260 err = entry.MoveTo(&trashDir, fNameInTrash.String()); 261 if (err != B_OK) { 262 fprintf(stderr, "failed to move entry into trash %s: %s\n", 263 trashPath, strerror(err)); 264 return err; 265 } 266 267 // Allow Tracker to restore this entry 268 BNode node(&entry); 269 BString originalPathString(originalPath.Path()); 270 node.WriteAttrString("_trk/original_path", &originalPathString); 271 272 return err; 247 return B_OK; 273 248 } 274 249 275 250 276 277 251 status_t 278 252 FilePlaylistItem::RestoreFromTrash() 279 253 { 280 if (fName InTrash.Length() <= 0) {254 if (fNamesInTrash[0].Length() <= 0) { 281 255 // Not in the trash! 282 256 return B_ERROR; 283 257 } 284 258 285 char trashPath[B_PATH_NAME_LENGTH]; 286 status_t err = find_directory(B_TRASH_DIRECTORY, fRef.device, 287 false /*create it*/, trashPath, B_PATH_NAME_LENGTH); 288 if (err != B_OK) { 289 fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); 259 status_t err; 260 err = _RestoreFromTrash(&fRefs, &fNamesInTrash); 261 if (err != B_OK) 290 262 return err; 291 } 292 // construct the entry to the file in the trash 293 // TODO: BEntry(const BDirectory* directory, const char* path) is broken! 294 // BEntry entry(trashPath, fNamesInTrash[i].String()); 295 BPath path(trashPath, fNameInTrash.String()); 296 BEntry entry(path.Path()); 297 err = entry.InitCheck(); 298 if (err != B_OK) { 299 fprintf(stderr, "failed to init BEntry for %s: %s\n", 300 fNameInTrash.String(), strerror(err)); 301 return err; 302 } 303 //entry.GetPath(&path); 304 //printf("moving '%s'\n", path.Path()); 263 264 if (fImageRefs.empty()) 265 return B_OK; 305 266 306 // construct the folder of the original entry_ref 307 node_ref nodeRef; 308 nodeRef.device = fRef.device; 309 nodeRef.node = fRef.directory; 310 BDirectory originalDir(&nodeRef); 311 err = originalDir.InitCheck(); 312 if (err != B_OK) { 313 fprintf(stderr, "failed to init original BDirectory for " 314 "%s: %s\n", fRef.name, strerror(err)); 267 err = _RestoreFromTrash(&fImageRefs, &fImageNamesInTrash); 268 if (err != B_OK) 315 269 return err; 316 }317 270 318 //path.SetTo(&originalDir, fItems[i].name); 319 //printf("as '%s'\n", path.Path()); 320 321 // Reset the name here, the user may have already moved the entry 322 // out of the trash via Tracker for example. 323 fNameInTrash = ""; 324 325 // Finally, move the entry back into the original folder 326 err = entry.MoveTo(&originalDir, fRef.name); 327 if (err != B_OK) { 328 fprintf(stderr, "failed to restore entry from trash " 329 "%s: %s\n", fRef.name, strerror(err)); 330 return err; 331 } 332 333 // Remove the attribute that helps Tracker restore the entry. 334 BNode node(&entry); 335 node.RemoveAttr("_trk/original_path"); 336 337 return err; 271 return B_OK; 338 272 } 339 273 340 274 341 275 // #pragma mark - 342 276 343 344 277 TrackSupplier* 345 278 FilePlaylistItem::CreateTrackSupplier() const 346 279 { 347 BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRef);348 if (mediaFile == NULL)349 return NULL;350 280 MediaFileTrackSupplier* supplier 351 = new(std::nothrow) MediaFileTrackSupplier(mediaFile); 352 if (supplier == NULL) { 353 delete mediaFile; 281 = new(std::nothrow) MediaFileTrackSupplier(); 282 if (supplier == NULL) 354 283 return NULL; 284 285 for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) { 286 BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRefs[i]); 287 if (mediaFile == NULL) { 288 delete supplier; 289 return NULL; 290 } 291 if (supplier->AddMediaFile(mediaFile) != B_OK) 292 delete mediaFile; 355 293 } 356 294 295 for (vector<entry_ref>::size_type i = 0; i < fImageRefs.size(); i++) { 296 BBitmap* bitmap = BTranslationUtils::GetBitmap(&fImageRefs[i]); 297 if (bitmap == NULL) 298 continue; 299 if (supplier->AddBitmap(bitmap) != B_OK) 300 delete bitmap; 301 } 302 357 303 // Search for subtitle files in the same folder 358 304 // TODO: Error checking 359 BEntry entry(&fRef , true);305 BEntry entry(&fRefs[0], true); 360 306 361 307 char originalName[B_FILE_NAME_LENGTH]; 362 308 entry.GetName(originalName); … … 411 357 412 358 413 359 status_t 360 FilePlaylistItem::AddRef(const entry_ref& ref) 361 { 362 fRefs.push_back(ref); 363 fNamesInTrash.push_back(""); 364 return B_OK; 365 } 366 367 368 status_t 369 FilePlaylistItem::AddImageRef(const entry_ref& ref) 370 { 371 fImageRefs.push_back(ref); 372 fImageNamesInTrash.push_back(""); 373 return B_OK; 374 } 375 376 377 const entry_ref& 378 FilePlaylistItem::ImageRef() const 379 { 380 static entry_ref ref; 381 382 if (fImageRefs.empty()) 383 return ref; 384 385 return fImageRefs[0]; 386 } 387 388 389 status_t 414 390 FilePlaylistItem::_SetAttribute(const char* attrName, type_code type, 415 391 const void* data, size_t size) 416 392 { 417 BEntry entry(&fRef , true);393 BEntry entry(&fRefs[0], true); 418 394 BNode node(&entry); 419 395 if (node.InitCheck() != B_OK) 420 396 return node.InitCheck(); … … 433 409 FilePlaylistItem::_GetAttribute(const char* attrName, type_code type, 434 410 void* data, size_t size) 435 411 { 436 BEntry entry(&fRef , true);412 BEntry entry(&fRefs[0], true); 437 413 BNode node(&entry); 438 414 if (node.InitCheck() != B_OK) 439 415 return node.InitCheck(); … … 447 423 return B_OK; 448 424 } 449 425 426 427 status_t 428 FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs, 429 vector<BString>* namesInTrash) 430 { 431 char trashPath[B_PATH_NAME_LENGTH]; 432 status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device, 433 true /*create it*/, trashPath, B_PATH_NAME_LENGTH); 434 if (err != B_OK) { 435 fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); 436 return err; 437 } 438 439 BDirectory trashDir(trashPath); 440 if (err != B_OK) { 441 fprintf(stderr, "failed to init BDirectory for %s: %s\n", 442 trashPath, strerror(err)); 443 return err; 444 } 445 446 for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) { 447 BEntry entry(&(*refs)[i]); 448 err = entry.InitCheck(); 449 if (err != B_OK) { 450 fprintf(stderr, "failed to init BEntry for %s: %s\n", 451 (*refs)[i].name, strerror(err)); 452 return err; 453 } 454 455 // Find a unique name for the entry in the trash 456 (*namesInTrash)[i] = (*refs)[i].name; 457 int32 uniqueNameIndex = 1; 458 while (true) { 459 BEntry test(&trashDir, (*namesInTrash)[i].String()); 460 if (!test.Exists()) 461 break; 462 (*namesInTrash)[i] = (*refs)[i].name; 463 (*namesInTrash)[i] << ' ' << uniqueNameIndex; 464 uniqueNameIndex++; 465 } 466 467 // Remember the original path 468 BPath originalPath; 469 entry.GetPath(&originalPath); 470 471 // Finally, move the entry into the trash 472 err = entry.MoveTo(&trashDir, (*namesInTrash)[i].String()); 473 if (err != B_OK) { 474 fprintf(stderr, "failed to move entry into trash %s: %s\n", 475 trashPath, strerror(err)); 476 return err; 477 } 478 479 // Allow Tracker to restore this entry 480 BNode node(&entry); 481 BString originalPathString(originalPath.Path()); 482 node.WriteAttrString("_trk/original_path", &originalPathString); 483 } 484 485 return B_OK; 486 } 487 488 489 status_t 490 FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs, 491 vector<BString>* namesInTrash) 492 { 493 char trashPath[B_PATH_NAME_LENGTH]; 494 status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device, 495 false /*create it*/, trashPath, B_PATH_NAME_LENGTH); 496 if (err != B_OK) { 497 fprintf(stderr, "failed to find Trash: %s\n", strerror(err)); 498 return err; 499 } 500 501 for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) { 502 // construct the entry to the file in the trash 503 // TODO: BEntry(const BDirectory* directory, const char* path) is broken! 504 // BEntry entry(trashPath, (*namesInTrash)[i].String()); 505 BPath path(trashPath, (*namesInTrash)[i].String()); 506 BEntry entry(path.Path()); 507 err = entry.InitCheck(); 508 if (err != B_OK) { 509 fprintf(stderr, "failed to init BEntry for %s: %s\n", 510 (*namesInTrash)[i].String(), strerror(err)); 511 return err; 512 } 513 //entry.GetPath(&path); 514 //printf("moving '%s'\n", path.Path()); 515 516 // construct the folder of the original entry_ref 517 node_ref nodeRef; 518 nodeRef.device = (*refs)[i].device; 519 nodeRef.node = (*refs)[i].directory; 520 BDirectory originalDir(&nodeRef); 521 err = originalDir.InitCheck(); 522 if (err != B_OK) { 523 fprintf(stderr, "failed to init original BDirectory for " 524 "%s: %s\n", (*refs)[i].name, strerror(err)); 525 return err; 526 } 527 528 //path.SetTo(&originalDir, fItems[i].name); 529 //printf("as '%s'\n", path.Path()); 530 531 // Reset the name here, the user may have already moved the entry 532 // out of the trash via Tracker for example. 533 (*namesInTrash)[i] = ""; 534 535 // Finally, move the entry back into the original folder 536 err = entry.MoveTo(&originalDir, (*refs)[i].name); 537 if (err != B_OK) { 538 fprintf(stderr, "failed to restore entry from trash " 539 "%s: %s\n", (*refs)[i].name, strerror(err)); 540 return err; 541 } 542 543 // Remove the attribute that helps Tracker restore the entry. 544 BNode node(&entry); 545 node.RemoveAttr("_trk/original_path"); 546 } 547 548 return B_OK; 549 } 550 -
playlist/FilePlaylistItem.h
9 9 10 10 #include <Entry.h> 11 11 12 #include <vector> 13 12 14 class FilePlaylistItem : public PlaylistItem { 13 15 public: 14 16 FilePlaylistItem(const entry_ref& ref); … … 50 52 // playback 51 53 virtual TrackSupplier* CreateTrackSupplier() const; 52 54 53 const entry_ref& Ref() const { return fRef; } 55 status_t AddRef(const entry_ref& ref); 56 const entry_ref& Ref() const { return fRefs[0]; } 54 57 58 status_t AddImageRef(const entry_ref& ref); 59 const entry_ref& ImageRef() const; 60 55 61 private: 56 62 status_t _SetAttribute(const char* attrName, 57 63 type_code type, const void* data, … … 59 65 status_t _GetAttribute(const char* attrName, 60 66 type_code type, void* data, 61 67 size_t size); 68 status_t _MoveIntoTrash(vector<entry_ref>* refs, 69 vector<BString>* namesInTrash); 70 status_t _RestoreFromTrash(vector<entry_ref>* refs, 71 vector<BString>* namesInTrash); 62 72 63 73 private: 64 entry_ref fRef; 65 BString fNameInTrash; 74 // always fRefs.size() == fNamesInTrash.size() 75 vector<entry_ref> fRefs; 76 vector<BString> fNamesInTrash; 77 // always fImageRefs.size() == fImageNamesInTrash.size() 78 vector<entry_ref> fImageRefs; 79 vector<BString> fImageNamesInTrash; 66 80 }; 67 81 68 82 #endif // FILE_PLAYLIST_ITEM_H -
supplier/MediaFileTrackSupplier.cpp
17 17 18 18 #include "MediaTrackAudioSupplier.h" 19 19 #include "MediaTrackVideoSupplier.h" 20 #include "ImageTrackVideoSupplier.h" 20 21 21 22 22 MediaFileTrackSupplier::MediaFileTrackSupplier( BMediaFile* mediaFile)23 MediaFileTrackSupplier::MediaFileTrackSupplier() 23 24 : 24 TrackSupplier(), 25 fMediaFile(mediaFile) 25 TrackSupplier() 26 26 { 27 if (fMediaFile->InitCheck() != B_OK)28 return;29 int trackCount = fMediaFile->CountTracks();30 if (trackCount <= 0)31 return;32 33 for (int i = 0; i < trackCount; i++) {34 BMediaTrack* track = fMediaFile->TrackAt(i);35 media_format format;36 status_t status = track->EncodedFormat(&format);37 if (status != B_OK) {38 fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for "39 "track index %d, error: %s\n", i, strerror(status));40 fMediaFile->ReleaseTrack(track);41 continue;42 }43 44 if (track->Duration() <= 0) {45 fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "46 "has no duration\n", i);47 }48 49 if (format.IsAudio()) {50 if (!fAudioTracks.AddItem(track)) {51 fMediaFile->ReleaseTrack(track);52 return;53 }54 } else if (format.IsVideo()) {55 if (!fVideoTracks.AddItem(track)) {56 fMediaFile->ReleaseTrack(track);57 return;58 }59 } else {60 printf("MediaFileTrackSupplier: track index %d has unknown "61 "type\n", i);62 fMediaFile->ReleaseTrack(track);63 }64 }65 27 } 66 28 67 29 68 30 MediaFileTrackSupplier::~MediaFileTrackSupplier() 69 31 { 70 delete fMediaFile; 32 for (vector<BMediaFile*>::size_type i = fMediaFiles.size() - 1; static_cast<int32>(i) >= 0; i--) 33 delete fMediaFiles[i]; 71 34 // BMediaFile destructor will call ReleaseAllTracks() 35 for (vector<BBitmap*>::size_type i = fBitmaps.size() - 1; static_cast<int32>(i) >= 0; i--) 36 delete fBitmaps[i]; 72 37 for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--) 73 38 delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i)); 74 39 } … … 77 42 status_t 78 43 MediaFileTrackSupplier::InitCheck() 79 44 { 80 return fMediaFile->InitCheck(); 45 if (fMediaFiles.empty()) 46 return B_ERROR; 47 48 return fMediaFiles[0]->InitCheck(); 81 49 } 82 50 83 51 84 52 status_t 85 53 MediaFileTrackSupplier::GetFileFormatInfo(media_file_format* fileFormat) 86 54 { 87 return fMediaFile->GetFileFormatInfo(fileFormat); 55 if (fMediaFiles.empty()) 56 return B_ERROR; 57 58 return fMediaFiles[0]->GetFileFormatInfo(fileFormat); 88 59 } 89 60 90 61 91 62 status_t 92 63 MediaFileTrackSupplier::GetCopyright(BString* copyright) 93 64 { 94 *copyright = fMediaFile->Copyright(); 65 if (fMediaFiles.empty()) 66 return B_ERROR; 67 68 *copyright = fMediaFiles[0]->Copyright(); 95 69 return B_OK; 96 70 } 97 71 … … 99 73 status_t 100 74 MediaFileTrackSupplier::GetMetaData(BMessage* metaData) 101 75 { 102 return fMediaFile->GetMetaData(metaData); 76 if (fMediaFiles.empty()) 77 return B_ERROR; 78 79 return fMediaFiles[0]->GetMetaData(metaData); 103 80 } 104 81 105 82 … … 113 90 int32 114 91 MediaFileTrackSupplier::CountVideoTracks() 115 92 { 116 return fVideoTracks.CountItems() ;93 return fVideoTracks.CountItems() + fBitmaps.size(); 117 94 } 118 95 119 96 … … 160 137 VideoTrackSupplier* 161 138 MediaFileTrackSupplier::CreateVideoTrackForIndex(int32 index) 162 139 { 163 BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index); 164 if (track == NULL) 165 return NULL; 140 VideoTrackSupplier* supplier; 141 status_t initStatus; 166 142 167 status_t initStatus; 168 MediaTrackVideoSupplier* supplier 169 = new(std::nothrow) MediaTrackVideoSupplier(track, index, initStatus); 143 if (fVideoTracks.CountItems() <= index 144 && index < fVideoTracks.CountItems() + static_cast<int32>(fBitmaps.size())) { 145 supplier = new(std::nothrow) ImageTrackVideoSupplier(fBitmaps[index-fVideoTracks.CountItems()], index, initStatus); 146 } else { 147 BMediaTrack* track = (BMediaTrack*)fVideoTracks.ItemAt(index); 148 if (track == NULL) 149 return NULL; 150 151 supplier = new(std::nothrow) MediaTrackVideoSupplier(track, index, initStatus); 152 } 153 170 154 if (initStatus != B_OK) { 171 155 delete supplier; 172 156 return NULL; 173 157 } 174 175 158 return supplier; 176 159 } 177 160 … … 189 172 return fSubTitleTracks.AddItem(subTitles); 190 173 } 191 174 175 176 status_t 177 MediaFileTrackSupplier::AddMediaFile(BMediaFile* mediaFile) 178 { 179 if (mediaFile->InitCheck() != B_OK) 180 return B_ERROR; 181 int trackCount = mediaFile->CountTracks(); 182 if (trackCount <= 0) 183 return B_ERROR; 184 185 status_t funcStatus = B_ERROR; 186 for (int i = 0; i < trackCount; i++) { 187 BMediaTrack* track = mediaFile->TrackAt(i); 188 media_format format; 189 status_t status = track->EncodedFormat(&format); 190 if (status != B_OK) { 191 fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for " 192 "track index %d, error: %s\n", i, strerror(status)); 193 mediaFile->ReleaseTrack(track); 194 continue; 195 } 196 197 if (track->Duration() <= 0) { 198 fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d " 199 "has no duration\n", i); 200 } 201 202 if (format.IsAudio()) { 203 if (fAudioTracks.AddItem(track)) { 204 funcStatus = B_OK; 205 } else { 206 mediaFile->ReleaseTrack(track); 207 } 208 } else if (format.IsVideo()) { 209 if (fVideoTracks.AddItem(track)) { 210 funcStatus = B_OK; 211 } else { 212 mediaFile->ReleaseTrack(track); 213 } 214 } else { 215 printf("MediaFileTrackSupplier: track index %d has unknown " 216 "type\n", i); 217 mediaFile->ReleaseTrack(track); 218 } 219 } 220 if (funcStatus == B_OK) 221 fMediaFiles.push_back(mediaFile); 222 return funcStatus; 223 } 224 225 226 status_t 227 MediaFileTrackSupplier::AddBitmap(BBitmap* bitmap) 228 { 229 fBitmaps.push_back(bitmap); 230 return B_OK; 231 } 232 233 -
supplier/MediaFileTrackSupplier.h
6 6 #define MEDIA_FILE_TRACK_SUPPLIER_H 7 7 8 8 9 #include <Bitmap.h> 9 10 #include <List.h> 10 11 11 12 #include "TrackSupplier.h" 12 13 14 #include <vector> 13 15 14 16 class BMediaFile; 15 17 16 18 17 19 class MediaFileTrackSupplier : public TrackSupplier { 18 20 public: 19 MediaFileTrackSupplier( BMediaFile* mediaFile);21 MediaFileTrackSupplier(); 20 22 virtual ~MediaFileTrackSupplier(); 21 23 22 24 virtual status_t InitCheck(); … … 41 43 42 44 bool AddSubTitles(SubTitles* subTitles); 43 45 46 status_t AddMediaFile(BMediaFile* mediaFile); 47 48 status_t AddBitmap(BBitmap* bitmap); 49 44 50 private: 45 BMediaFile* fMediaFile; 51 vector<BMediaFile*> fMediaFiles; 52 vector<BBitmap*> fBitmaps; 46 53 BList fAudioTracks; 47 54 BList fVideoTracks; 48 55 BList fSubTitleTracks; -
Jamfile
77 77 78 78 # supplier 79 79 AudioTrackSupplier.cpp 80 ImageTrackVideoSupplier.cpp 80 81 MediaFileTrackSupplier.cpp 81 82 MediaTrackAudioSupplier.cpp 82 83 MediaTrackVideoSupplier.cpp