mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #13659 from shenweip/mpeg-multi_streams
Mpeg:Improves the support of multiple streams video.
This commit is contained in:
commit
e01d538707
3 changed files with 66 additions and 13 deletions
|
@ -667,6 +667,7 @@ static int sceMpegRegistStream(u32 mpeg, u32 streamType, u32 streamNum)
|
|||
switch (streamType) {
|
||||
case MPEG_AVC_STREAM:
|
||||
ctx->avcRegistered = true;
|
||||
ctx->mediaengine->addVideoStream(streamNum);
|
||||
// TODO: Probably incorrect?
|
||||
ctx->mediaengine->setVideoStream(streamNum);
|
||||
break;
|
||||
|
@ -1495,6 +1496,9 @@ void PostPutAction::run(MipsCall &call) {
|
|||
// Program signals that it has written data to the ringbuffer and gets a callback ?
|
||||
static u32 sceMpegRingbufferPut(u32 ringbufferAddr, int numPackets, int available)
|
||||
{
|
||||
// Generally, program will call sceMpegRingbufferAvailableSize() before this func.
|
||||
// Still need to check available?
|
||||
|
||||
numPackets = std::min(numPackets, available);
|
||||
if (numPackets <= 0) {
|
||||
DEBUG_LOG(ME, "sceMpegRingbufferPut(%08x, %i, %i): no packets to enqueue", ringbufferAddr, numPackets, available);
|
||||
|
@ -1518,15 +1522,21 @@ static u32 sceMpegRingbufferPut(u32 ringbufferAddr, int numPackets, int availabl
|
|||
if (ringbuffer->callback_addr != 0) {
|
||||
DEBUG_LOG(ME, "sceMpegRingbufferPut(%08x, %i, %i)", ringbufferAddr, numPackets, available);
|
||||
|
||||
PostPutAction *action = (PostPutAction *)__KernelCreateAction(actionPostPut);
|
||||
action->setRingAddr(ringbufferAddr);
|
||||
// TODO: Should call this multiple times until we get numPackets.
|
||||
// Call this multiple times until we get numPackets.
|
||||
// Normally this would be if it did not read enough, but also if available > packets.
|
||||
// Should ultimately return the TOTAL number of returned packets.
|
||||
int writeOffset = ringbuffer->packetsWritePos % (s32)ringbuffer->packets;
|
||||
u32 packetsThisRound = std::min(numPackets, (s32)ringbuffer->packets - writeOffset);
|
||||
u32 args[3] = {(u32)ringbuffer->data + (u32)writeOffset * 2048, packetsThisRound, (u32)ringbuffer->callback_args};
|
||||
hleEnqueueCall(ringbuffer->callback_addr, 3, args, action);
|
||||
u32 packetsThisRound = 0;
|
||||
while (numPackets) {
|
||||
PostPutAction *action = (PostPutAction *)__KernelCreateAction(actionPostPut);
|
||||
action->setRingAddr(ringbufferAddr);
|
||||
|
||||
packetsThisRound = std::min(numPackets, (s32)ringbuffer->packets - writeOffset);
|
||||
numPackets -= packetsThisRound;
|
||||
u32 args[3] = { (u32)ringbuffer->data + (u32)writeOffset * 2048, packetsThisRound, (u32)ringbuffer->callback_args };
|
||||
hleEnqueueCall(ringbuffer->callback_addr, 3, args, action);
|
||||
writeOffset = (writeOffset + packetsThisRound) % (s32)ringbuffer->packets;
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG_REPORT(ME, "sceMpegRingbufferPut: callback_addr zero");
|
||||
}
|
||||
|
|
|
@ -132,6 +132,8 @@ MediaEngine::MediaEngine(): m_pdata(0) {
|
|||
m_videoStream = -1;
|
||||
m_audioStream = -1;
|
||||
|
||||
m_expectedVideoStreams = 0;
|
||||
|
||||
m_desWidth = 0;
|
||||
m_desHeight = 0;
|
||||
m_decodingsize = 0;
|
||||
|
@ -169,7 +171,7 @@ void MediaEngine::closeMedia() {
|
|||
}
|
||||
|
||||
void MediaEngine::DoState(PointerWrap &p) {
|
||||
auto s = p.Section("MediaEngine", 1, 5);
|
||||
auto s = p.Section("MediaEngine", 1, 6);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
|
@ -187,6 +189,11 @@ void MediaEngine::DoState(PointerWrap &p) {
|
|||
} else {
|
||||
m_mpegheaderReadPos = m_mpegheaderSize;
|
||||
}
|
||||
if (s >= 6) {
|
||||
Do(p, m_expectedVideoStreams);
|
||||
} else {
|
||||
m_expectedVideoStreams = 0;
|
||||
}
|
||||
|
||||
Do(p, m_ringbuffersize);
|
||||
|
||||
|
@ -258,20 +265,22 @@ bool MediaEngine::SetupStreams() {
|
|||
}
|
||||
|
||||
// Looking good. Let's add those streams.
|
||||
const AVCodec *h264_codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||
int videoStreamNum = -1;
|
||||
for (int i = 0; i < numStreams; i++) {
|
||||
const u8 *const currentStreamAddr = m_mpegheader + 0x82 + i * 16;
|
||||
int streamId = currentStreamAddr[0];
|
||||
|
||||
// We only set video streams. We demux the audio stream separately.
|
||||
if ((streamId & PSMF_VIDEO_STREAM_ID) == PSMF_VIDEO_STREAM_ID) {
|
||||
AVStream *stream = avformat_new_stream(m_pFormatCtx, h264_codec);
|
||||
stream->id = 0x00000100 | streamId;
|
||||
stream->request_probe = 0;
|
||||
stream->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
// We could set the width here, but we don't need to.
|
||||
++videoStreamNum;
|
||||
addVideoStream(videoStreamNum, streamId);
|
||||
}
|
||||
}
|
||||
// Add the streams to meet the expectation.
|
||||
for (int i = videoStreamNum + 1; i < m_expectedVideoStreams; i++) {
|
||||
addVideoStream(i);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
return true;
|
||||
|
@ -386,6 +395,38 @@ bool MediaEngine::reloadStream()
|
|||
return loadStream(m_mpegheader, 2048, m_ringbuffersize);
|
||||
}
|
||||
|
||||
bool MediaEngine::addVideoStream(int streamNum, int streamId) {
|
||||
#ifdef USE_FFMPEG
|
||||
if (m_pFormatCtx) {
|
||||
// no need to add an existing stream.
|
||||
if ((u32)streamNum < m_pFormatCtx->nb_streams)
|
||||
return true;
|
||||
const AVCodec *h264_codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||
if (!h264_codec)
|
||||
return false;
|
||||
AVStream *stream = avformat_new_stream(m_pFormatCtx, h264_codec);
|
||||
if (stream) {
|
||||
// Reference ISO/IEC 13818-1.
|
||||
if (streamId == -1)
|
||||
streamId = PSMF_VIDEO_STREAM_ID | streamNum;
|
||||
|
||||
stream->id = 0x00000100 | streamId;
|
||||
stream->request_probe = 0;
|
||||
stream->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
// We could set the width here, but we don't need to.
|
||||
if (streamNum >= m_expectedVideoStreams) {
|
||||
++m_expectedVideoStreams;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (streamNum >= m_expectedVideoStreams) {
|
||||
++m_expectedVideoStreams;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MediaEngine::addStreamData(const u8 *buffer, int addSize) {
|
||||
int size = addSize;
|
||||
if (size > 0 && m_pdata) {
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
void closeMedia();
|
||||
bool loadStream(const u8 *buffer, int readSize, int RingbufferSize);
|
||||
bool reloadStream();
|
||||
bool addVideoStream(int streamNum, int streamId = -1);
|
||||
// open the mpeg context
|
||||
bool openContext(bool keepReadPos = false);
|
||||
void closeContext();
|
||||
|
@ -114,6 +115,7 @@ public: // TODO: Very little of this below should be public.
|
|||
int m_sws_fmt;
|
||||
u8 *m_buffer;
|
||||
int m_videoStream;
|
||||
int m_expectedVideoStreams;
|
||||
|
||||
// Used by the demuxer.
|
||||
int m_audioStream;
|
||||
|
|
Loading…
Add table
Reference in a new issue