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