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