ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
mpeg.c File Reference
#include "libmpeg.h"
#include <dma_tags.h>
#include <gif_tags.h>
#include <gs_psm.h>
#include <gs_gp.h>
#include <kernel.h>
#include <dma.h>
#include <draw.h>
#include <fileio.h>
#include <malloc.h>
#include <graph.h>
#include <packet.h>
#include <stdio.h>
+ Include dependency graph for mpeg.c:

Go to the source code of this file.

Data Structures

struct  InitCBParam
 

Macros

#define MPEG_BITSTREAM_FILE   "host:test.bin"
 
#define MAX_SIZE   ( 1024 * 1024 * 24 )
 

Functions

static int SetDMA (void *)
 
static void * InitCB (void *, MPEGSequenceInfo *)
 
int main (void)
 

Variables

static unsigned char * s_pMPEGData
 
static unsigned char * s_pTransferPtr
 
static unsigned int s_MPEGDataSize
 

Macro Definition Documentation

◆ MAX_SIZE

#define MAX_SIZE   ( 1024 * 1024 * 24 )

Definition at line 36 of file mpeg.c.

◆ MPEG_BITSTREAM_FILE

#define MPEG_BITSTREAM_FILE   "host:test.bin"

Definition at line 34 of file mpeg.c.

Function Documentation

◆ InitCB()

static void * InitCB ( void *  apParam,
MPEGSequenceInfo apInfo 
)
static

Definition at line 218 of file mpeg.c.

