Track pts of encoded pictures

master
palana 2014-08-09 01:56:19 +02:00
parent 0f07f473e7
commit 5f1f3d40b3
7 changed files with 25 additions and 19 deletions

View File

@ -50,7 +50,7 @@ public:
NVENCEncoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, ColorDescription &colorDesc, int maxBitRate, int bufferSize, bool bUseCFR);
~NVENCEncoder();
bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp);
bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp, DWORD &out_pts) override;
void RequestBuffers(LPVOID buffers);
int GetBitRate() const;
@ -76,7 +76,7 @@ private:
bool checkPresetSupport(const GUID &preset);
void init();
void ProcessOutput(NVENCEncoderOutputSurface *surf, List<DataPacket> &packets, List<PacketType> &packetTypes);
void ProcessOutput(NVENCEncoderOutputSurface *surf, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD &out_pts);
void dumpEncodeConfig();
void tryParseEncodeConfig();

View File

@ -436,7 +436,7 @@ void NVENCEncoder::RequestBuffers(LPVOID buffers)
NvLog(TEXT("No unlocked frame found"));
}
bool NVENCEncoder::Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp)
bool NVENCEncoder::Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp, DWORD &out_pts)
{
NVENCSTATUS nvStatus;
int i = -1;
@ -541,7 +541,7 @@ bool NVENCEncoder::Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketTy
NVENCEncoderOutputSurface *qSurf = outputSurfaceQueueReady.front();
outputSurfaceQueueReady.pop();
ProcessOutput(qSurf, packets, packetTypes);
ProcessOutput(qSurf, packets, packetTypes, out_pts);
qSurf->busy = false;
@ -552,7 +552,7 @@ bool NVENCEncoder::Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketTy
return true;
}
void NVENCEncoder::ProcessOutput(NVENCEncoderOutputSurface *surf, List<DataPacket> &packets, List<PacketType> &packetTypes)
void NVENCEncoder::ProcessOutput(NVENCEncoderOutputSurface *surf, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD &out_pts)
{
List<uint32_t> sliceOffsets;
sliceOffsets.SetSize(encodeConfig.encodeCodecConfig.h264Config.sliceModeData);
@ -607,7 +607,7 @@ void NVENCEncoder::ProcessOutput(NVENCEncoderOutputSurface *surf, List<DataPacke
size_t nalNum = nalOut.Num();
uint64_t dts = surf->timestamp;
uint64_t out_pts = lockParams.outputTimeStamp;
out_pts = (DWORD)lockParams.outputTimeStamp;
int32_t timeOffset = int(out_pts - dts);
timeOffset += frameShift;

View File

@ -648,7 +648,7 @@ public:
#define SEI_USER_DATA_UNREGISTERED 0x5
#endif
void ProcessEncodedFrame(List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, mfxU32 wait=0)
void ProcessEncodedFrame(List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, DWORD &out_pts, mfxU32 wait=0)
{
if(!filled_bitstream_waiter.wait_for(2, wait))
return;
@ -717,8 +717,8 @@ public:
INT64 dts = msFromTimestamp(bs.DecodeTimeStamp);
INT64 in_pts = msFromTimestamp(task.surf.Data.TimeStamp),
out_pts = msFromTimestamp(bs.TimeStamp);
INT64 in_pts = msFromTimestamp(task.surf.Data.TimeStamp);
out_pts = (DWORD)msFromTimestamp(bs.TimeStamp);
if(!bFirstFrameProcessed && nalNum)
{
@ -968,7 +968,7 @@ public:
CrashError(TEXT("QSV encoder is too slow"));
}
bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp)
bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, DWORD &out_pts) override
{
if(!process_waiter.wait_timeout())
{
@ -997,7 +997,7 @@ public:
profileIn("ProcessEncodedFrame");
do
{
ProcessEncodedFrame(packets, packetTypes, outputTimestamp, idle_tasks.Num() ? 0 : INFINITE);
ProcessEncodedFrame(packets, packetTypes, outputTimestamp, out_pts, idle_tasks.Num() ? 0 : INFINITE);
}
while(!idle_tasks.Num());
profileOut;

View File

@ -315,7 +315,7 @@ public:
x264_encoder_close(x264);
}
bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp)
bool Encode(LPVOID picInPtr, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD outputTimestamp, DWORD &out_pts)
{
x264_picture_t *picIn = (x264_picture_t*)picInPtr;
@ -353,6 +353,8 @@ public:
timeOffset = int(picOut.i_pts-picOut.i_dts);
timeOffset += frameShift;
out_pts = (DWORD)picOut.i_pts;
if(nalNum && timeOffset < 0)
{
frameShift -= timeOffset;

View File

@ -23,7 +23,7 @@
class NullVideoEncoder : public VideoEncoder
{
public:
virtual bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp) {return false;}
virtual bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp, DWORD &out_pts) override {return false;}
virtual void GetHeaders(DataPacket &packet) {}
virtual int GetBitRate() const {return 0;}
virtual String GetInfoString() const {return String();}

View File

@ -161,7 +161,7 @@ class VideoEncoder
friend class OBS;
protected:
virtual bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp)=0;
virtual bool Encode(LPVOID picIn, List<DataPacket> &packets, List<PacketType> &packetTypes, DWORD timestamp, DWORD &out_pts)=0;
virtual void RequestBuffers(LPVOID buffers) {}
@ -526,8 +526,9 @@ struct VideoSegment
{
List<VideoPacketData> packets;
DWORD timestamp;
DWORD pts;
inline VideoSegment() : timestamp(0) {}
inline VideoSegment() : timestamp(0), pts(0) {}
inline ~VideoSegment() {Clear();}
inline void Clear()
{
@ -790,7 +791,7 @@ private:
static DWORD STDCALL EncodeThread(LPVOID lpUnused);
static DWORD STDCALL MainCaptureThread(LPVOID lpUnused);
bool BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, QWORD firstFrameTime, VideoSegment &segmentOut);
bool BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, DWORD out_pts, QWORD firstFrameTime, VideoSegment &segmentOut);
void SendFrame(VideoSegment &curSegment, QWORD firstFrameTime);
bool ProcessFrame(FrameProcessInfo &frameInfo);
void EncodeLoop();

View File

@ -75,10 +75,11 @@ DWORD STDCALL Convert444Thread(Convert444Data *data)
return 0;
}
bool OBS::BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, QWORD firstFrameTime, VideoSegment &segmentOut)
bool OBS::BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, DWORD out_pts, QWORD firstFrameTime, VideoSegment &segmentOut)
{
VideoSegment &segmentIn = *bufferedVideo.CreateNew();
segmentIn.timestamp = timestamp;
segmentIn.pts = out_pts;
segmentIn.packets.SetSize(inputPackets.Num());
for(UINT i=0; i<inputPackets.Num(); i++)
@ -104,6 +105,7 @@ bool OBS::BufferVideoData(const List<DataPacket> &inputPackets, const List<Packe
{
segmentOut.packets.TransferFrom(bufferedVideo[0].packets);
segmentOut.timestamp = bufferedVideo[0].timestamp;
segmentOut.pts = bufferedVideo[0].pts;
bufferedVideo.Remove(0);
return true;
@ -227,14 +229,15 @@ bool OBS::ProcessFrame(FrameProcessInfo &frameInfo)
else
picIn = frameInfo.pic->picOut ? (LPVOID)frameInfo.pic->picOut : (LPVOID)frameInfo.pic->mfxOut;
videoEncoder->Encode(picIn, videoPackets, videoPacketTypes, bufferedTimes[0]);
DWORD out_pts = 0;
videoEncoder->Encode(picIn, videoPackets, videoPacketTypes, bufferedTimes[0], out_pts);
bProcessedFrame = (videoPackets.Num() != 0);
//buffer video data before sending out
if(bProcessedFrame)
{
bSendFrame = BufferVideoData(videoPackets, videoPacketTypes, bufferedTimes[0], frameInfo.firstFrameTime, curSegment);
bSendFrame = BufferVideoData(videoPackets, videoPacketTypes, bufferedTimes[0], out_pts, frameInfo.firstFrameTime, curSegment);
bufferedTimes.Remove(0);
}
else