MythTV  master
mythbddecoder.cpp
Go to the documentation of this file.
1 // MythTV
2 #include "libmythbase/iso639.h"
3 #include "Bluray/mythbdplayer.h"
4 #include "Bluray/mythbdbuffer.h"
5 #include "Bluray/mythbddecoder.h"
6 
7 #define LOC QString("BDDecoder: ")
8 
10  : AvFormatDecoder(Parent, PGInfo, Flags)
11 {
12 }
13 
14 bool MythBDDecoder::IsValidStream(int StreamId)
15 {
16  if (m_ringBuffer && m_ringBuffer->IsBD())
17  return m_ringBuffer->BD()->IsValidStream(static_cast<uint>(StreamId));
18  return AvFormatDecoder::IsValidStream(StreamId);
19 }
20 
21 void MythBDDecoder::Reset(bool ResetVideoData, bool SeekReset, bool ResetFile)
22 {
23  AvFormatDecoder::Reset(ResetVideoData, SeekReset, ResetFile);
25 }
26 
28 {
29  if (!m_ringBuffer->IsBD())
30  return;
31 
32  auto currentpos = static_cast<long long>(m_ringBuffer->BD()->GetCurrentTime().count() * m_fps);
33  m_framesPlayed = m_framesRead = currentpos ;
34  m_parent->SetFramesPlayed(static_cast<uint64_t>(currentpos + 1));
35 }
36 
37 bool MythBDDecoder::DoRewindSeek(long long DesiredFrame)
38 {
39  if (!m_ringBuffer->IsBD())
40  return false;
41 
42  m_ringBuffer->Seek(BDFindPosition(DesiredFrame), SEEK_SET);
43  m_framesPlayed = m_framesRead = m_lastKey = DesiredFrame + 1;
44  m_frameCounter += 100;
45  return true;
46 }
47 
48 void MythBDDecoder::DoFastForwardSeek(long long DesiredFrame, bool &Needflush)
49 {
50  if (!m_ringBuffer->IsBD())
51  return;
52 
53  m_ringBuffer->Seek(BDFindPosition(DesiredFrame), SEEK_SET);
54  Needflush = true;
55  m_framesPlayed = m_framesRead = m_lastKey = DesiredFrame + 1;
56  m_frameCounter += 100;
57 }
58 
60 {
61  if (!m_ringBuffer->IsBD())
62  return;
63 
64  if (m_streamsChanged)
65  {
66  // This was originally in HandleBDStreamChange
67  LOG(VB_PLAYBACK, LOG_INFO, LOC + "resetting");
68  QMutexLocker locker(&m_trackLock);
69  Reset(true, false, false);
70  CloseCodecs();
72  ScanStreams(false);
73  m_streamsChanged=false;
74  }
75 
77  {
78  ResetPosMap();
81  }
82 }
83 
84 int MythBDDecoder::GetSubtitleLanguage(uint /*SubtitleIndex*/, uint StreamIndex)
85 {
86  if (m_ringBuffer && m_ringBuffer->IsBD() && (StreamIndex < m_ic->nb_streams) &&
87  (m_ic->streams[StreamIndex] != nullptr))
88  {
89  return m_ringBuffer->BD()->GetSubtitleLanguage(static_cast<uint>(m_ic->streams[StreamIndex]->id));
90  }
91 
92  return iso639_str3_to_key("und");
93 }
94 
95 int MythBDDecoder::GetAudioLanguage(uint /*AudioIndex*/, uint StreamIndex)
96 {
97  if (m_ringBuffer && m_ringBuffer->IsBD() && (StreamIndex < m_ic->nb_streams) &&
98  (m_ic->streams[StreamIndex] != nullptr))
99  {
100  return m_ringBuffer->BD()->GetAudioLanguage(static_cast<uint>(m_ic->streams[StreamIndex]->id));
101  }
102 
103  return iso639_str3_to_key("und");
104 }
105 
106 int MythBDDecoder::ReadPacket(AVFormatContext *Ctx, AVPacket* Pkt, bool& /*StorePacket*/)
107 {
108  m_avCodecLock.lock();
109  int result = av_read_frame(Ctx, Pkt);
110  m_avCodecLock.unlock();
111  /* If we seem to have hit the end of the file, the ringbuffer may
112  * just be blocked in order to drain the ffmpeg buffers, so try
113  * unblocking it and reading again.
114  * If ffmpeg's buffers are empty, it takes a couple of goes to
115  * fill and read from them.
116  */
117  for (int count = 0; (count < 3) && (result == AVERROR_EOF); count++)
118  {
119  if (m_ringBuffer->BD()->IsReadingBlocked())
121  m_avCodecLock.lock();
122  result = av_read_frame(Ctx, Pkt);
123  m_avCodecLock.unlock();
124  }
125 
126  if (result >= 0)
127  {
128  Pkt->dts = m_ringBuffer->BD()->AdjustTimestamp(Pkt->dts);
129  Pkt->pts = m_ringBuffer->BD()->AdjustTimestamp(Pkt->pts);
130  }
131 
132  return result;
133 }
134 
135 long long MythBDDecoder::BDFindPosition(long long DesiredFrame)
136 {
137  if (!m_ringBuffer->IsBD())
138  return 0;
139 
140  int ffrewSkip = 1;
141  int current_speed = 0;
142  if (m_parent)
143  {
144  ffrewSkip = m_parent->GetFFRewSkip();
145  current_speed = static_cast<int>(m_parent->GetNextPlaySpeed());
146  }
147 
148  if (ffrewSkip == 1 || ffrewSkip == 0)
149  {
150 #if 0
151  int diffTime = (int)ceil((desiredFrame - m_framesPlayed) / m_fps);
152  long long desiredTimePos = m_ringBuffer->BD()->GetCurrentTime() +
153  diffTime;
154  if (diffTime <= 0)
155  desiredTimePos--;
156  else
157  desiredTimePos++;
158 
159  if (desiredTimePos < 0)
160  desiredTimePos = 0;
161 #endif
162  return static_cast<long long>(DesiredFrame * 90000.0 / m_fps);
163  }
164  return current_speed;
165 }
MythBDBuffer::GetAudioLanguage
int GetAudioLanguage(uint StreamID)
Definition: mythbdbuffer.cpp:891
MythMediaBuffer::BD
const MythBDBuffer * BD(void) const
Definition: mythmediabuffer.cpp:1846
mythbddecoder.h
MythPlayer::AtNormalSpeed
bool AtNormalSpeed(void) const
Definition: mythplayer.h:159
mythbdplayer.h
DecoderBase::m_ringBuffer
MythMediaBuffer * m_ringBuffer
Definition: decoderbase.h:290
DecoderBase::m_fps
double m_fps
Definition: decoderbase.h:292
MythBDBuffer::TitleChanged
bool TitleChanged(void)
Definition: mythbdbuffer.cpp:779
MythMediaBuffer::Seek
long long Seek(long long Position, int Whence, bool HasLock=false)
Definition: mythmediabuffer.cpp:473
DecoderBase::m_parent
MythPlayer * m_parent
Definition: decoderbase.h:287
MythBDBuffer::IsReadingBlocked
bool IsReadingBlocked(void)
Definition: mythbdbuffer.cpp:1215
MythPlayer::GetNextPlaySpeed
float GetNextPlaySpeed(void) const
Definition: mythplayer.h:141
MythBDDecoder::DoRewindSeek
bool DoRewindSeek(long long DesiredFrame) override
Definition: mythbddecoder.cpp:37
AvFormatDecoder::IsValidStream
virtual bool IsValidStream(int)
Definition: avformatdecoder.h:250
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
DecoderBase::m_trackLock
QRecursiveMutex m_trackLock
Definition: decoderbase.h:350
PlayerFlags
PlayerFlags
Definition: mythplayer.h:64
MythPlayer
Definition: mythplayer.h:83
AvFormatDecoder::SeekReset
void SeekReset(long long newkey, uint skipFrames, bool doFlush, bool discardFrames) override
Definition: avformatdecoder.cpp:674
MythBDDecoder::UpdateFramesPlayed
void UpdateFramesPlayed(void) override
Definition: mythbddecoder.cpp:27
MythMediaBuffer::IsBD
bool IsBD(void) const
Definition: mythmediabuffer.cpp:1836
AvFormatDecoder::FindStreamInfo
int FindStreamInfo(void)
Definition: avformatdecoder.cpp:899
AvFormatDecoder::CloseCodecs
void CloseCodecs()
Definition: avformatdecoder.cpp:438
AvFormatDecoder::m_streamsChanged
bool m_streamsChanged
Definition: avformatdecoder.h:361
AvFormatDecoder::Reset
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
Definition: avformatdecoder.cpp:818
MythBDDecoder::GetSubtitleLanguage
int GetSubtitleLanguage(uint SubtitleIndex, uint StreamIndex) override
Returns DVD Subtitle language.
Definition: mythbddecoder.cpp:84
MythBDDecoder::GetAudioLanguage
int GetAudioLanguage(uint AudioIndex, uint StreamIndex) override
Definition: mythbddecoder.cpp:95
MythBDBuffer::UnblockReading
void UnblockReading(void)
Definition: mythbdbuffer.cpp:1210
MythBDDecoder::BDFindPosition
long long BDFindPosition(long long DesiredFrame)
Definition: mythbddecoder.cpp:135
AvFormatDecoder::m_ic
AVFormatContext * m_ic
Definition: avformatdecoder.h:263
MythBDDecoder::ReadPacket
int ReadPacket(AVFormatContext *Ctx, AVPacket *Pkt, bool &StorePacket) override
Definition: mythbddecoder.cpp:106
DecoderBase::ResetPosMap
virtual void ResetPosMap(void)
Definition: decoderbase.cpp:647
AvFormatDecoder
A decoder for media files.
Definition: avformatdecoder.h:82
uint
unsigned int uint
Definition: compat.h:81
DecoderBase::SyncPositionMap
virtual bool SyncPositionMap(void)
Updates the position map used for skipping frames.
Definition: decoderbase.cpp:322
MythBDDecoder::Reset
void Reset(bool ResetVideoData, bool SeekReset, bool ResetFile) override
Definition: mythbddecoder.cpp:21
mythbdbuffer.h
ProgramInfo
Holds information on recordings and videos.
Definition: programinfo.h:67
DecoderBase::m_framesPlayed
long long m_framesPlayed
Definition: decoderbase.h:300
MythPlayer::SetFramesPlayed
void SetFramesPlayed(uint64_t played)
Definition: mythplayer.cpp:562
MythBDBuffer::GetCurrentTime
std::chrono::seconds GetCurrentTime(void) const
Definition: mythbdbuffer.cpp:633
AvFormatDecoder::m_avCodecLock
QRecursiveMutex m_avCodecLock
Definition: avformatdecoder.h:367
MythBDBuffer::GetSubtitleLanguage
int GetSubtitleLanguage(uint StreamID)
Definition: mythbdbuffer.cpp:913
MythBDDecoder::StreamChangeCheck
void StreamChangeCheck(void) override
Definition: mythbddecoder.cpp:59
MythBDDecoder::MythBDDecoder
MythBDDecoder(MythPlayer *Parent, const ProgramInfo &PGInfo, PlayerFlags Flags)
Definition: mythbddecoder.cpp:9
iso639.h
ISO 639-1 and ISO 639-2 support functions.
DecoderBase::m_lastKey
long long m_lastKey
Definition: decoderbase.h:305
MythBDBuffer::IsValidStream
bool IsValidStream(uint StreamId)
Definition: mythbdbuffer.cpp:1191
MythBDDecoder::IsValidStream
bool IsValidStream(int StreamId) override
Definition: mythbddecoder.cpp:14
DecoderBase::m_framesRead
long long m_framesRead
Definition: decoderbase.h:301
iso639_str3_to_key
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:59
MythBDDecoder::DoFastForwardSeek
void DoFastForwardSeek(long long DesiredFrame, bool &Needflush) override
Seeks to the keyframe just before the desiredFrame if exact seeks is enabled, or the frame just after...
Definition: mythbddecoder.cpp:48
AvFormatDecoder::ScanStreams
int ScanStreams(bool novideo)
Definition: avformatdecoder.cpp:1896
MythPlayer::GetFFRewSkip
int GetFFRewSkip(void) const
Definition: mythplayer.h:138
MythBDBuffer::AdjustTimestamp
int64_t AdjustTimestamp(int64_t Timestamp) const
Definition: mythbdbuffer.cpp:809
LOC
#define LOC
Definition: mythbddecoder.cpp:7
DecoderBase::m_frameCounter
uint64_t m_frameCounter
Definition: decoderbase.h:302