218  {
219 
220  int lDataSize = apInfo -> m_Width * apInfo -> m_Height * 4;
221  char* retVal = ( char* )malloc ( lDataSize );
222  InitCBParam* lpParam = ( InitCBParam* )apParam;
223  int lMBW = ( apInfo -> m_Width ) >> 4;
224  int lMBH = ( apInfo -> m_Height ) >> 4;
225  int lTBW = ( apInfo -> m_Width + 63 ) >> 6;
226  int lTW = draw_log2 ( apInfo -> m_Width );
227  int lTH = draw_log2 ( apInfo -> m_Height );
228  int lX, lY;
229  char* lpImg;
230  qword_t* q;
231 
232  lpParam -> m_TexAddr >>= 6;
233 
234  lpParam -> m_pData = lpImg = retVal;
235  lpParam -> m_pInfo = apInfo;
236  SyncDCache ( retVal, retVal + lDataSize );
237 /* This initializes picture transfer packet. */
238 /* Decoded picture is a sequence of 16x16 pixels */
239 /* 'subpictures' (macroblocks) and DMA controller */
240 /* will transfer them all at once using source */
241 /* chain transfer mode. */
242  lpParam -> m_XFerPck = packet_init((10 + 12 * lMBW * lMBH )>>1,PACKET_NORMAL);
243 
244  q = lpParam-> m_XFerPck -> data;
245 
246  DMATAG_CNT(q, 3, 0, 0, 0);
247  q++;
248  PACK_GIFTAG(q,GIF_SET_TAG( 2, 0, 0, 0, 0, 1 ),GIF_REG_AD);
249  q++;
251  q++;
252  PACK_GIFTAG(q,GS_SET_BITBLTBUF( 0, 0, 0, lpParam -> m_TexAddr, lTBW, GS_PSM_32 ), GS_REG_BITBLTBUF);
253  q++;
254 
255  for ( lY = 0; lY < apInfo -> m_Height; lY += 16 ) {
256  for ( lX = 0; lX < apInfo -> m_Width; lX += 16, lpImg += 1024 ) {
257  DMATAG_CNT(q, 4, 0, 0, 0 );
258  q++;
259  PACK_GIFTAG(q,GIF_SET_TAG( 2, 0, 0, 0, 0, 1 ), GIF_REG_AD );
260  q++;
261  PACK_GIFTAG(q,GS_SET_TRXPOS( 0, 0, lX, lY, 0 ), GS_REG_TRXPOS );
262  q++;
264  q++;
265  PACK_GIFTAG(q,GIF_SET_TAG( 64, 1, 0, 0, 2, 0),0);
266  q++;
267  DMATAG_REF(q, 64, ( unsigned )lpImg, 0, 0, 0);
268  q++;
269  } /* end for */
270  } /* end for */
271 
272  //DMATAG_END(q,0,0,0,0);
273  //q++;
274 
275  lpParam-> m_XFerPck -> qwc = q - lpParam-> m_XFerPck -> data;
276 
277 /* This initializes picture drawing packet. Just textrured sprite */
278 /* that occupies the whole screen (no aspect ratio is taken into */
279 /* account for simplicity. */
280  lpParam -> m_DrawPck = packet_init(7,PACKET_NORMAL);
281  q = lpParam -> m_DrawPck -> data;
282  PACK_GIFTAG(q, GIF_SET_TAG( 6, 1, 0, 0, 0, 1 ), GIF_REG_AD );
283  q++;
284  PACK_GIFTAG(q, GS_SET_TEX0( lpParam -> m_TexAddr, lTBW, GS_PSM_32, lTW, lTH, 1, 1, 0, 0, 0, 0, 0 ), GS_REG_TEX0_1 );
285  q++;
286  PACK_GIFTAG(q, GS_SET_PRIM( 6, 0, 1, 0, 0, 0, 1, 0, 0 ), GS_REG_PRIM );
287  q++;
288  PACK_GIFTAG(q, GS_SET_UV( 0, 0 ), GS_REG_UV );
289  q++;
290  PACK_GIFTAG(q, GS_SET_XYZ( 0, 0, 0 ), GS_REG_XYZ2 );
291  q++;
292  PACK_GIFTAG(q, GS_SET_UV( apInfo -> m_Width << 4, apInfo -> m_Height << 4 ), GS_REG_UV );
293  q++;
294  PACK_GIFTAG(q, GS_SET_XYZ( (640 << 4) + (2048 << 4), (512 << 4) + (2048 << 4), 0 ), GS_REG_XYZ2 );
295  q++;
296 
297  lpParam -> m_DrawPck -> qwc = q - lpParam -> m_DrawPck -> data;
298 
299  return retVal;
300 
301 } /* end InitCB */
#define DMATAG_REF(Q, QWC, ADDR, SPR, W2, W3)
Definition: dma_tags.h:93
#define DMATAG_CNT(Q, QWC, SPR, W2, W3)
Definition: dma_tags.h:57
unsigned char draw_log2(unsigned int x)
Definition: draw.c:348
#define PACK_GIFTAG(Q, D0, D1)
Definition: gif_tags.h:76
#define GIF_SET_TAG(NLOOP, EOP, PRE, PRIM, FLG, NREG)
Definition: gif_tags.h:80
#define GIF_REG_AD
Definition: gif_tags.h:72
#define GS_REG_TEX0_1
Definition: gs_gp.h:27
#define GS_SET_XYZ(X, Y, Z)
Definition: gs_gp.h:326
#define GS_SET_TRXREG(W, H)
Definition: gs_gp.h:317
#define GS_REG_TRXREG
Definition: gs_gp.h:135
#define GS_SET_PRIM(PRIM, IIP, TME, FGE, ABE, AA1, FST, CTXT, FIX)
Definition: gs_gp.h:237
#define GS_SET_BITBLTBUF(SBA, SBW, SPSM, DBA, DBW, DPSM)
Definition: gs_gp.h:175
#define GS_SET_TRXPOS(SX, SY, DX, DY, DIR)
Definition: gs_gp.h:312
#define GS_SET_TEX0(TBA, TBW, PSM, TW, TH, TCC, TFNCT, CBA, CPSM, CSM, CSA, CLD)
Definition: gs_gp.h:281
#define GS_REG_PRIM
Definition: gs_gp.h:13
#define GS_REG_XYZ2
Definition: gs_gp.h:23
#define GS_REG_UV
Definition: gs_gp.h:19
#define GS_REG_TRXPOS
Definition: gs_gp.h:133
#define GS_REG_BITBLTBUF
Definition: gs_gp.h:131
#define GS_SET_UV(U, V)
Definition: gs_gp.h:320
#define GS_REG_TRXDIR
Definition: gs_gp.h:137
#define GS_SET_TRXDIR(DIR)
Definition: gs_gp.h:308
#define GS_PSM_32
Definition: gs_psm.h:11
void SyncDCache(void *start, void *end)
u32 data
Definition: libmouse.c:36
packet_t * packet_init(int qwords, int type)
Definition: packet.c:8
#define PACKET_NORMAL
Definition: packet.h:14

