18#include "libavcodec/avcodec.h"
40 auto* ref =
reinterpret_cast<AVBufferRef*
>(
Frame->m_priv[0]);
42 Discards.push_back(ref);
47 ref =
reinterpret_cast<AVBufferRef*
>(
Frame->m_priv[1]);
49 Discards.push_back(ref);
50 Frame->m_priv[1] =
nullptr;
55static inline void DoDiscard(
const std::vector<AVBufferRef *> &Discards)
57 for (
auto * it : Discards)
136 uint refs =
static_cast<uint>(MaxReferenceFrames);
175 uint NeedPrebufferNormal,
uint NeedPrebufferSmall)
183 m_buffers.reserve(std::max(NumDecode, 128U));
185 for (
uint i = 0; i < NumDecode; i++)
193 for (
uint i = 0; i < NumDecode; i++)
219 Frame.m_deinterlaceSingle = Single;
220 Frame.m_deinterlaceDouble = Double;
225 Frame.m_deinterlaceAllowed = kSoftware | kShader | kDriver;
227 Frame.m_deinterlaceAllowed = kSoftware | kShader;
231 Frame.m_deinterlaceAllowed = kShader;
235 Frame.m_deinterlaceAllowed = kShader;
239 Frame.m_deinterlaceAllowed = kShader;
243 Frame.m_deinterlaceAllowed = kShader | kDriver;
247 Frame.m_deinterlaceAllowed = kDriver;
251 Frame.m_deinterlaceAllowed = kDriver;
255 Frame.m_deinterlaceAllowed = kSoftware | kShader;
303 LOG(VB_PLAYBACK, LOG_NOTICE,
304 QString(
"GetNextFreeFrame() served a busy frame %1. Dropping. %2")
320 for (
uint tries = 1;
true; tries++)
328 LOG(VB_GENERAL, LOG_ERR, QString(
"GetNextFreeFrame: "
329 "available:%1 used:%2 limbo:%3 pause:%4 displayed:%5 decode:%6 finished:%7")
333 LOG(VB_GENERAL, LOG_ERR,
334 QString(
"GetNextFreeFrame() unable to "
335 "lock frame %1 times. Discarding Frames.")
343 LOG(VB_PLAYBACK, LOG_NOTICE,
344 QString(
"GetNextFreeFrame() TryLock has "
345 "spun %1 times, this is a lot.").arg(tries));
366 if (
Frame->m_directRendering)
378 std::vector<AVBufferRef*> discards;
418 std::vector<AVBufferRef*> discards;
429 for (
auto & it : ula)
451 std::vector<AVBufferRef*> discards;
461 std::vector<AVBufferRef*> discards;
484 std::vector<AVBufferRef*> refs;
487 LOG(VB_PLAYBACK, LOG_INFO, QString(
"DiscardAndRecreate: %1").arg(
GetStatus()));
506 for (
auto & discard : discards)
519 LOG(VB_GENERAL, LOG_INFO,
520 QString(
"VideoBuffers::DiscardFrames(): %1 (%2) not "
521 "in available, pause, or displayed %3")
577 LOG(VB_PLAYBACK, LOG_INFO, QString(
"DiscardAndRecreate: %1").arg(
GetStatus()));
653 return queue->
head();
664 return queue->
tail();
679 Frame->m_pauseFrame =
true;
724 return queue->begin();
745 return queue->size();
809 std::vector<AVBufferRef*> refs;
811 LOG(VB_PLAYBACK, LOG_INFO, QString(
"VideoBuffers::DiscardFrames(%1): %2")
812 .arg(NextFrameIsKeyFrame).arg(
GetStatus()));
814 if (!NextFrameIsKeyFrame)
817 for (
auto & it : ula)
822 LOG(VB_PLAYBACK, LOG_INFO,
823 QString(
"VideoBuffers::DiscardFrames(%1): %2 -- done")
824 .arg(NextFrameIsKeyFrame).arg(
GetStatus()));
841 for (it = discards.begin(); it != discards.end(); ++it)
859 LOG(VB_GENERAL, LOG_DEBUG,
860 QString(
"VideoBuffers::DiscardFrames(): %1 (%2) not "
861 "in available, pause, or displayed %3")
878 LOG(VB_PLAYBACK, LOG_INFO,
879 QString(
"VideoBuffers::DiscardFrames(%1): %2 -- done")
880 .arg(NextFrameIsKeyFrame).arg(
GetStatus()));
896 std::vector<AVBufferRef*> discards;
940 uint NeedFree,
uint NeedprebufferNormal,
941 uint NeedPrebufferSmall,
int MaxReferenceFrames)
944 Init(
GetNumBuffers(Type, MaxReferenceFrames), NeedFree, NeedprebufferNormal, NeedPrebufferSmall);
958 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Created %1 empty %2 (%3x%4) video buffers")
972 if (!success && (Width < 1 || Height < 1))
975 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Created %1 %2 (%3x%4) video buffers")
981 int Width,
int Height)
988 LOG(VB_GENERAL, LOG_ERR,
"Cannot re-initialise a hardware buffer");
994 LOG(VB_PLAYBACK, LOG_INFO, QString(
"Reallocating frame %1 %2x%3->%4 %5x%6")
1001 Frame->ClearBufferToBlank();
1026 for (
uint i = 0; i < Num; i++)
1028 unsigned long long mask = 1ULL << i;
1031 tmp += (x & mask) ?
"a" :
"A";
1033 tmp += (x & mask) ?
"u" :
"U";
1035 tmp += (x & mask) ?
"d" :
"D";
1037 tmp += (x & mask) ?
"l" :
"L";
1039 tmp += (x & mask) ?
"p" :
"P";
1041 tmp += (x & mask) ?
"f" :
"F";
1042 if (0 ==
tmp.length())
1044 else if (1 ==
tmp.length())
1047 str +=
"(" +
tmp +
")";
1053 for (
uint i = 0; i < Num; i++)
1066 "A ",
" B ",
" C ",
" D ",
1067 " E ",
" F ",
" G ",
" H",
1068 "a ",
" b ",
" c ",
" d ",
1069 " e ",
" f ",
" g ",
" h",
1070 "0 ",
" 1 ",
" 2 ",
" 3 ",
1071 " 4 ",
" 5 ",
" 6 ",
" 7",
1072 "I ",
" J ",
" K ",
" L ",
1073 " M ",
" N ",
" O ",
" P",
1074 "i ",
" j ",
" k ",
" l ",
1075 " m ",
" n ",
" o ",
" p",
1079 "A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
1080 "a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
1081 "0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
1082 "I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
1083 "i",
"j",
"k",
"l",
"m",
"n",
"o",
"p",
1110 unsigned long long bitmap = 0;
1111 for (
auto *it : Queue)
1114 bitmap |= 1ULL << shift;
static const std::array< const std::string, 8 > formats
T head()
Returns item at head of list. O(1).
size_type count() const
Returns size of list. O(1).
T dequeue()
Removes item from front of list and returns a copy. O(1).
void remove(T const item)
Removes any item from list. O(n).
void enqueue(const T &d)
Adds item to the back of the list. O(1).
bool contains(T const &item) const
Returns true if item is in list. O(n).
typename std::deque< MythVideoFrame * >::iterator iterator
T tail()
Returns item at tail of list. O(1).
static QString FormatDescription(VideoFrameType Type)
static bool HardwareFramesFormat(VideoFrameType Type)
std::chrono::milliseconds m_timecode
static bool HardwareFormat(VideoFrameType Type)
uint m_needPrebufferFramesSmall
void SetPrebuffering(bool Normal)
Sets prebuffering state to normal, or small.
QRecursiveMutex m_globalLock
MythVideoFrame * GetNextFreeFrame(BufferType EnqueueTo=kVideoBuffer_limbo)
Gets a frame from available buffers list.
static uint GetNumBuffers(int PixelFormat, int MaxReferenceFrames=16, bool Decoder=false)
void SafeEnqueue(BufferType Type, MythVideoFrame *Frame)
frame_queue_t::iterator BeginLock(BufferType Type)
Lock the video buffers.
MythVideoFrame * Tail(BufferType Type)
bool EnoughFreeFrames(void) const
frame_queue_t * Queue(BufferType Type)
MythVideoFrame * At(uint FrameNum)
QString GetStatus(uint Num=0) const
frame_queue_t m_displayed
MythVideoFrame * GetLastShownFrame(void)
MythVideoFrame * GetLastDecodedFrame(void)
void SetDeinterlacing(MythDeintType Single, MythDeintType Double, MythCodecID CodecID)
frame_queue_t m_available
static void SetDeinterlacingFlags(MythVideoFrame &Frame, MythDeintType Single, MythDeintType Double, MythCodecID CodecID)
Set the appropriate flags for single and double rate deinterlacing.
bool CreateBuffers(VideoFrameType Type, const VideoFrameTypes *RenderFormats, QSize Size, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall, int MaxReferenceFrames=16)
uint ValidVideoFrames(void) const
bool EnoughDecodedFrames(void) const
void Reset(void)
Resets the class so that Init may be called again.
bool Contains(BufferType Type, MythVideoFrame *Frame) const
void Remove(BufferType Type, MythVideoFrame *Frame)
void DiscardPauseFrames(void)
void DoneDisplayingFrame(MythVideoFrame *Frame)
Removes frame from used queue and adds it to the available list.
const VideoFrameTypes * m_renderFormats
MythVideoFrame * Dequeue(BufferType Type)
MythVideoFrame * GetNextFreeFrameInternal(BufferType EnqueueTo)
void Enqueue(BufferType Type, MythVideoFrame *Frame)
static bool ReinitBuffer(MythVideoFrame *Frame, VideoFrameType Type, MythCodecID CodecID, int Width, int Height)
frame_queue_t::iterator End(BufferType Type)
void DiscardFrames(bool NextFrameIsKeyFrame)
Mark all used frames as ready to be reused, this is for seek.
void ReleaseFrame(MythVideoFrame *Frame)
Frame is ready to be for filtering or OSD application.
void Init(uint NumDecode, uint NeedFree, uint NeedprebufferNormal, uint NeedPrebufferSmall)
Creates buffers and sets various buffer management parameters.
void ClearAfterSeek(void)
Clear used frames after seeking.
vbuffer_map_t m_vbufferMap
void DiscardFrame(MythVideoFrame *Frame)
Frame is ready to be reused by decoder.
bool DiscardAndRecreate(MythCodecID CodecID, QSize VideoDim, int References)
Discard all buffers and recreate.
uint FreeVideoFrames(void) const
void StartDisplayingFrame(void)
Sets rpos to index of videoframe at head of used queue.
uint m_needPrebufferFramesNormal
MythVideoFrame * Head(BufferType Type)
void DeLimboFrame(MythVideoFrame *Frame)
If the frame is still in the limbo state it is added to the available queue.
uint m_needPrebufferFrames
static const iso6937table * d
static bool codec_is_vdpau(MythCodecID id)
static bool codec_is_mediacodec(MythCodecID id)
static bool codec_is_drmprime(MythCodecID id)
static bool codec_is_mmal(MythCodecID id)
static bool codec_is_nvdec(MythCodecID id)
static bool codec_is_vtb(MythCodecID id)
static bool codec_is_v4l2(MythCodecID id)
static bool codec_is_copyback(MythCodecID id)
static bool codec_is_nvdec_dec(MythCodecID id)
static bool codec_is_vaapi(MythCodecID id)
static bool codec_is_vaapi_dec(MythCodecID id)
std::vector< VideoFrameType > VideoFrameTypes
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static unsigned long long to_bitmap(const frame_queue_t &Queue, int Num)
static constexpr std::chrono::milliseconds TRY_LOCK_SPIN_WAIT
static constexpr size_t DBG_STR_ARR_SIZE
static int DebugNum(const MythVideoFrame *Frame)
std::map< const MythVideoFrame *, int > dbg_str
const std::array< const QString, DBG_STR_ARR_SIZE > dbg_str_arr
static constexpr uint16_t TRY_LOCK_SPINS_BEFORE_WARNING
static void DoDiscard(const std::vector< AVBufferRef * > &Discards)
static void ReleaseDecoderResources(MythVideoFrame *Frame, std::vector< AVBufferRef * > &Discards)
Store AVBufferRef's for later disposal.
static constexpr uint16_t TRY_LOCK_SPINS
const std::array< const QString, DBG_STR_ARR_SIZE > dbg_str_arr_short
const QString & DebugString(const MythVideoFrame *Frame, bool Short)