MythTV  0.26-pre
avformatdecoderdvd.cpp
Go to the documentation of this file.
00001 #include "dvdringbuffer.h"
00002 #include "mythdvdplayer.h"
00003 #include "avformatdecoderdvd.h"
00004 
00005 #define LOC QString("AFD_DVD: ")
00006 
00007 AvFormatDecoderDVD::AvFormatDecoderDVD(
00008     MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
00009   : AvFormatDecoder(parent, pginfo, flags)
00010 {
00011 }
00012 
00013 void AvFormatDecoderDVD::Reset(bool reset_video_data, bool seek_reset, bool reset_file)
00014 {
00015     AvFormatDecoder::Reset(reset_video_data, seek_reset, reset_file);
00016     SyncPositionMap();
00017 }
00018 
00019 void AvFormatDecoderDVD::UpdateFramesPlayed(void)
00020 {
00021     if (!ringBuffer->IsDVD())
00022         return;
00023 
00024     long long currentpos = (long long)(ringBuffer->DVD()->GetCurrentTime() * fps);
00025     framesPlayed = framesRead = currentpos ;
00026     m_parent->SetFramesPlayed(currentpos + 1);
00027 }
00028 
00029 void AvFormatDecoderDVD::PostProcessTracks(void)
00030 {
00031     if (!ringBuffer)
00032         return;
00033     if (!ringBuffer->IsDVD())
00034         return;
00035 
00036     if (tracks[kTrackTypeAudio].size() > 1)
00037     {
00038         stable_sort(tracks[kTrackTypeAudio].begin(),
00039                     tracks[kTrackTypeAudio].end());
00040         sinfo_vec_t::iterator it = tracks[kTrackTypeAudio].begin();
00041         for (; it != tracks[kTrackTypeAudio].end(); ++it)
00042         {
00043             LOG(VB_PLAYBACK, LOG_INFO, LOC +
00044                 QString("DVD Audio Track Map Stream id #%1, MPEG stream %2")
00045                     .arg(it->stream_id)
00046                     .arg(ic->streams[it->av_stream_index]->id));
00047         }
00048         int trackNo = ringBuffer->DVD()->GetTrack(kTrackTypeAudio);
00049         if (trackNo >= (int)GetTrackCount(kTrackTypeAudio))
00050             trackNo = GetTrackCount(kTrackTypeAudio) - 1;
00051         SetTrack(kTrackTypeAudio, trackNo);
00052     }
00053 
00054     if (tracks[kTrackTypeSubtitle].size() > 0)
00055     {
00056         stable_sort(tracks[kTrackTypeSubtitle].begin(),
00057                     tracks[kTrackTypeSubtitle].end());
00058         sinfo_vec_t::iterator it = tracks[kTrackTypeSubtitle].begin();
00059         for(; it != tracks[kTrackTypeSubtitle].end(); ++it)
00060         {
00061             LOG(VB_PLAYBACK, LOG_INFO, LOC +
00062                 QString("DVD Subtitle Track Map Stream id #%1 ")
00063                     .arg(it->stream_id));
00064         }
00065         stable_sort(tracks[kTrackTypeSubtitle].begin(),
00066                     tracks[kTrackTypeSubtitle].end());
00067         int trackNo = ringBuffer->DVD()->GetTrack(kTrackTypeSubtitle);
00068         uint captionmode = m_parent->GetCaptionMode();
00069         int trackcount = (int)GetTrackCount(kTrackTypeSubtitle);
00070         if (captionmode == kDisplayAVSubtitle &&
00071             (trackNo < 0 || trackNo >= trackcount))
00072         {
00073             m_parent->EnableSubtitles(false);
00074         }
00075         else if (trackNo >= 0 && trackNo < trackcount &&
00076                  !ringBuffer->IsInDiscMenuOrStillFrame())
00077         {
00078             SetTrack(kTrackTypeSubtitle, trackNo);
00079             m_parent->EnableSubtitles(true);
00080         }
00081     }
00082 }
00083 
00084 bool AvFormatDecoderDVD::DoRewindSeek(long long desiredFrame)
00085 {
00086     if (!ringBuffer->IsDVD())
00087         return false;
00088 
00089     ringBuffer->Seek(DVDFindPosition(desiredFrame), SEEK_SET);
00090     framesPlayed = framesRead = lastKey = desiredFrame + 1;
00091     return true;
00092 }
00093 
00094 void AvFormatDecoderDVD::DoFastForwardSeek(long long desiredFrame, bool &needflush)
00095 {
00096     if (!ringBuffer->IsDVD())
00097         return;
00098 
00099     ringBuffer->Seek(DVDFindPosition(desiredFrame),SEEK_SET);
00100     needflush    = true;
00101     framesPlayed = framesRead = lastKey = desiredFrame + 1;
00102 }
00103 
00104 void AvFormatDecoderDVD::StreamChangeCheck(void)
00105 {
00106     if (!ringBuffer->IsDVD())
00107         return;
00108 
00109     // Update the title length
00110     if (m_parent->AtNormalSpeed() &&
00111         ringBuffer->DVD()->PGCLengthChanged())
00112     {
00113         ResetPosMap();
00114         SyncPositionMap();
00115         UpdateFramesPlayed();
00116     }
00117 
00118     // rescan the non-video streams as necessary
00119     if (ringBuffer->DVD()->AudioStreamsChanged())
00120         ScanStreams(true);
00121 
00122     // Always use the first video stream
00123     // (must come after ScanStreams above)
00124     selectedTrack[kTrackTypeVideo].av_stream_index = 0;
00125 }
00126 
00127 int AvFormatDecoderDVD::GetAudioLanguage(uint audio_index, uint stream_index)
00128 {
00129     (void)audio_index;
00130     if (ringBuffer && ringBuffer->IsDVD())
00131     {
00132         return ringBuffer->DVD()->GetAudioLanguage(
00133             ringBuffer->DVD()->GetAudioTrackNum(ic->streams[stream_index]->id));
00134     }
00135     return iso639_str3_to_key("und");
00136 }
00137 
00138 long long AvFormatDecoderDVD::DVDFindPosition(long long desiredFrame)
00139 {
00140     if (!ringBuffer->IsDVD())
00141         return 0;
00142 
00143     int diffTime = 0;
00144     long long desiredTimePos;
00145     int ffrewSkip = 1;
00146     int current_speed = 0;
00147     if (m_parent)
00148     {
00149         ffrewSkip = m_parent->GetFFRewSkip();
00150         current_speed = (int)m_parent->GetNextPlaySpeed();
00151     }
00152 
00153     if (ffrewSkip == 1 || ffrewSkip == 0)
00154     {
00155         diffTime = (int)ceil((desiredFrame - framesPlayed) / fps);
00156         desiredTimePos = ringBuffer->DVD()->GetCurrentTime() +
00157                         diffTime;
00158         if (diffTime <= 0)
00159             desiredTimePos--;
00160         else
00161             desiredTimePos++;
00162 
00163         if (desiredTimePos < 0)
00164             desiredTimePos = 0;
00165         return (desiredTimePos * 90000LL);
00166     }
00167     return current_speed;
00168 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends