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