1 /*---------------------------------------------------------------------------*
2 Project: THP Player
3 File: THPRead.c
4
5 Copyright (C)2002-2006 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: THPRead.c,v $
14 Revision 1.1 02/03/2006 10:01:41 aka
15 Imported from Dolphin tree.
16
17
18 3 03/11/25 11:24 Dante
19 Japanese to English translation of comments and text strings
20
21 2 02/05/14 9:14a Suzuki
22 Changed return value type and argument type of PopReadedBuffer(),
23 PushReadedBuffer(), PopFreeReadBuffer(), PushFreeReadBuffer(),
24 PopReadedBuffer2(), PushReadedBuffer2(r)
25
26 1 02/01/16 10:53a Akagi
27 Initial revision made by Suzuki-san (IRD).
28
29 $NoKeywords: $
30
31 *---------------------------------------------------------------------------*/
32
33 #include <string.h>
34 #include <revolution.h>
35
36 #include "THPPlayer.h"
37 #include "THPRead.h"
38
39 /*---------------------------------------------------------------------------*
40 External function
41 *---------------------------------------------------------------------------*/
42
43 extern void PrepareReady(BOOL flag);
44
45 /*---------------------------------------------------------------------------*
46 Static function
47 *---------------------------------------------------------------------------*/
48
49 static void *Reader(void *ptr);
50
51 /*---------------------------------------------------------------------------*
52 Global variable
53 *---------------------------------------------------------------------------*/
54
55 extern THPPlayer ActivePlayer;
56
57 /*---------------------------------------------------------------------------*
58 Static variable
59 *---------------------------------------------------------------------------*/
60
61 static s32 ReadThreadCreated = 0;
62 static OSMessageQueue FreeReadBufferQueue;
63 static OSMessageQueue ReadedBufferQueue;
64 static OSMessageQueue ReadedBufferQueue2;
65 static OSMessage FreeReadBufferMessage[READ_BUFFER_NUM];
66 static OSMessage ReadedBufferMessage[READ_BUFFER_NUM];
67 static OSMessage ReadedBufferMessage2[READ_BUFFER_NUM];
68 static OSThread ReadThread;
69 static u8 ReadThreadStack[4*1024];
70
71 /*---------------------------------------------------------------------------*
72 Name: CreateReadThread
73
74 Description: Create read thread
75
76 Arguments: priority Thread priority
77
78 Returns: If successful in creating thread, returns TRUE. If unsuccessful, returns FALSE.
79 *---------------------------------------------------------------------------*/
80
CreateReadThread(OSPriority priority)81 BOOL CreateReadThread(OSPriority priority)
82 {
83 if (OSCreateThread(&ReadThread,
84 Reader,
85 NULL,
86 ReadThreadStack + sizeof(ReadThreadStack),
87 sizeof(ReadThreadStack),
88 priority,
89 OS_THREAD_ATTR_DETACH) == FALSE)
90 {
91 #ifdef _DEBUG
92 OSReport("Can't create read thread\n");
93 #endif
94 return FALSE;
95 }
96
97 OSInitMessageQueue(&FreeReadBufferQueue,
98 FreeReadBufferMessage,
99 READ_BUFFER_NUM);
100
101 OSInitMessageQueue(&ReadedBufferQueue,
102 ReadedBufferMessage,
103 READ_BUFFER_NUM);
104
105 OSInitMessageQueue(&ReadedBufferQueue2,
106 ReadedBufferMessage2,
107 READ_BUFFER_NUM);
108
109 ReadThreadCreated = 1;
110
111 return TRUE;
112 }
113
114 /*---------------------------------------------------------------------------*
115 Name: ReadThreadStart
116
117 Description: Start of read thread.
118
119 Arguments: None
120
121 Returns: None
122 *---------------------------------------------------------------------------*/
123
ReadThreadStart(void)124 void ReadThreadStart(void)
125 {
126 if (ReadThreadCreated)
127 {
128 OSResumeThread(&ReadThread);
129 }
130
131 return;
132 }
133
134 /*---------------------------------------------------------------------------*
135 Name: ReadThreadCancel
136
137 Description: Cancel of read thread.
138
139 Arguments: None
140
141 Returns: None
142 *---------------------------------------------------------------------------*/
143
ReadThreadCancel(void)144 void ReadThreadCancel(void)
145 {
146 if (ReadThreadCreated)
147 {
148 OSCancelThread(&ReadThread);
149
150 ReadThreadCreated = 0;
151 }
152
153 return;
154 }
155
156 /*---------------------------------------------------------------------------*
157 Name: Reader
158
159 Description: Read process for streaming playback
160
161 Arguments: None
162
163 Returns: None
164 *---------------------------------------------------------------------------*/
165
Reader(void * ptr)166 static void *Reader(void *ptr)
167 {
168 #pragma unused(ptr)
169 THPReadBuffer *readBuffer;
170 s32 offset;
171 s32 size;
172 s32 readFrame;
173 s32 result;
174 s32 frameNumber;
175
176 readFrame = 0;
177 offset = ActivePlayer.initOffset;
178 size = ActivePlayer.initReadSize;
179
180 while(1)
181 {
182 readBuffer = PopFreeReadBuffer();
183
184 result = DVDRead(&ActivePlayer.fileInfo, readBuffer->ptr, size, offset);
185
186 // FATAL error during cancel
187 if (result != size)
188 {
189 if (result == DVD_RESULT_FATAL_ERROR)
190 {
191 ActivePlayer.dvdError = DVD_RESULT_FATAL_ERROR;
192 }
193
194 if (readFrame == 0)
195 {
196 PrepareReady(FALSE);
197 }
198
199 OSSuspendThread(&ReadThread);
200 }
201
202 readBuffer->frameNumber = readFrame;
203
204 PushReadedBuffer(readBuffer);
205
206 offset += size;
207 size = NEXT_READ_SIZE(readBuffer);
208
209 // Calculate current frame # from quantity read
210 frameNumber = (s32)((readFrame + ActivePlayer.initReadFrame)
211 % ActivePlayer.header.numFrames);
212
213 // Check THP movie end
214 if (frameNumber == ActivePlayer.header.numFrames - 1)
215 {
216 // If loop playback, at beginning of movie data
217 if (ActivePlayer.playFlag & THP_PLAY_LOOP)
218 {
219 offset = (s32)(ActivePlayer.header.movieDataOffsets);
220 }
221 // Stop decoding if one shot playback
222 else
223 {
224 OSSuspendThread(&ReadThread);
225 }
226 }
227
228 readFrame++;
229 }
230
231 return NULL;
232 }
233
234 /*---------------------------------------------------------------------------*
235 Name: PopReadedBuffer
236
237 Description: Acquire the buffer where the THP frame is stored.
238
239 Arguments: None
240
241 Returns: Pointer for buffer where the THP frame is stored.
242 *---------------------------------------------------------------------------*/
243
PopReadedBuffer()244 void *PopReadedBuffer()
245 {
246 OSMessage msg;
247
248 OSReceiveMessage(&ReadedBufferQueue, &msg, OS_MESSAGE_BLOCK);
249
250 return msg;
251 }
252
253 /*---------------------------------------------------------------------------*
254 Name: PushReadedBuffer
255
256 Description: Pushes the buffer where the THP frame is stored to queue.
257
258 Arguments: buffer Pointer for buffer where read is completed
259
260 Returns: None
261 *---------------------------------------------------------------------------*/
262
PushReadedBuffer(void * buffer)263 void PushReadedBuffer(void *buffer)
264 {
265 OSSendMessage(&ReadedBufferQueue, buffer, OS_MESSAGE_BLOCK);
266
267 return;
268 }
269
270 /*---------------------------------------------------------------------------*
271 Name: PopFreeReadBuffer
272
273 Description: Acquire free read buffers
274
275 Arguments: None
276
277 Returns: Pointer for read buffer
278 *---------------------------------------------------------------------------*/
279
PopFreeReadBuffer()280 void *PopFreeReadBuffer()
281 {
282 OSMessage msg;
283
284 OSReceiveMessage(&FreeReadBufferQueue, &msg, OS_MESSAGE_BLOCK);
285
286 return msg;
287 }
288
289 /*---------------------------------------------------------------------------*
290 Name: PushFreeReadBuffer
291
292 Description: Free used read buffers
293
294 Arguments: buffer Pointer for free read buffers
295
296 Returns: None
297 *---------------------------------------------------------------------------*/
298
PushFreeReadBuffer(void * buffer)299 void PushFreeReadBuffer(void *buffer)
300 {
301 OSSendMessage(&FreeReadBufferQueue, buffer, OS_MESSAGE_BLOCK);
302
303 return;
304 }
305
306 /*---------------------------------------------------------------------------*
307 Name: PopReadedBuffer2
308
309 Description: Acquire read buffer passed from audio decode thread
310 Called from video decode thread.
311
312 Arguments: None
313
314 Returns: Pointer for read buffer
315 *---------------------------------------------------------------------------*/
316
PopReadedBuffer2()317 void *PopReadedBuffer2()
318 {
319 OSMessage msg;
320
321 OSReceiveMessage(&ReadedBufferQueue2, &msg, OS_MESSAGE_BLOCK);
322
323 return msg;
324 }
325
326 /*---------------------------------------------------------------------------*
327 Name: PushReadedBuffer2
328
329 Description: Passes read buffer to video decode thread.
330
331 Arguments: Pointer for read buffer.
332
333 Returns: None
334 *---------------------------------------------------------------------------*/
335
PushReadedBuffer2(void * buffer)336 void PushReadedBuffer2(void *buffer)
337 {
338 OSSendMessage(&ReadedBufferQueue2, buffer, OS_MESSAGE_BLOCK);
339
340 return;
341 }
342