References data, DMATAG_CNT, DMATAG_REF, draw_log2(), GIF_REG_AD, GIF_SET_TAG, GS_PSM_32, GS_REG_BITBLTBUF, GS_REG_PRIM, GS_REG_TEX0_1, GS_REG_TRXDIR, GS_REG_TRXPOS, GS_REG_TRXREG, GS_REG_UV, GS_REG_XYZ2, GS_SET_BITBLTBUF, GS_SET_PRIM, GS_SET_TEX0, GS_SET_TRXDIR, GS_SET_TRXPOS, GS_SET_TRXREG, GS_SET_UV, GS_SET_XYZ, PACK_GIFTAG, packet_init(), PACKET_NORMAL, and SyncDCache().

Referenced by main().

◆ main()

int main ( void  )

Definition at line 55 of file mpeg.c.

55  {
56 /* read file (or part of it ) into memory */
57  packet_t *lPck;
58  qword_t *q;
59  framebuffer_t frame;
60  zbuffer_t z;
61  InitCBParam lInfo;
62  int lFD = open ( MPEG_BITSTREAM_FILE, O_RDONLY );
63  long lSize;
64  s64 lPTS, lCurPTS;
65 
66  frame.width = 640;
67  frame.height = 512;
68  frame.mask = 0;
69  frame.psm = GS_PSM_32;
70  frame.address = graph_vram_allocate(frame.width,frame.height, frame.psm, GRAPH_ALIGN_PAGE);
71 
72  z.enable = 0;
73  z.mask = 0;
74  z.method = 0;
75  z.zsm = 0;
76  z.address = 0;
77 
78  lPck = packet_init(100, PACKET_NORMAL);
79 
80  if ( lFD < 0 ) {
81  printf ( "test_mpeg: could not open '%s'\n", MPEG_BITSTREAM_FILE );
82  goto end;
83  } /* end if */
84 
85  lSize = lseek ( lFD, 0, SEEK_END );
86  lseek ( lFD, 0, SEEK_SET );
87 
88  if ( lSize <= 0 ) {
89  printf ( "test_mpeg: could not obtain file size (%ld)\n", lSize );
90  goto end;
91  } /* end if */
92 
93  s_pMPEGData = ( unsigned char* )malloc ( lSize = lSize > MAX_SIZE ? MAX_SIZE : lSize );
94 
95  if ( !s_pMPEGData ) {
96  printf ( "test_mpeg: could not allocate enough memory (%ld)\n", lSize );
97  goto end;
98  } /* end if */
99 
100  if ( read (
102  ) != lSize
103  ) {
104  printf ( "test_mpeg: could not read file\n" );
105  goto end;
106  } /* end if */
107 
108  close ( lFD );
109 
110 /* initialize DMAC (I have no idea what this code does as */
111 /* I'm not quite familiar with ps2sdk) */
115 
116 /* initialize graphics synthesizer */
117  graph_initialize(0,640,512,GS_PSM_32,0,0);
118 
119 /* setup texture buffer address just after the framebuffer */
121 
122  q = lPck->data;
123  q = draw_setup_environment(q,0,&frame,&z);
124 
125 /* clear screen */
126  q = draw_clear(q,0,0,0,640.0f,512.0f,0,0,0);
127 
128  dma_channel_send_normal(DMA_CHANNEL_GIF, lPck->data, q - lPck->data, 0, 0);
129 
130 /* now it's time to initialize MPEG decoder (though it can be */
131 /* initialized any time). Just make sure that DMA transfers */
132 /* to and from IPU (and DRAM -> SPR) are not active, otherwise */
133 /* unpredicted things will happen. Initialization code is also */
134 /* allocating some memory using 'memalign' function and no */
135 /* check is performed whether the allocation was successful or */
136 /* not, so, before calling this make sure that at least WxHx4x3 */
137 /* bytes are avaliable for dynamic allocation (possibly using */
138 /* ps2_sbrk ( 0 ) call) where W and H are picture dimensions in */
139 /* units of pixels. */
140  MPEG_Initialize ( SetDMA, NULL, InitCB, &lInfo, &lCurPTS );
141 /* during decoding scratchpad RAM from address 0x0000 to 0x3C00 */
142 /* is used by the decoder. */
143 /* let's go */
144  while ( 1 ) {
145 /* try decode picture into "lInfo.m_pData" area. It's allowed */
146 /* to supply different area each time, just make sure that */
147 /* there're no conflicts with data cache, as decoder doesn't do */
148 /* anything to synchronize/flush/invalidate data cache. */
149 /* RGB -> YUV colorspace conversion is pefromed automatically */
150 /* using interrupt hahdler/semaphore, so, multithreaded */
151 /* application can benefit from it. Usage of IPU and DMA channels */
152 /* to/from IPU and DRAM -> SPR is strictly forbidden during */
153 /* decoding :). */
154  if ( !MPEG_Picture ( lInfo.m_pData, &lPTS ) ) {
155 /* MPEG_Picture returns nonzero if the picture was successfully */
156 /* decoded. Zero return means one of the following: */
157 /* - end of stream was detected (SetDMA function returned zero) */
158 /* - MPEG sequence end code (0x000001B7) was detected */
159 /* this test just finishes in both cases */
160  if ( lInfo.m_pInfo -> m_fEOF ) break;
161 /* ...instead of 'break' we can continue to the next sequence...*/
162 /* ...but I'm too lazy to handle second call of 'InitCB' :D */
163  else break;
164  } /* end if */
165 /* now transfer decoded picture data into texture area of GS RAM */
166  dma_wait_fast();
167  dma_channel_send_chain( DMA_CHANNEL_GIF, lInfo.m_XFerPck -> data, lInfo.m_XFerPck -> qwc, 0, 0);
168 /* wait for vsync 2 times (we have interlaced frame mode) */
169  graph_wait_vsync ();
170  graph_wait_vsync ();
171 /* no need to wait for DMA transfer completion since vsyncs above */
172 /* have enough lattency... */
173 /* ...and finally draw decoded picture... */
174  dma_channel_send_normal( DMA_CHANNEL_GIF, lInfo.m_DrawPck -> data, lInfo.m_DrawPck -> qwc, 0, 0);
175 /* ...and go back for the next one */
176  } /* end while */
177 /* free memory and other resources */
178  MPEG_Destroy ();
179 
180 end:
181  printf ( "test_mpeg: test finished\n" );
182  return SleepThread (), 0;
183 
184 } /* end main */
void dma_wait_fast(void)
Definition: dma.c:115
int dma_channel_send_normal(int channel, void *data, int qwc, int flags, int spr)
Definition: dma.c:238
#define DMA_CHANNEL_toIPU
Definition: dma.h:26
int dma_channel_initialize(int channel, void *handler, int flags)
Definition: dma.c:58
#define DMA_CHANNEL_GIF
Definition: dma.h:24
void dma_channel_fast_waits(int channel)
Definition: dma.c:108
int dma_channel_send_chain(int channel, void *data, int qwc, int flags, int spr)
Definition: dma.c:184
qword_t * draw_setup_environment(qword_t *q, int context, framebuffer_t *frame, zbuffer_t *z)
Definition: draw.c:11
qword_t * draw_clear(qword_t *q, int context, float x, float y, float width, float height, int r, int g, int b)
Definition: draw.c:148
int graph_initialize(int fbp, int width, int height, int psm, int x, int y)
Definition: graph.c:6
void graph_wait_vsync(void)
Definition: graph.c:99
#define GRAPH_ALIGN_BLOCK
Definition: graph_vram.h:16
int graph_vram_allocate(int width, int height, int psm, int alignment)
Definition: graph_vram.c:7
#define GRAPH_ALIGN_PAGE
Definition: graph_vram.h:13
s32 SleepThread(void)
void MPEG_Destroy(void)
Definition: libmpeg.c:117
int(* MPEG_Picture)(void *, s64 *)
Definition: libmpeg.h:62
void MPEG_Initialize(int(*)(void *), void *, void *(*)(void *, MPEGSequenceInfo *), void *, s64 *)
#define MAX_SIZE
Definition: mpeg.c:36
static unsigned char * s_pTransferPtr
Definition: mpeg.c:49
static int SetDMA(void *)
Definition: mpeg.c:193
static void * InitCB(void *, MPEGSequenceInfo *)
Definition: mpeg.c:218
static unsigned char * s_pMPEGData
Definition: mpeg.c:48
#define MPEG_BITSTREAM_FILE
Definition: mpeg.c:34
static unsigned int s_MPEGDataSize
Definition: mpeg.c:50
int m_TexAddr
Definition: mpeg.c:44
MPEGSequenceInfo * m_pInfo
Definition: mpeg.c:40
packet_t * m_DrawPck
Definition: mpeg.c:43
packet_t * m_XFerPck
Definition: mpeg.c:42
void * m_pData
Definition: mpeg.c:41
unsigned int address
Definition: draw_buffers.h:41
unsigned int height
Definition: draw_buffers.h:43
unsigned int psm
Definition: draw_buffers.h:44
unsigned int mask
Definition: draw_buffers.h:45
unsigned int width
Definition: draw_buffers.h:42
qword_t * data
Definition: packet.h:27
unsigned int mask
Definition: draw_buffers.h:53
unsigned int method
Definition: draw_buffers.h:50
unsigned int address
Definition: draw_buffers.h:51
unsigned int enable
Definition: draw_buffers.h:49
unsigned int zsm
Definition: draw_buffers.h:52
#define NULL
Definition: tamtypes.h:91
signed long s64
Definition: tamtypes.h:62

