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