MythTV  master
avformatdecoderbd.cpp
Go to the documentation of this file.
1 #include "bdringbuffer.h"
2 #include "mythbdplayer.h"
3 #include "avformatdecoderbd.h"
4 
5 #include "iso639.h"
6 
7 #define LOC QString("AFD_BD: ")
8 
10  MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
11  : AvFormatDecoder(parent, pginfo, flags)
12 {
13 }
14 
16 {
17  if (ringBuffer && ringBuffer->IsBD())
18  return ringBuffer->BD()->IsValidStream(streamid);
19  return AvFormatDecoder::IsValidStream(streamid);
20 }
21 
22 void AvFormatDecoderBD::Reset(bool reset_video_data, bool seek_reset, bool reset_file)
23 {
24  AvFormatDecoder::Reset(reset_video_data, seek_reset, reset_file);
26 }
27 
29 {
30  if (!ringBuffer->IsBD())
31  return;
32 
33  long long currentpos = (long long)(ringBuffer->BD()->GetCurrentTime() * m_fps);
34  m_framesPlayed = m_framesRead = currentpos ;
35  m_parent->SetFramesPlayed(currentpos + 1);
36 }
37 
38 bool AvFormatDecoderBD::DoRewindSeek(long long desiredFrame)
39 {
40  if (!ringBuffer->IsBD())
41  return false;
42 
43  ringBuffer->Seek(BDFindPosition(desiredFrame), SEEK_SET);
44  m_framesPlayed = m_framesRead = m_lastKey = desiredFrame + 1;
45  return true;
46 }
47 
48 void AvFormatDecoderBD::DoFastForwardSeek(long long desiredFrame, bool &needflush)
49 {
50  if (!ringBuffer->IsBD())
51  return;
52 
53  ringBuffer->Seek(BDFindPosition(desiredFrame), SEEK_SET);
54  needflush = true;
55  m_framesPlayed = m_framesRead = m_lastKey = desiredFrame + 1;
56 }
57 
59 {
60  if (!ringBuffer->IsBD())
61  return;
62 
64  {
65  // This was originally in HandleBDStreamChange
66  LOG(VB_PLAYBACK, LOG_INFO, LOC + "resetting");
67  QMutexLocker locker(avcodeclock);
68  Reset(true, false, false);
69  CloseCodecs();
71  ScanStreams(false);
72  avcodeclock->unlock();
73  m_streams_changed=false;
74  }
75 
77  {
78  ResetPosMap();
81  }
82 }
83 
85  uint stream_index)
86 {
87  (void)subtitle_index;
88  if (ringBuffer && ringBuffer->IsBD() &&
89  stream_index < m_ic->nb_streams &&
90  m_ic->streams[stream_index] != nullptr)
91  {
92  return ringBuffer->BD()->GetSubtitleLanguage(m_ic->streams[stream_index]->id);
93  }
94 
95  return iso639_str3_to_key("und");
96 }
97 
98 int AvFormatDecoderBD::GetAudioLanguage(uint audio_index, uint stream_index)
99 {
100  (void)audio_index;
101  if (ringBuffer && ringBuffer->IsBD() &&
102  stream_index < m_ic->nb_streams &&
103  m_ic->streams[stream_index] != nullptr)
104  {
105  return ringBuffer->BD()->GetAudioLanguage(m_ic->streams[stream_index]->id);
106  }
107 
108  return iso639_str3_to_key("und");
109 }
110 
111 int AvFormatDecoderBD::ReadPacket(AVFormatContext *ctx, AVPacket* pkt, bool& /*storePacket*/)
112 {
113  QMutexLocker locker(avcodeclock);
114 
115  int result = av_read_frame(ctx, pkt);
116 
117  /* If we seem to have hit the end of the file, the ringbuffer may
118  * just be blocked in order to drain the ffmpeg buffers, so try
119  * unblocking it and reading again.
120  * If ffmpeg's buffers are empty, it takes a couple of goes to
121  * fill and read from them.
122  */
123  for (int count = 0; (count < 3) && (result == AVERROR_EOF); count++)
124  {
125  if (ringBuffer->BD()->IsReadingBlocked())
127 
128  result = av_read_frame(ctx, pkt);
129  }
130 
131  if (result >= 0)
132  {
133  pkt->dts = ringBuffer->BD()->AdjustTimestamp(pkt->dts);
134  pkt->pts = ringBuffer->BD()->AdjustTimestamp(pkt->pts);
135  }
136 
137  return result;
138 }
139 
140 long long AvFormatDecoderBD::BDFindPosition(long long desiredFrame)
141 {
142  if (!ringBuffer->IsBD())
143  return 0;
144 
145  int ffrewSkip = 1;
146  int current_speed = 0;
147  if (m_parent)
148  {
149  ffrewSkip = m_parent->GetFFRewSkip();
150  current_speed = (int)m_parent->GetNextPlaySpeed();
151  }
152 
153  if (ffrewSkip == 1 || ffrewSkip == 0)
154  {
155 #if 0
156  int diffTime = (int)ceil((desiredFrame - m_framesPlayed) / m_fps);
157  long long desiredTimePos = ringBuffer->BD()->GetCurrentTime() +
158  diffTime;
159  if (diffTime <= 0)
160  desiredTimePos--;
161  else
162  desiredTimePos++;
163 
164  if (desiredTimePos < 0)
165  desiredTimePos = 0;
166 #endif
167  return (desiredFrame * 90000LL / m_fps);
168  }
169  return current_speed;
170 }
ISO 639-1 and ISO 639-2 support functions.
PlayerFlags
Definition: mythplayer.h:88
bool IsValidStream(int streamid) override
int GetAudioLanguage(uint audio_index, uint stream_index) override
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
bool IsReadingBlocked(void)
Definition: bdringbuffer.h:122
unsigned int uint
Definition: compat.h:140
static int iso639_str3_to_key(const unsigned char *iso639_2)
Definition: iso639.h:63
uint64_t GetCurrentTime(void)
Definition: bdringbuffer.h:107
int ReadPacket(AVFormatContext *ctx, AVPacket *pkt, bool &storePacket) override
#define LOC
void SetFramesPlayed(uint64_t played)
Definition: mythplayer.cpp:968
void UpdateFramesPlayed(void) override
RingBuffer * ringBuffer
Definition: decoderbase.h:298
bool DoRewindSeek(long long desiredFrame) override
Holds information on recordings and videos.
Definition: programinfo.h:66
int64_t AdjustTimestamp(int64_t timestamp)
AvFormatDecoderBD(MythPlayer *parent, const ProgramInfo &pginfo, PlayerFlags flags)
bool IsValidStream(int streamid)
long long BDFindPosition(long long desiredFrame)
AVFormatContext * m_ic
int GetAudioLanguage(uint streamID)
virtual void ResetPosMap(void)
A decoder for video files.
long long m_framesPlayed
Definition: decoderbase.h:308
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...
bool IsBD(void) const
int GetFFRewSkip(void) const
Definition: mythplayer.h:187
int GetSubtitleLanguage(uint streamID)
int FindStreamInfo(void)
virtual bool SyncPositionMap(void)
Updates the position map used for skipping frames.
int ScanStreams(bool novideo)
bool AtNormalSpeed(void) const
Definition: mythplayer.h:224
long long m_lastKey
Definition: decoderbase.h:311
int GetSubtitleLanguage(uint subtitle_index, uint stream_index) override
Returns DVD Subtitle language.
bool TitleChanged(void)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void Reset(bool reset_video_data, bool seek_reset, bool reset_file) override
QMutex * avcodeclock
This global variable is used to makes certain calls to avlib threadsafe.
void StreamChangeCheck(void) override
float GetNextPlaySpeed(void) const
Definition: mythplayer.h:192
long long Seek(long long pos, int whence, bool has_lock=false)
Seeks to a particular position in the file.
Definition: ringbuffer.cpp:510
const BDRingBuffer * BD(void) const
void UnblockReading(void)
Definition: bdringbuffer.h:121
long long m_framesRead
Definition: decoderbase.h:309
virtual bool IsValidStream(int)
MythPlayer * m_parent
Definition: decoderbase.h:295