Ticket #7416: mediaplayer.diff

File mediaplayer.diff, 7.8 KB (added by shinta, 9 years ago)

This is the patch to add Extra Media Binding Feature to MediaPlayer

  • src/apps/mediaplayer/Controller.cpp

     
    3030#include <Autolock.h>
    3131#include <Bitmap.h>
    3232#include <Debug.h>
     33#include <Directory.h>
     34#include <MediaFile.h>
    3335#include <Path.h>
    3436#include <Window.h> // for debugging only
    3537
    3638#include "AutoDeleter.h"
    3739#include "ControllerView.h"
     40#include "FilePlaylistItem.h"
    3841#include "MainApp.h"
    3942#include "PlaybackState.h"
    4043#include "Settings.h"
     
    4245
    4346// suppliers
    4447#include "AudioTrackSupplier.h"
     48#include "MediaFileTrackSupplier.h"
    4549#include "MediaTrackAudioSupplier.h"
    4650#include "MediaTrackVideoSupplier.h"
    4751#include "ProxyAudioSupplier.h"
     
    288292
    289293    fTrackSupplier = trackSupplier;
    290294
     295    _BindExtraMedia();
     296
    291297    SelectAudioTrack(0);
    292298    SelectVideoTrack(0);
    293299
     
    11791185}
    11801186
    11811187
     1188// If fTrackSupplier has only either audio or video, _BindExtraMedia() searches
     1189// alternative video or audio and addes it to fTrackSupplier as a extra media.
    11821190void
     1191Controller::_BindExtraMedia()
     1192{
     1193    // If fTrackSupplier has already had both audio and video, there is no need
     1194    // to search alternative media.
     1195    if ( fTrackSupplier->CountAudioTracks() == 0 && fTrackSupplier->CountVideoTracks() == 0
     1196            || fTrackSupplier->CountAudioTracks() > 0 && fTrackSupplier->CountVideoTracks() > 0 )
     1197            return;
     1198
     1199    // Currently, _BindExtraMedia() searches alternative media only from files.
     1200    FilePlaylistItem*   fileItem = dynamic_cast<FilePlaylistItem*>(fItem.Get());
     1201    if ( fileItem == NULL )
     1202        return;
     1203
     1204    // For example, if the media file is foo.mp3, _BindExtraMedia() searches foo.avi
     1205    // and addes video track of foo.avi as a extra media.
     1206    BPath   mediaFilePath(&fileItem->Ref());
     1207    BString mediaFilePathString = mediaFilePath.Path();
     1208    BPath   dirPath;
     1209    mediaFilePath.GetParent(&dirPath);
     1210    BDirectory  dir(dirPath.Path());
     1211    if ( dir.InitCheck() != B_OK )
     1212        return;
     1213   
     1214    BEntry  entry;
     1215    BString entryPathString;
     1216    while ( dir.GetNextEntry(&entry, true) == B_OK ) {
     1217        if ( !entry.IsFile() )
     1218            continue;
     1219        entryPathString = BPath(&entry).Path();
     1220        if ( entryPathString != mediaFilePathString
     1221                && _GetExceptExtension(entryPathString) == _GetExceptExtension(mediaFilePathString) ) {
     1222            if ( _BindExtraMedia(entryPathString) == B_OK )
     1223                return;
     1224        }
     1225    }
     1226}
     1227
     1228
     1229status_t
     1230Controller::_BindExtraMedia(const BString& path)
     1231{
     1232    // Currently, _BindExtraMedia() searches alternative media only from files.
     1233    MediaFileTrackSupplier* supplier = dynamic_cast<MediaFileTrackSupplier*>(fTrackSupplier);
     1234    if ( supplier == NULL )
     1235        return B_ERROR;
     1236       
     1237    entry_ref   ref;
     1238    get_ref_for_path(path.String(), &ref);
     1239    BMediaFile* mediaFile = new BMediaFile(&ref);
     1240    return supplier->AddExtraMediaTracks(mediaFile);
     1241}
     1242
     1243
     1244BString
     1245Controller::_GetExceptExtension(const BString& path) const
     1246{
     1247    int32   periodPos = path.FindLast('.');
     1248    if ( periodPos <= path.FindLast('/') )
     1249        return path;
     1250    return BString(path.String(), periodPos);
     1251}
     1252
     1253
     1254void
    11831255Controller::NotifyPlayModeChanged(int32 mode) const
    11841256{
    11851257    uint32 state = _PlaybackState(mode);
  • src/apps/mediaplayer/Controller.h

     
    175175            void                _NotifyVolumeChanged(float volume) const;
    176176            void                _NotifyMutedChanged(bool muted) const;
    177177
     178    // extra media binding
     179            void                _BindExtraMedia();
     180            status_t            _BindExtraMedia(const BString& path);
     181            BString             _GetExceptExtension(const BString& path) const;
     182
    178183    // overridden from PlaybackManager so that we
    179184    // can use our own Listener mechanism
    180185    virtual void                NotifyPlayModeChanged(int32 mode) const;
  • src/apps/mediaplayer/supplier/MediaFileTrackSupplier.cpp

     
    2222MediaFileTrackSupplier::MediaFileTrackSupplier(BMediaFile* mediaFile)
    2323    :
    2424    TrackSupplier(),
    25     fMediaFile(mediaFile)
     25    fMediaFile(mediaFile),
     26    fExtraMediaFile(NULL)
    2627{
    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     }
     28    _AddTracks(fMediaFile, true, true);
    6529}
    6630
    6731
    6832MediaFileTrackSupplier::~MediaFileTrackSupplier()
    6933{
    7034    delete fMediaFile;
     35    delete fExtraMediaFile;
    7136        // BMediaFile destructor will call ReleaseAllTracks()
    7237    for (int32 i = fSubTitleTracks.CountItems() - 1; i >= 0; i--)
    7338        delete reinterpret_cast<SubTitles*>(fSubTitleTracks.ItemAtFast(i));
     
    189154    return fSubTitleTracks.AddItem(subTitles);
    190155}
    191156
     157
     158status_t
     159MediaFileTrackSupplier::AddExtraMediaTracks(BMediaFile* mediaFile)
     160{
     161    delete fExtraMediaFile;
     162    fExtraMediaFile = mediaFile;
     163    if ( _AddTracks(mediaFile, CountAudioTracks() == 0, CountVideoTracks() == 0) != B_OK )
     164        return B_ERROR;
     165    return B_OK;
     166}
     167
     168
     169status_t
     170MediaFileTrackSupplier::_AddTracks(BMediaFile* mediaFile, bool audio, bool video)
     171{
     172    if (mediaFile->InitCheck() != B_OK)
     173        return B_ERROR;
     174    int trackCount = mediaFile->CountTracks();
     175    if (trackCount <= 0)
     176        return B_ERROR;
     177
     178    status_t    funcStatus = B_ERROR;
     179    for (int i = 0; i < trackCount; i++) {
     180        BMediaTrack* track = mediaFile->TrackAt(i);
     181        media_format format;
     182        status_t status = track->EncodedFormat(&format);
     183        if (status != B_OK) {
     184            fprintf(stderr, "MediaFileTrackSupplier: EncodedFormat failed for "
     185                "track index %d, error: %s\n", i, strerror(status));
     186            mediaFile->ReleaseTrack(track);
     187            continue;
     188        }
     189
     190        if (track->Duration() <= 0) {
     191            fprintf(stderr, "MediaFileTrackSupplier: warning! track index %d "
     192                "has no duration\n", i);
     193        }
     194
     195        if (format.IsAudio()) {
     196            if (audio && fAudioTracks.AddItem(track)) {
     197                funcStatus = B_OK;
     198            } else {
     199                mediaFile->ReleaseTrack(track);
     200            }
     201        } else if (format.IsVideo()) {
     202            if (video && fVideoTracks.AddItem(track)) {
     203                funcStatus = B_OK;
     204            } else {
     205                mediaFile->ReleaseTrack(track);
     206            }
     207        } else {
     208            printf("MediaFileTrackSupplier: track index %d has unknown "
     209                "type\n", i);
     210            mediaFile->ReleaseTrack(track);
     211        }
     212    }
     213    return funcStatus;
     214}
     215
     216
  • src/apps/mediaplayer/supplier/MediaFileTrackSupplier.h

     
    4141
    4242            bool                AddSubTitles(SubTitles* subTitles);
    4343
     44            status_t            AddExtraMediaTracks(BMediaFile* mediaFile);
     45
    4446private:
     47            status_t            _AddTracks(BMediaFile* mediaFile, bool audio, bool video);
     48
     49private:
    4550            BMediaFile*         fMediaFile;
     51            BMediaFile*         fExtraMediaFile;
    4652            BList               fAudioTracks;
    4753            BList               fVideoTracks;
    4854            BList               fSubTitleTracks;