diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index e62afc50d5..a1df84ff6d 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1019,6 +1019,8 @@ int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) return -1; } + ctx->mediaengine->setVideoStream(streamInfo->second.num); + if (streamInfo->second.needsReset) { sceAu.pts = 0; @@ -1099,6 +1101,10 @@ int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr) sceAu.pts = 0; streamInfo->second.needsReset = false; } + if (streamInfo != ctx->streamMap.end()) + ctx->mediaengine->setAudioStream(streamInfo->second.num); + else + WARN_LOG_REPORT(ME, "sceMpegGetAtracAu: invalid audio stream %08x", streamId); // The audio can end earlier than the video does. if (mpegRingbuffer.packetsFree == mpegRingbuffer.packets) { @@ -1245,7 +1251,7 @@ u32 sceMpegAvcCopyYCbCr(u32 mpeg, u32 sourceAddr, u32 YCbCrAddr) u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init) { - DEBUG_LOG(ME, "UNIMPL sceMpegAtracDecode(%08x, %08x, %08x, %i)", mpeg, auAddr, bufferAddr, init); + DEBUG_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i)", mpeg, auAddr, bufferAddr, init); MpegContext *ctx = getMpegCtx(mpeg); if (!ctx) { diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp index d6ce76a8aa..79570d8c8f 100644 --- a/Core/HW/MediaEngine.cpp +++ b/Core/HW/MediaEngine.cpp @@ -266,19 +266,9 @@ bool MediaEngine::openContext() { return false; } - // Get a pointer to the codec context for the video stream - m_pCodecCtx = m_pFormatCtx->streams[m_videoStream]->codec; - - // Find the decoder for the video stream - AVCodec *pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id); - if(pCodec == NULL) + if (!setVideoStream(m_videoStream, true)) return false; - // Open codec - AVDictionary *optionsDict = 0; - if(avcodec_open2(m_pCodecCtx, pCodec, &optionsDict)<0) - return false; // Could not open codec - setVideoDim(); m_audioContext = AT3Create(); m_isVideoEnd = false; @@ -341,7 +331,6 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) { size = 0; if (m_demux) { m_demux->addStreamData(buffer, addSize); - m_demux->demux(m_audioStream); } #ifdef USE_FFMPEG if (!m_pFormatCtx && m_pdata->getQueueSize() >= 2048) { @@ -358,6 +347,39 @@ int MediaEngine::addStreamData(u8* buffer, int addSize) { return size; } +bool MediaEngine::setVideoStream(int streamNum, bool force) { + if (m_videoStream == streamNum && !force) { + // Yay, nothing to do. + return true; + } + + m_videoStream = streamNum; +#ifdef USE_FFMPEG + if (m_pFormatCtx) { + if (m_pCodecCtx) { + avcodec_close(m_pCodecCtx); + } + + // Get a pointer to the codec context for the video stream + m_pCodecCtx = m_pFormatCtx->streams[m_videoStream]->codec; + + // Find the decoder for the video stream + AVCodec *pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id); + if (pCodec == NULL) { + return false; + } + + // Open codec + AVDictionary *optionsDict = 0; + if (avcodec_open2(m_pCodecCtx, pCodec, &optionsDict) < 0) { + return false; // Could not open codec + } + } +#endif + + return true; +} + bool MediaEngine::setVideoDim(int width, int height) { #ifdef USE_FFMPEG @@ -670,6 +692,10 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) { if (!m_demux) { return 0; } + + // Demux now (rather than on add data) so that we select the right stream. + m_demux->demux(m_audioStream); + u8 *audioFrame = 0; int headerCode1, headerCode2; int frameSize = m_demux->getNextaudioFrame(&audioFrame, &headerCode1, &headerCode2); diff --git a/Core/HW/MediaEngine.h b/Core/HW/MediaEngine.h index 3969f5901a..4e9c6dc6f2 100644 --- a/Core/HW/MediaEngine.h +++ b/Core/HW/MediaEngine.h @@ -65,7 +65,7 @@ public: // Returns number of packets actually added. I guess the buffer might be full. int addStreamData(u8* buffer, int addSize); - void setVideoStream(int streamNum) { m_videoStream = streamNum; } + bool setVideoStream(int streamNum, bool force = false); void setAudioStream(int streamNum) { m_audioStream = streamNum; } u8 *getFrameImage();