mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
Update
This commit is contained in:
parent
7f7d5a57c8
commit
8cc6a287a7
@ -393,7 +393,7 @@ s64 CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4)
|
|||||||
{
|
{
|
||||||
if (Emu.IsStopped())
|
if (Emu.IsStopped())
|
||||||
{
|
{
|
||||||
ConLog.Warning("ExecAsCallback(wait=%s) aborted", wxString(wait ? "true" : false).wx_str());
|
ConLog.Warning("ExecAsCallback(wait=%s) aborted", wxString(wait ? "true" : "false").wx_str());
|
||||||
return CELL_EABORT; // doesn't mean anything
|
return CELL_EABORT; // doesn't mean anything
|
||||||
}
|
}
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
|
@ -20,14 +20,66 @@ int adecRead(void* opaque, u8* buf, int buf_size)
|
|||||||
{
|
{
|
||||||
AudioDecoder& adec = *(AudioDecoder*)opaque;
|
AudioDecoder& adec = *(AudioDecoder*)opaque;
|
||||||
|
|
||||||
if (adec.reader.size < (u32)buf_size)
|
int res = 0;
|
||||||
|
|
||||||
|
next:
|
||||||
|
if (adec.reader.size < (u32)buf_size /*&& !vdec.just_started*/)
|
||||||
|
{
|
||||||
|
while (adec.job.IsEmpty())
|
||||||
|
{
|
||||||
|
if (Emu.IsStopped())
|
||||||
|
{
|
||||||
|
ConLog.Warning("vdecRead() aborted");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (adec.job.Peek().type)
|
||||||
|
{
|
||||||
|
case adecEndSeq:
|
||||||
|
{
|
||||||
|
buf_size = adec.reader.size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case adecDecodeAu:
|
||||||
|
{
|
||||||
|
if (!Memory.CopyToReal(buf, adec.reader.addr, adec.reader.size))
|
||||||
|
{
|
||||||
|
ConLog.Error("adecRead: data reading failed (reader.size=0x%x)", adec.reader.size);
|
||||||
|
Emu.Pause();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += adec.reader.size;
|
||||||
|
buf_size -= adec.reader.size;
|
||||||
|
res += adec.reader.size;
|
||||||
|
|
||||||
|
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, adec.task.au.auInfo_addr, adec.cbArg);
|
||||||
|
|
||||||
|
adec.job.Pop(adec.task);
|
||||||
|
|
||||||
|
adec.reader.addr = adec.task.au.addr;
|
||||||
|
adec.reader.size = adec.task.au.size;
|
||||||
|
|
||||||
|
adec.last_pts = adec.task.au.pts;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ConLog.Error("adecRead(): sequence error (task %d)", adec.job.Peek().type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
else if (adec.reader.size < (u32)buf_size)
|
||||||
{
|
{
|
||||||
buf_size = adec.reader.size;
|
buf_size = adec.reader.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buf_size)
|
if (!buf_size)
|
||||||
{
|
{
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
else if (!Memory.CopyToReal(buf, adec.reader.addr, buf_size))
|
else if (!Memory.CopyToReal(buf, adec.reader.addr, buf_size))
|
||||||
{
|
{
|
||||||
@ -39,7 +91,7 @@ int adecRead(void* opaque, u8* buf, int buf_size)
|
|||||||
{
|
{
|
||||||
adec.reader.addr += buf_size;
|
adec.reader.addr += buf_size;
|
||||||
adec.reader.size -= buf_size;
|
adec.reader.size -= buf_size;
|
||||||
return 0 + buf_size;
|
return res + buf_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +111,7 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
{
|
{
|
||||||
ConLog.Write("Audio Decoder enter()");
|
ConLog.Write("Audio Decoder enter()");
|
||||||
|
|
||||||
AdecTask task;
|
AdecTask& task = adec.task;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -119,12 +171,12 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
|
|
||||||
case adecDecodeAu:
|
case adecDecodeAu:
|
||||||
{
|
{
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
adec.reader.addr = task.au.addr;
|
adec.reader.addr = task.au.addr;
|
||||||
adec.reader.size = task.au.size;
|
adec.reader.size = task.au.size;
|
||||||
|
|
||||||
u64 last_pts = task.au.pts;
|
adec.last_pts = task.au.pts;
|
||||||
|
|
||||||
struct AVPacketHolder : AVPacket
|
struct AVPacketHolder : AVPacket
|
||||||
{
|
{
|
||||||
@ -160,7 +212,7 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size);
|
if (Memory.CopyToReal(buf, task.au.addr, task.au.size)) dump.Write(buf, task.au.size);
|
||||||
free(buf);
|
free(buf);
|
||||||
dump.Close();
|
dump.Close();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (adec.just_started) // deferred initialization
|
if (adec.just_started) // deferred initialization
|
||||||
{
|
{
|
||||||
@ -171,6 +223,13 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_ATRAC3P); // ???
|
||||||
|
if (!codec)
|
||||||
|
{
|
||||||
|
ConLog.Error("adecDecodeAu: avcodec_find_decoder() failed");
|
||||||
|
Emu.Pause();
|
||||||
|
break;
|
||||||
|
}
|
||||||
err = avformat_find_stream_info(adec.fmt, NULL);
|
err = avformat_find_stream_info(adec.fmt, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -185,16 +244,8 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data
|
adec.ctx = adec.fmt->streams[0]->codec; // TODO: check data
|
||||||
|
|
||||||
AVCodec* codec = avcodec_find_decoder(adec.ctx->codec_id); // ???
|
|
||||||
if (!codec)
|
|
||||||
{
|
|
||||||
ConLog.Error("adecDecodeAu: avcodec_find_decoder() failed");
|
|
||||||
Emu.Pause();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVDictionary* opts;
|
AVDictionary* opts = nullptr;
|
||||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||||
{
|
{
|
||||||
SMutexGeneralLocker lock(g_mutex_avcodec_open2);
|
SMutexGeneralLocker lock(g_mutex_avcodec_open2);
|
||||||
@ -210,9 +261,17 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
adec.just_started = false;
|
adec.just_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (av_read_frame(adec.fmt, &au) >= 0)*/ while (true)
|
bool last_frame = false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
if (!adec.ctx) // fake
|
if (Emu.IsStopped())
|
||||||
|
{
|
||||||
|
ConLog.Warning("adecDecodeAu aborted");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (!adec.ctx) // fake
|
||||||
{
|
{
|
||||||
AdecFrame frame;
|
AdecFrame frame;
|
||||||
frame.pts = task.au.pts;
|
frame.pts = task.au.pts;
|
||||||
@ -223,13 +282,18 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
frame.data = nullptr;
|
frame.data = nullptr;
|
||||||
adec.frames.Push(frame);
|
adec.frames.Push(frame);
|
||||||
|
|
||||||
/*Callback cb;
|
|
||||||
cb.SetAddr(adec.cbFunc);
|
|
||||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
|
||||||
cb.Branch(false);*/
|
|
||||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
last_frame = av_read_frame(adec.fmt, &au) < 0;
|
||||||
|
if (last_frame)
|
||||||
|
{
|
||||||
|
//break;
|
||||||
|
av_free(au.data);
|
||||||
|
au.data = NULL;
|
||||||
|
au.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VdecFrameHolder : AdecFrame
|
struct VdecFrameHolder : AdecFrame
|
||||||
@ -261,10 +325,13 @@ u32 adecOpen(AudioDecoder* data)
|
|||||||
|
|
||||||
int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au);
|
int decode = avcodec_decode_audio4(adec.ctx, frame.data, &got_frame, &au);
|
||||||
|
|
||||||
if (decode < 0)
|
if (decode <= 0)
|
||||||
{
|
{
|
||||||
ConLog.Error("adecDecodeAu: AU decoding error(0x%x)", decode);
|
if (!last_frame && decode < 0)
|
||||||
break;
|
{
|
||||||
|
ConLog.Error("adecDecodeAu: AU decoding error(0x%x)", decode);
|
||||||
|
}
|
||||||
|
if (!got_frame && adec.reader.size == 0) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_frame)
|
if (got_frame)
|
||||||
|
@ -1064,6 +1064,9 @@ public:
|
|||||||
const u32 cbArg;
|
const u32 cbArg;
|
||||||
u32 memBias;
|
u32 memBias;
|
||||||
|
|
||||||
|
AdecTask task;
|
||||||
|
u64 last_pts;
|
||||||
|
|
||||||
CPUThread* adecCb;
|
CPUThread* adecCb;
|
||||||
|
|
||||||
AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg)
|
AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg)
|
||||||
|
@ -18,7 +18,7 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t<CellCodecEsFi
|
|||||||
const u32 esSpecificInfo_addr, mem_ptr_t<CellDmuxEsAttr> attr)
|
const u32 esSpecificInfo_addr, mem_ptr_t<CellDmuxEsAttr> attr)
|
||||||
{
|
{
|
||||||
if (esFilterId->filterIdMajor >= 0xe0)
|
if (esFilterId->filterIdMajor >= 0xe0)
|
||||||
attr->memSize = 0x1000000; // 0x45fa49 from ps3
|
attr->memSize = 0x3000000; // 0x45fa49 from ps3
|
||||||
else
|
else
|
||||||
attr->memSize = 0x200000; // 0x73d9 from ps3
|
attr->memSize = 0x200000; // 0x73d9 from ps3
|
||||||
|
|
||||||
@ -156,6 +156,16 @@ u32 dmuxOpen(Demuxer* data)
|
|||||||
|
|
||||||
//ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts);
|
//ConLog.Write("*** AT3+ AU sent (pts=0x%llx, dts=0x%llx)", pes.pts, pes.dts);
|
||||||
|
|
||||||
|
stream.skip(4);
|
||||||
|
len -= 4;
|
||||||
|
u32 abc;
|
||||||
|
stream.peek(abc);
|
||||||
|
if (abc == 0x5548D00F)
|
||||||
|
{
|
||||||
|
stream.skip(8);
|
||||||
|
len -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
es.push(stream, len - pes.size - 3, pes);
|
es.push(stream, len - pes.size - 3, pes);
|
||||||
es.finish(stream);
|
es.finish(stream);
|
||||||
|
|
||||||
@ -231,7 +241,7 @@ u32 dmuxOpen(Demuxer* data)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//hack: reconstruction of MPEG2-PS stream for vdec module (seems it works without it too)
|
//reconstruction of MPEG2-PS stream for vdec module
|
||||||
stream = backup;
|
stream = backup;
|
||||||
es.push(stream, len + 6 /*- pes.size - 3*/, pes);
|
es.push(stream, len + 6 /*- pes.size - 3*/, pes);
|
||||||
}
|
}
|
||||||
@ -288,18 +298,32 @@ u32 dmuxOpen(Demuxer* data)
|
|||||||
{
|
{
|
||||||
case dmuxSetStream:
|
case dmuxSetStream:
|
||||||
{
|
{
|
||||||
|
if (stream.discontinuity)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < 192; i++)
|
||||||
|
{
|
||||||
|
if (esALL[i])
|
||||||
|
{
|
||||||
|
esALL[i]->reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updates_count = 0;
|
||||||
|
updates_signaled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updates_count != updates_signaled)
|
||||||
|
{
|
||||||
|
ConLog.Error("dmuxSetStream: stream update inconsistency (input=%d, signaled=%d)", updates_count, updates_signaled);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updates_count++;
|
||||||
stream = task.stream;
|
stream = task.stream;
|
||||||
ConLog.Write("*** stream updated(addr=0x%x, size=0x%x, discont=%d, userdata=0x%llx)",
|
ConLog.Write("*** stream updated(addr=0x%x, size=0x%x, discont=%d, userdata=0x%llx)",
|
||||||
stream.addr, stream.size, stream.discontinuity, stream.userdata);
|
stream.addr, stream.size, stream.discontinuity, stream.userdata);
|
||||||
if (stream.discontinuity) for (u32 i = 0; i < 192; i++)
|
|
||||||
{
|
|
||||||
if (esALL[i])
|
|
||||||
{
|
|
||||||
esALL[i]->reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updates_count++;
|
|
||||||
dmux.is_running = true;
|
dmux.is_running = true;
|
||||||
|
dmux.fbSetStream.Push(task.stream.addr); // feedback
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -592,12 +616,12 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize
|
|||||||
return CELL_DMUX_ERROR_FATAL;
|
return CELL_DMUX_ERROR_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dmux->is_running) // !!!
|
if (dmux->is_running)
|
||||||
{
|
{
|
||||||
if (Emu.IsStopped())
|
if (Emu.IsStopped())
|
||||||
{
|
{
|
||||||
ConLog.Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle);
|
ConLog.Warning("cellDmuxSetStream(%d) aborted (waiting)", demuxerHandle);
|
||||||
break;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
Sleep(1);
|
Sleep(1);
|
||||||
return CELL_DMUX_ERROR_BUSY;
|
return CELL_DMUX_ERROR_BUSY;
|
||||||
@ -612,14 +636,16 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize
|
|||||||
|
|
||||||
dmux->job.Push(task);
|
dmux->job.Push(task);
|
||||||
|
|
||||||
while (!dmux->is_running)
|
u32 addr;
|
||||||
|
if (!dmux->fbSetStream.Pop(addr))
|
||||||
{
|
{
|
||||||
if (Emu.IsStopped())
|
ConLog.Warning("cellDmuxSetStream(%d) aborted (fbSetStream.Pop())", demuxerHandle);
|
||||||
{
|
return CELL_OK;
|
||||||
ConLog.Warning("cellDmuxSetStream(%d) aborted", demuxerHandle);
|
}
|
||||||
break;
|
if (addr != info.addr)
|
||||||
}
|
{
|
||||||
Sleep(1);
|
ConLog.Error("cellDmuxSetStream(%d): wrong stream queued (right=0x%x, queued=0x%x)", demuxerHandle, info.addr, addr);
|
||||||
|
Emu.Pause();
|
||||||
}
|
}
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -921,7 +947,7 @@ int cellDmuxPeekAuEx(u32 esHandle, mem32_t auInfoEx_ptr, mem32_t auSpecificInfo_
|
|||||||
|
|
||||||
int cellDmuxReleaseAu(u32 esHandle)
|
int cellDmuxReleaseAu(u32 esHandle)
|
||||||
{
|
{
|
||||||
cellDmux.Log("cellDmuxReleaseAu(esHandle=0x%x)", esHandle);
|
cellDmux.Log("(disabled) cellDmuxReleaseAu(esHandle=0x%x)", esHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
|
|
||||||
@ -931,21 +957,8 @@ int cellDmuxReleaseAu(u32 esHandle)
|
|||||||
return CELL_DMUX_ERROR_ARG;
|
return CELL_DMUX_ERROR_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!es->canrelease())
|
|
||||||
{
|
|
||||||
cellDmux.Error("cellDmuxReleaseAu: no AU");
|
|
||||||
return CELL_DMUX_ERROR_SEQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*DemuxerTask task(dmuxReleaseAu);
|
|
||||||
task.es.es = esHandle;
|
|
||||||
task.es.es_ptr = es;
|
|
||||||
|
|
||||||
es->dmux->job.Push(task);*/
|
|
||||||
|
|
||||||
if (!es->release())
|
if (!es->release())
|
||||||
{
|
{
|
||||||
cellDmux.Error("cellDmuxReleaseAu failed");
|
|
||||||
return CELL_DMUX_ERROR_SEQ;
|
return CELL_DMUX_ERROR_SEQ;
|
||||||
}
|
}
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
@ -953,7 +966,7 @@ int cellDmuxReleaseAu(u32 esHandle)
|
|||||||
|
|
||||||
int cellDmuxFlushEs(u32 esHandle)
|
int cellDmuxFlushEs(u32 esHandle)
|
||||||
{
|
{
|
||||||
cellDmux.Log("cellDmuxFlushEs(esHandle=0x%x)", esHandle);
|
cellDmux.Warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle);
|
||||||
|
|
||||||
ElementaryStream* es;
|
ElementaryStream* es;
|
||||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||||
|
@ -304,11 +304,6 @@ enum
|
|||||||
PRIVATE_STREAM_2 = 0x000001bf,
|
PRIVATE_STREAM_2 = 0x000001bf,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MAX_AU = 640 * 1024 + 128, // 640 KB
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DemuxerStream
|
struct DemuxerStream
|
||||||
{
|
{
|
||||||
u32 addr;
|
u32 addr;
|
||||||
@ -385,7 +380,7 @@ struct PesHeader
|
|||||||
stream.get(v);
|
stream.get(v);
|
||||||
if (v != 0xFF) break; // skip padding bytes
|
if (v != 0xFF) break; // skip padding bytes
|
||||||
empty++;
|
empty++;
|
||||||
if (empty = size) return;
|
if (empty == size) return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only
|
if ((v & 0xF0) == 0x20 && (size - empty) >= 5) // pts only
|
||||||
@ -460,7 +455,8 @@ struct DemuxerTask
|
|||||||
class Demuxer
|
class Demuxer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SQueue<DemuxerTask> job;
|
SQueue<DemuxerTask, 32> job;
|
||||||
|
SQueue<u32, 16> fbSetStream;
|
||||||
const u32 memAddr;
|
const u32 memAddr;
|
||||||
const u32 memSize;
|
const u32 memSize;
|
||||||
const u32 cbFunc;
|
const u32 cbFunc;
|
||||||
@ -491,6 +487,26 @@ class ElementaryStream
|
|||||||
u32 last_addr; // AU that is being written now
|
u32 last_addr; // AU that is being written now
|
||||||
u32 last_size; // number of bytes written (after 128b header)
|
u32 last_size; // number of bytes written (after 128b header)
|
||||||
u32 peek_addr; // AU that will be obtained by GetAu(Ex)/PeekAu(Ex)
|
u32 peek_addr; // AU that will be obtained by GetAu(Ex)/PeekAu(Ex)
|
||||||
|
|
||||||
|
bool is_full()
|
||||||
|
{
|
||||||
|
if (first_addr)
|
||||||
|
{
|
||||||
|
if (first_addr >= last_addr)
|
||||||
|
{
|
||||||
|
return (first_addr - last_addr) <= GetMaxAU();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// probably, always false
|
||||||
|
return (last_addr + GetMaxAU()) > (memAddr + memSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Demuxer* dmux;
|
Demuxer* dmux;
|
||||||
@ -523,6 +539,11 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const u32 GetMaxAU() const
|
||||||
|
{
|
||||||
|
return 640 * 1024 + 128;
|
||||||
|
}
|
||||||
|
|
||||||
volatile bool hasunseen()
|
volatile bool hasunseen()
|
||||||
{
|
{
|
||||||
return peek_addr;
|
return peek_addr;
|
||||||
@ -536,21 +557,7 @@ public:
|
|||||||
bool isfull()
|
bool isfull()
|
||||||
{
|
{
|
||||||
SMutexLocker lock(mutex);
|
SMutexLocker lock(mutex);
|
||||||
if (first_addr)
|
return is_full();
|
||||||
{
|
|
||||||
if (first_addr > last_addr)
|
|
||||||
{
|
|
||||||
return (first_addr - last_addr) < MAX_AU;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (first_addr + MAX_AU) > (memAddr + memSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish(DemuxerStream& stream) // not multithread-safe
|
void finish(DemuxerStream& stream) // not multithread-safe
|
||||||
@ -565,8 +572,9 @@ public:
|
|||||||
{
|
{
|
||||||
peek_addr = last_addr;
|
peek_addr = last_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 new_addr = a128(last_addr + 128 + last_size);
|
u32 new_addr = a128(last_addr + 128 + last_size);
|
||||||
if ((new_addr + MAX_AU) > (memAddr + memSize))
|
if ((new_addr + GetMaxAU()) > (memAddr + memSize))
|
||||||
{
|
{
|
||||||
last_addr = memAddr;
|
last_addr = memAddr;
|
||||||
}
|
}
|
||||||
@ -581,24 +589,8 @@ public:
|
|||||||
{
|
{
|
||||||
SMutexLocker lock(mutex);
|
SMutexLocker lock(mutex);
|
||||||
//ConLog.Write("es::push(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
//ConLog.Write("es::push(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
||||||
bool is_full;
|
|
||||||
if (first_addr)
|
|
||||||
{
|
|
||||||
if (first_addr > last_addr)
|
|
||||||
{
|
|
||||||
is_full = (first_addr - last_addr) < MAX_AU;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
is_full = (first_addr + MAX_AU) > (memAddr + memSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
is_full = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_full)
|
if (is_full())
|
||||||
{
|
{
|
||||||
ConLog.Error("ElementaryStream::push(): buffer is full");
|
ConLog.Error("ElementaryStream::push(): buffer is full");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
@ -646,16 +638,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool canrelease()
|
|
||||||
{
|
|
||||||
return first_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool release()
|
bool release()
|
||||||
{
|
{
|
||||||
SMutexLocker lock(mutex);
|
SMutexLocker lock(mutex);
|
||||||
//ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
//ConLog.Write("es::release(): peek=0x%x, first=0x%x, last=0x%x, size=0x%x", peek_addr, first_addr, last_addr, last_size);
|
||||||
if (!canrelease())
|
if (!first_addr)
|
||||||
{
|
{
|
||||||
ConLog.Error("ElementaryStream::release(): buffer is empty");
|
ConLog.Error("ElementaryStream::release(): buffer is empty");
|
||||||
return false;
|
return false;
|
||||||
@ -675,7 +662,7 @@ public:
|
|||||||
{
|
{
|
||||||
first_addr = 0;
|
first_addr = 0;
|
||||||
}
|
}
|
||||||
else if ((new_addr + MAX_AU) > (memAddr + memSize))
|
else if ((new_addr + GetMaxAU()) > (memAddr + memSize))
|
||||||
{
|
{
|
||||||
first_addr = memAddr;
|
first_addr = memAddr;
|
||||||
}
|
}
|
||||||
@ -706,7 +693,7 @@ public:
|
|||||||
{
|
{
|
||||||
peek_addr = 0;
|
peek_addr = 0;
|
||||||
}
|
}
|
||||||
else if ((new_addr + MAX_AU) > (memAddr + memSize))
|
else if ((new_addr + GetMaxAU()) > (memAddr + memSize))
|
||||||
{
|
{
|
||||||
peek_addr = memAddr;
|
peek_addr = memAddr;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
|||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (vdec.reader.size < (u32)buf_size && !vdec.just_started)
|
next:
|
||||||
|
if (vdec.reader.size < (u32)buf_size /*&& !vdec.just_started*/)
|
||||||
{
|
{
|
||||||
while (vdec.job.IsEmpty())
|
while (vdec.job.IsEmpty())
|
||||||
{
|
{
|
||||||
@ -74,6 +75,8 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
|||||||
ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type);
|
ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goto next;
|
||||||
}
|
}
|
||||||
else if (vdec.reader.size < (u32)buf_size)
|
else if (vdec.reader.size < (u32)buf_size)
|
||||||
{
|
{
|
||||||
@ -235,14 +238,21 @@ u32 vdecOpen(VideoDecoder* data)
|
|||||||
|
|
||||||
if (vdec.just_started) // deferred initialization
|
if (vdec.just_started) // deferred initialization
|
||||||
{
|
{
|
||||||
err = avformat_open_input(&vdec.fmt, NULL, NULL, NULL);
|
err = avformat_open_input(&vdec.fmt, NULL, av_find_input_format("mpeg"), NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
ConLog.Error("vdecDecodeAu: avformat_open_input() failed");
|
ConLog.Error("vdecDecodeAu: avformat_open_input() failed");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err = avformat_find_stream_info(vdec.fmt, NULL);
|
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264); // ???
|
||||||
|
if (!codec)
|
||||||
|
{
|
||||||
|
ConLog.Error("vdecDecodeAu: avcodec_find_decoder() failed");
|
||||||
|
Emu.Pause();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*err = avformat_find_stream_info(vdec.fmt, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
ConLog.Error("vdecDecodeAu: avformat_find_stream_info() failed");
|
ConLog.Error("vdecDecodeAu: avformat_find_stream_info() failed");
|
||||||
@ -254,17 +264,15 @@ u32 vdecOpen(VideoDecoder* data)
|
|||||||
ConLog.Error("vdecDecodeAu: no stream found");
|
ConLog.Error("vdecDecodeAu: no stream found");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}*/
|
||||||
vdec.ctx = vdec.fmt->streams[0]->codec; // TODO: check data
|
if (!avformat_new_stream(vdec.fmt, codec))
|
||||||
|
|
||||||
AVCodec* codec = avcodec_find_decoder(vdec.ctx->codec_id); // ???
|
|
||||||
if (!codec)
|
|
||||||
{
|
{
|
||||||
ConLog.Error("vdecDecodeAu: avcodec_find_decoder() failed");
|
ConLog.Error("vdecDecodeAu: avformat_new_stream() failed");
|
||||||
Emu.Pause();
|
Emu.Pause();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
vdec.ctx = vdec.fmt->streams[0]->codec; // TODO: check data
|
||||||
|
|
||||||
AVDictionary* opts = nullptr;
|
AVDictionary* opts = nullptr;
|
||||||
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
av_dict_set(&opts, "refcounted_frames", "1", 0);
|
||||||
{
|
{
|
||||||
@ -292,6 +300,7 @@ u32 vdecOpen(VideoDecoder* data)
|
|||||||
ConLog.Warning("vdecDecodeAu aborted");
|
ConLog.Warning("vdecDecodeAu aborted");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_frame = av_read_frame(vdec.fmt, &au) < 0;
|
last_frame = av_read_frame(vdec.fmt, &au) < 0;
|
||||||
if (last_frame)
|
if (last_frame)
|
||||||
{
|
{
|
||||||
@ -335,7 +344,6 @@ u32 vdecOpen(VideoDecoder* data)
|
|||||||
if (!last_frame && decode < 0)
|
if (!last_frame && decode < 0)
|
||||||
{
|
{
|
||||||
ConLog.Error("vdecDecodeAu: AU decoding error(0x%x)", decode);
|
ConLog.Error("vdecDecodeAu: AU decoding error(0x%x)", decode);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (!got_picture && vdec.reader.size == 0) break; // video end?
|
if (!got_picture && vdec.reader.size == 0) break; // video end?
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,7 @@ bool SleepQueue::finalize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_mutex.unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user