1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "DVDMessage.h" 12 #include "threads/CriticalSection.h" 13 #include "threads/Event.h" 14 15 #include <algorithm> 16 #include <atomic> 17 #include <list> 18 #include <string> 19 20 struct DVDMessageListItem 21 { DVDMessageListItemDVDMessageListItem22 DVDMessageListItem(CDVDMsg* msg, int prio) 23 { 24 message = msg->Acquire(); 25 priority = prio; 26 } DVDMessageListItemDVDMessageListItem27 DVDMessageListItem() 28 { 29 message = NULL; 30 priority = 0; 31 } 32 DVDMessageListItem(const DVDMessageListItem&) = delete; ~DVDMessageListItemDVDMessageListItem33 ~DVDMessageListItem() 34 { 35 if(message) 36 message->Release(); 37 } 38 39 DVDMessageListItem& operator=(const DVDMessageListItem&) = delete; 40 41 CDVDMsg* message; 42 int priority; 43 }; 44 45 enum MsgQueueReturnCode 46 { 47 MSGQ_OK = 1, 48 MSGQ_TIMEOUT = 0, 49 MSGQ_ABORT = -1, // negative for legacy, not an error actually 50 MSGQ_NOT_INITIALIZED = -2, 51 MSGQ_INVALID_MSG = -3, 52 MSGQ_OUT_OF_MEMORY = -4 53 }; 54 55 #define MSGQ_IS_ERROR(c) (c < 0) 56 57 class CDVDMessageQueue 58 { 59 public: 60 explicit CDVDMessageQueue(const std::string &owner); 61 virtual ~CDVDMessageQueue(); 62 63 void Init(); 64 void Flush(CDVDMsg::Message message = CDVDMsg::DEMUXER_PACKET); 65 void Abort(); 66 void End(); 67 68 MsgQueueReturnCode Put(CDVDMsg* pMsg, int priority = 0); 69 MsgQueueReturnCode PutBack(CDVDMsg* pMsg, int priority = 0); 70 71 /** 72 * msg, message type from DVDMessage.h 73 * timeout, timeout in msec 74 * priority, minimum priority to get, outputs returned packets priority 75 */ 76 MsgQueueReturnCode Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds, int &priority); Get(CDVDMsg ** pMsg,unsigned int iTimeoutInMilliSeconds)77 MsgQueueReturnCode Get(CDVDMsg** pMsg, unsigned int iTimeoutInMilliSeconds) 78 { 79 int priority = 0; 80 return Get(pMsg, iTimeoutInMilliSeconds, priority); 81 } 82 GetDataSize()83 int GetDataSize() const { return m_iDataSize; } 84 int GetTimeSize() const; 85 unsigned GetPacketCount(CDVDMsg::Message type); ReceivedAbortRequest()86 bool ReceivedAbortRequest() { return m_bAbortRequest; } 87 void WaitUntilEmpty(); 88 89 // non messagequeue related functions IsFull()90 bool IsFull() const { return GetLevel() == 100; } 91 int GetLevel() const; 92 SetMaxDataSize(int iMaxDataSize)93 void SetMaxDataSize(int iMaxDataSize) { m_iMaxDataSize = iMaxDataSize; } SetMaxTimeSize(double sec)94 void SetMaxTimeSize(double sec) { m_TimeSize = 1.0 / std::max(1.0, sec); } GetMaxDataSize()95 int GetMaxDataSize() const { return m_iMaxDataSize; } GetMaxTimeSize()96 double GetMaxTimeSize() const { return m_TimeSize; } IsInited()97 bool IsInited() const { return m_bInitialized; } 98 bool IsDataBased() const; 99 100 private: 101 102 MsgQueueReturnCode Put(CDVDMsg* pMsg, int priority, bool front); 103 void UpdateTimeFront(); 104 void UpdateTimeBack(); 105 106 CEvent m_hEvent; 107 mutable CCriticalSection m_section; 108 109 std::atomic<bool> m_bAbortRequest; 110 bool m_bInitialized; 111 bool m_drain = false; 112 113 int m_iDataSize; 114 double m_TimeFront; 115 double m_TimeBack; 116 double m_TimeSize; 117 118 int m_iMaxDataSize; 119 std::string m_owner; 120 121 std::list<DVDMessageListItem> m_messages; 122 std::list<DVDMessageListItem> m_prioMessages; 123 }; 124 125