Track pts of encoded pictures
parent
0f07f473e7
commit
5f1f3d40b3
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue