Skip to content

Commit

Permalink
Revert "Mpeg: Parse video streams from PSMF header."
Browse files Browse the repository at this point in the history
This revert
hrydgard@558b462
  • Loading branch information
sum2012 committed Jun 12, 2018
1 parent b7c2ef5 commit 6760c3d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 67 deletions.
1 change: 1 addition & 0 deletions Core/HLE/sceMpeg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ static void AnalyzeMpeg(u8 *buffer, MpegContext *ctx) {
// TODO: Does this make any sense?
ctx->mediaengine->loadStream(buffer, ctx->mpegOffset, 0);
}
ctx->mediaengine->setVideoDim();
}

// When used with scePsmf, some applications attempt to use sceMpegQueryStreamOffset
Expand Down
92 changes: 28 additions & 64 deletions Core/HW/MediaEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ void MediaEngine::DoState(PointerWrap &p) {
}

if (hasopencontext && p.mode == p.MODE_READ) {
openContext(true);
openContext();
}

p.Do(m_isVideoEnd);
Expand All @@ -234,6 +234,9 @@ static int MpegReadbuffer(void *opaque, uint8_t *buf, int buf_size) {
size = std::min(buf_size, mpeg->m_mpegheaderSize - mpeg->m_mpegheaderReadPos);
memcpy(buf, mpeg->m_mpegheader + mpeg->m_mpegheaderReadPos, size);
mpeg->m_mpegheaderReadPos += size;
}
else if (mpeg->m_mpegheaderReadPos == mpeg->m_mpegheaderSize) {
return 0;
} else {
size = mpeg->m_pdata->pop_front(buf, buf_size);
if (size > 0)
Expand All @@ -242,73 +245,34 @@ static int MpegReadbuffer(void *opaque, uint8_t *buf, int buf_size) {
return size;
}

bool MediaEngine::SetupStreams() {
#ifdef USE_FFMPEG
const u32 magic = *(u32_le *)&m_mpegheader[0];
if (magic != PSMF_MAGIC) {
WARN_LOG_REPORT(ME, "Could not setup streams, bad magic: %08x", magic);
return false;
}
int numStreams = *(u16_be *)&m_mpegheader[0x80];
if (numStreams <= 0 || numStreams > 8) {
// Looks crazy. Let's bail out and let FFmpeg handle it.
WARN_LOG_REPORT(ME, "Could not setup streams, unexpected stream count: %d", numStreams);
return false;
}

// Looking good. Let's add those streams.
const AVCodec *h264_codec = avcodec_find_decoder(AV_CODEC_ID_H264);
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.
}
}

#endif
return true;
}

bool MediaEngine::openContext(bool keepReadPos) {
bool MediaEngine::openContext() {
#ifdef USE_FFMPEG
InitFFmpeg();

if (m_pFormatCtx || !m_pdata)
return false;
if (!keepReadPos) {
m_mpegheaderReadPos = 0;
}
m_mpegheaderReadPos = 0;
m_decodingsize = 0;

m_bufSize = std::max(m_bufSize, m_mpegheaderSize);
u8 *tempbuf = (u8*)av_malloc(m_bufSize);

m_pFormatCtx = avformat_alloc_context();
m_pIOContext = avio_alloc_context(tempbuf, m_bufSize, 0, (void*)this, &MpegReadbuffer, nullptr, nullptr);
m_pIOContext = avio_alloc_context(tempbuf, m_bufSize, 0, (void*)this, MpegReadbuffer, NULL, 0);
m_pFormatCtx->pb = m_pIOContext;

// Open video file
AVDictionary *open_opt = nullptr;
av_dict_set_int(&open_opt, "probesize", m_mpegheaderSize, 0);
if (avformat_open_input((AVFormatContext**)&m_pFormatCtx, nullptr, nullptr, &open_opt) != 0) {
if (avformat_open_input((AVFormatContext**)&m_pFormatCtx, NULL, NULL, &open_opt) != 0) {
av_dict_free(&open_opt);
return false;
}
av_dict_free(&open_opt);

if (!SetupStreams()) {
// Fallback to old behavior.
if (avformat_find_stream_info(m_pFormatCtx, NULL) < 0) {
closeContext();
return false;
}
if (avformat_find_stream_info(m_pFormatCtx, NULL) < 0) {
closeContext();
return false;
}

if (m_videoStream >= (int)m_pFormatCtx->nb_streams) {
Expand All @@ -333,6 +297,8 @@ bool MediaEngine::openContext(bool keepReadPos) {

setVideoDim();
m_audioContext = new SimpleAudio(m_audioType, 44100, 2);
m_mpegheaderReadPos++;

m_isVideoEnd = false;
#endif // USE_FFMPEG
return true;
Expand Down Expand Up @@ -399,7 +365,8 @@ int MediaEngine::addStreamData(const u8 *buffer, int addSize) {
int streamOffset = (int)(*(s32_be *)(m_mpegheader + 8));
if (streamOffset <= m_mpegheaderSize) {
m_mpegheaderSize = streamOffset;
m_pdata->pop_front(0, m_mpegheaderSize);
int mpegoffset = (int)(*(s32_be*)(m_mpegheader + 8));
m_pdata->pop_front(0, mpegoffset);
openContext();
}
}
Expand Down Expand Up @@ -461,7 +428,7 @@ bool MediaEngine::setVideoStream(int streamNum, bool force) {
if (pCodec == nullptr) {
return false;
}

/*
AVDictionary *opt = nullptr;
// Allow ffmpeg to use any number of threads it wants. Without this, it doesn't use threads.
av_dict_set(&opt, "threads", "0", 0);
Expand All @@ -470,7 +437,11 @@ bool MediaEngine::setVideoStream(int streamNum, bool force) {
if (openResult < 0) {
return false;
}

*/
AVDictionary *optionsDict = 0;
if (avcodec_open2(m_pCodecCtx, pCodec, &optionsDict) < 0) {
return false; // Could not open codec
}
m_pCodecCtxs[streamNum] = m_pCodecCtx;
}
#endif
Expand Down Expand Up @@ -508,10 +479,6 @@ bool MediaEngine::setVideoDim(int width, int height)
m_sws_ctx = NULL;
m_sws_fmt = -1;

if (m_desWidth == 0 || m_desHeight == 0) {
// Can't setup SWS yet, so stop for now.
return false;
}

updateSwsFormat(GE_CMODE_32BIT_ABGR8888);

Expand Down Expand Up @@ -580,9 +547,14 @@ bool MediaEngine::stepVideo(int videoPixelMode, bool skipFrame) {
return false;
if (!m_pCodecCtx)
return false;
if (!m_pFrame)
if ((!m_pFrame) || (!m_pFrameRGB))
return false;

updateSwsFormat(videoPixelMode);
// TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf.
// Update the linesize for the new format too. We started with the largest size, so it should fit.
m_pFrameRGB->linesize[0] = getPixelFormatBytes(videoPixelMode) * m_desWidth;

AVPacket packet;
av_init_packet(&packet);
int frameFinished;
Expand All @@ -603,15 +575,7 @@ bool MediaEngine::stepVideo(int videoPixelMode, bool skipFrame) {

int result = avcodec_decode_video2(m_pCodecCtx, m_pFrame, &frameFinished, &packet);
if (frameFinished) {
if (!m_pFrameRGB) {
setVideoDim();
}
if (m_pFrameRGB && !skipFrame) {
updateSwsFormat(videoPixelMode);
// TODO: Technically we could set this to frameWidth instead of m_desWidth for better perf.
// Update the linesize for the new format too. We started with the largest size, so it should fit.
m_pFrameRGB->linesize[0] = getPixelFormatBytes(videoPixelMode) * m_desWidth;

if (!skipFrame) {
sws_scale(m_sws_ctx, m_pFrame->data, m_pFrame->linesize, 0,
m_pCodecCtx->height, m_pFrameRGB->data, m_pFrameRGB->linesize);
}
Expand Down
5 changes: 2 additions & 3 deletions Core/HW/MediaEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class MediaEngine
bool loadStream(const u8 *buffer, int readSize, int RingbufferSize);
bool reloadStream();
// open the mpeg context
bool openContext(bool keepReadPos = false);
bool openContext();
void closeContext();

// Returns number of packets actually added. I guess the buffer might be full.
Expand All @@ -81,6 +81,7 @@ class MediaEngine
int xpos, int ypos, int width, int height);
int getAudioSamples(u32 bufferPtr);

bool setVideoDim(int width = 0, int height = 0);
s64 getVideoTimeStamp();
s64 getAudioTimeStamp();
s64 getLastTimeStamp();
Expand All @@ -93,8 +94,6 @@ class MediaEngine
void DoState(PointerWrap &p);

private:
bool SetupStreams();
bool setVideoDim(int width = 0, int height = 0);
void updateSwsFormat(int videoPixelMode);
int getNextAudioFrame(u8 **buf, int *headerCode1, int *headerCode2);

Expand Down

0 comments on commit 6760c3d

Please sign in to comment.