|
Nugget
Bare-metal libraries and examples for the original PlayStation
|
Streams an STR movie off the CD-ROM: MDEC video and interleaved XA audio. More...
#include <psyqo-paths/str-player.hh>
Classes | |
| struct | Options |
| struct | Stats |
Public Types | |
| enum class | Present : uint8_t { STREAM , ASAP } |
| enum class | Status : uint8_t { IDLE , PLAYING , ENDED , FAILED } |
Public Member Functions | |
| StrPlayer (CDRomDevice &cdrom, GPU &gpu) | |
| ~StrPlayer () | |
| bool | play (uint32_t lba, uint32_t sectors, const Options &options) |
| Starts playing the movie in sectors [lba, lba + sectors). | |
| bool | play (uint32_t lba, uint32_t sectors) |
| Status | frame () |
Drives the playback, to be called from the scene's frame(). | |
| void | stop () |
| Stops the playback early. The drive is paused and the buffers freed. | |
| const Stats & | stats () const |
Static Public Member Functions | |
| static uint32_t | heapNeeded (const Options &options) |
The heap play() takes with these options, in bytes. | |
Friends | |
| class | StrStreamAction |
Streams an STR movie off the CD-ROM: MDEC video and interleaved XA audio.
The player only knows about a run of sectors: a start LBA and a sector count. Where they come from is the business of the helpers at the bottom of this file, which resolve an ISO9660 path or an archive entry into that pair.
The sectors are read in one continuous ReadS, at double speed unless a movie made for single speed asks otherwise (Options::doubleSpeed). Video sectors (the 0x0160 chunk magic at the start of their user data) are reassembled into frame slots straight from the CD-ROM interrupt, and XA-ADPCM audio sectors go to the SPU through the drive, without ever touching RAM. Frames are VLC-decoded with bsdec, run through the MDEC one 16-pixel column at a time, and each column is uploaded to VRAM while the next one decodes.
The player draws into psyqo's own double buffer, and presents through the normal frame() / flip cycle: call frame() from the scene's frame(), and it returns once the back buffer holds the next movie frame, so the flip that follows shows it. That means a scene playing a movie does nothing else while it plays, which is what the original libraries did too.
The GPU has to be configured by the application for the depth the player outputs: 24 bits per pixel by default, 15 bits with Options::rgb24 = false. In 24 bits, a 320 pixels wide frame occupies 480 halfwords of VRAM per buffer.
With Options::vramX set, frames go to that one VRAM rectangle instead, always in 15 bits, for a program that draws the movie as a texture: frame() then returns once the rectangle holds the next frame, and the display is left alone.
The CD-ROM device is owned by the player for the duration of the playback.
|
strong |
|
strong |
|
inline |
| psyqo::paths::StrPlayer::~StrPlayer | ( | ) |
| psyqo::paths::StrPlayer::Status psyqo::paths::StrPlayer::frame | ( | ) |
Drives the playback, to be called from the scene's frame().
Blocks until the back buffer holds the next frame to present, then returns PLAYING. Returns ENDED once the stream is exhausted and every frame was shown, FAILED if the drive gave up, and IDLE when not playing.
|
static |
| bool psyqo::paths::StrPlayer::play | ( | uint32_t | lba, |
| uint32_t | sectors | ||
| ) |
| bool psyqo::paths::StrPlayer::play | ( | uint32_t | lba, |
| uint32_t | sectors, | ||
| const Options & | options | ||
| ) |
Starts playing the movie in sectors [lba, lba + sectors).
The CD-ROM device must be idle. Returns false if the buffers could not be allocated. Playback actually happens in frame().
|
inline |
| void psyqo::paths::StrPlayer::stop | ( | ) |
Stops the playback early. The drive is paused and the buffers freed.
Call it from the main loop, between two calls to frame(), never from a callback: it pumps callbacks itself while it waits for the drive.
|
friend |