Correct one other leaked change that broke encoding (damn some of this
[xiph/unicode.git] / oggds / OggPageQueue.cpp
blob592de19df36983986f7ba08e5705e3c23e66736f
1 /*******************************************************************************
2 * *
3 * This file is part of the Ogg Vorbis DirectShow filter collection *
4 * *
5 * Copyright (c) 2001, Tobias Waldvogel *
6 * All rights reserved. *
7 * *
8 * Redistribution and use in source and binary forms, with or without *
9 * modification, are permitted provided that the following conditions are met: *
10 * *
11 * - Redistributions of source code must retain the above copyright notice, *
12 * this list of conditions and the following disclaimer. *
13 * *
14 * - Redistributions in binary form must reproduce the above copyright notice, *
15 * this list of conditions and the following disclaimer in the documentation *
16 * and/or other materials provided with the distribution. *
17 * *
18 * - The names of the contributors may not be used to endorse or promote *
19 * products derived from this software without specific prior written *
20 * permission. *
21 * *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE *
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN *
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) *
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
32 * POSSIBILITY OF SUCH DAMAGE. *
33 * *
34 *******************************************************************************/
36 // This class is used for queueing Ogg pages
38 #include "OggPageQueue.h"
40 COggPageQueue::COggPageQueue()
42 m_pPageListFirst = NULL;
43 m_pPageListTail = NULL;
44 m_pFreePageList =NULL;
45 m_iHeaderAlloc = 0x80;
46 m_iBodyAlloc = 0x1400;
47 m_iPagesInQueue = 0;
50 COggPageQueue::~COggPageQueue()
52 OggPageQueueFlush();
55 void COggPageQueue::OggPageQueueClearFreeList()
57 // The lock must already be set
58 tPageNode* pTemp;
60 while (m_pFreePageList)
62 pTemp = m_pFreePageList;
63 m_pFreePageList = m_pFreePageList->pNext;
64 delete [] pTemp->og.header;
65 delete [] pTemp->og.body;
66 delete pTemp;
70 // Clears the page list and the free list
71 void COggPageQueue::OggPageQueueFlush()
73 CAutoLock lock(&m_csPageList);
75 tPageNode* pTemp;
77 // Clear the page list
78 while (m_pPageListFirst)
80 pTemp = m_pPageListFirst;
81 m_pPageListFirst = m_pPageListFirst->pNext;
82 delete [] pTemp->og.header;
83 delete [] pTemp->og.body;
84 delete pTemp;
86 m_pPageListTail = NULL;
87 m_iPagesInQueue = 0;
89 OggPageQueueClearFreeList();
92 // Queues one page
93 void COggPageQueue::OggPageEnqueue(ogg_page* pog, REFERENCE_TIME* prtTime)
95 tPageNode* pNode = NULL;
96 CAutoLock lock(&m_csPageList);
98 if ((pog->header_len <= m_iHeaderAlloc) &&
99 (pog->body_len <= m_iBodyAlloc)) // => Page fits
101 if (m_pFreePageList) // Are there pages in the free list ?
103 // reuse an existing page
104 pNode = m_pFreePageList;
105 m_pFreePageList = m_pFreePageList->pNext;
108 else
110 // Page doesn't fit => we must increase the size
111 if (pog->header_len > m_iHeaderAlloc)
112 m_iHeaderAlloc = (pog->header_len & 0xffffff80) + 0x80;
113 if (pog->body_len > m_iBodyAlloc)
114 m_iBodyAlloc = (pog->body_len & 0xfffffc00) + 0x400;
115 OggPageQueueClearFreeList(); // Clear all existing free pages
118 if (!pNode) // we must create a new one because free list was empty or it didnĀ“t fit
120 pNode = new tPageNode;
121 pNode->header_size = m_iHeaderAlloc;
122 pNode->og.header = new unsigned char[m_iHeaderAlloc];
123 pNode->body_size = m_iBodyAlloc;
124 pNode->og.body = new unsigned char[m_iBodyAlloc];
127 // Copy the page ...
128 memcpy(pNode->og.header, pog->header, pog->header_len);
129 pNode->og.header_len = pog->header_len;
130 memcpy(pNode->og.body, pog->body, pog->body_len);
131 pNode->og.body_len = pog->body_len;
132 pNode->rtPos = prtTime ? *prtTime : 0;
134 // and add this page at the end of the list
135 pNode->pNext = NULL;
136 if (m_pPageListTail)
138 m_pPageListTail->pNext = pNode; // Add it as last one
139 m_pPageListTail = m_pPageListTail->pNext; // and let tail point to it
141 else
143 m_pPageListFirst = pNode;
144 m_pPageListTail = pNode;
147 m_iPagesInQueue++;
150 // Get a page from the queue
151 tPageNode* COggPageQueue::OggPageDequeue()
153 CAutoLock lock(&m_csPageList);
154 tPageNode* pPage;
156 if (!m_pPageListFirst) return NULL;
158 pPage = m_pPageListFirst;
159 m_pPageListFirst = m_pPageListFirst->pNext;
160 if (m_pPageListFirst == NULL)
161 m_pPageListTail = NULL;
163 m_iPagesInQueue--;
164 return pPage;
167 void COggPageQueue::OggPageRelease(tPageNode* pNode)
169 if ((pNode->header_size < m_iHeaderAlloc) ||
170 (pNode->body_size < m_iBodyAlloc))
172 // This node can not be use anymore because the size has been increased
173 delete [] pNode->og.header;
174 delete [] pNode->og.body;
175 delete pNode;
176 return;
179 // Otherwise add it to the free list
180 CAutoLock lock(&m_csPageList);
182 pNode->pNext = m_pFreePageList;
183 m_pFreePageList = pNode;
186 // return the number of pages in the queue
187 int COggPageQueue::OggPageQueuePages()
189 CAutoLock lock(&m_csPageList);
190 return m_iPagesInQueue;
193 // checks if the queue is empty
194 bool COggPageQueue::OggPageQueuePageReady()
196 CAutoLock lock(&m_csPageList);
197 return m_pPageListFirst != NULL;
200 // returns the time of the first available page
201 bool COggPageQueue::OggPageQueueCurrTime(REFERENCE_TIME* rtTime)
203 CAutoLock lock(&m_csPageList);
205 if (!m_pPageListFirst)
206 return false;
208 *rtTime = m_pPageListFirst->rtPos;
209 return true;