References framebuffer_t::address, zbuffer_t::address, packet_t::data, data, dma_channel_fast_waits(), DMA_CHANNEL_GIF, dma_channel_initialize(), dma_channel_send_chain(), dma_channel_send_normal(), DMA_CHANNEL_toIPU, dma_wait_fast(), draw_clear(), draw_setup_environment(), zbuffer_t::enable, GRAPH_ALIGN_BLOCK, GRAPH_ALIGN_PAGE, graph_initialize(), graph_vram_allocate(), graph_wait_vsync(), GS_PSM_32, framebuffer_t::height, InitCB(), InitCBParam::m_DrawPck, InitCBParam::m_pData, InitCBParam::m_pInfo, InitCBParam::m_TexAddr, InitCBParam::m_XFerPck, framebuffer_t::mask, zbuffer_t::mask, MAX_SIZE, zbuffer_t::method, MPEG_BITSTREAM_FILE, MPEG_Destroy(), MPEG_Initialize(), MPEG_Picture, NULL, packet_init(), PACKET_NORMAL, framebuffer_t::psm, s_MPEGDataSize, s_pMPEGData, s_pTransferPtr, SetDMA(), SleepThread(), framebuffer_t::width, and zbuffer_t::zsm.

◆ SetDMA()

static int SetDMA ( void *  apUserData)
static

Definition at line 193 of file mpeg.c.

193  {
194 
195  if ( s_pTransferPtr - s_pMPEGData >= s_MPEGDataSize ) return 0;
196 
199  DMA_CHANNEL_toIPU, s_pTransferPtr, 2048>>4, 0, 0
200  );
201  s_pTransferPtr += 2048;
202 
203  return 1;
204 
205 } /* end SetDMA */
int dma_channel_wait(int channel, int timeout)
Definition: dma.c:130

References dma_channel_send_normal(), DMA_CHANNEL_toIPU, dma_channel_wait(), s_MPEGDataSize, s_pMPEGData, and s_pTransferPtr.

Referenced by main().

Variable Documentation

◆ s_MPEGDataSize

unsigned int s_MPEGDataSize
static

Definition at line 50 of file mpeg.c.

Referenced by main(), and SetDMA().

◆ s_pMPEGData

unsigned char* s_pMPEGData
static

Definition at line 48 of file mpeg.c.

Referenced by main(), and SetDMA().

◆ s_pTransferPtr

unsigned char* s_pTransferPtr
static

Definition at line 49 of file mpeg.c.

Referenced by main(), and SetDMA().