Skip to content

Commit

Permalink
Fixed the issue where PTS wrap around occurs when using the XMA decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
Keukhan committed Jan 19, 2025
1 parent 8700678 commit 68bfc9a
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/projects/transcoder/codec/decoder/decoder_avc_xma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#include "../../transcoder_private.h"
#include "base/info/application.h"


// The Xilinx Video SDK decoder uses a 32-bit PTS. At some point, it wrap around and becomes negative.
// To fix this, we changed it to calculate the PTS outside the codec.
#define USE_EXTERNAL_TIMESTAMP true

bool DecoderAVCxXMA::InitCodec()
{
const AVCodec *_codec = ::avcodec_find_decoder_by_name("mpsoc_vcu_h264");
Expand Down Expand Up @@ -91,6 +96,11 @@ void DecoderAVCxXMA::UninitCodec()
::av_parser_close(_parser);
}
_parser = nullptr;

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.clear();
#endif

}

bool DecoderAVCxXMA::ReinitCodecIfNeed()
Expand Down Expand Up @@ -224,6 +234,10 @@ void DecoderAVCxXMA::CodecThread()
logte("An error occurred while sending a packet for decoding: Unhandled error (%d:%s) ", ret, err_msg);
break;
}

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.push_back(_pkt->pts);
#endif
}

OV_ASSERT(
Expand Down Expand Up @@ -289,6 +303,14 @@ void DecoderAVCxXMA::CodecThread()
_frame->pkt_duration = (int64_t)(((double)_context->framerate.den / (double)_context->framerate.num) / ((double)GetRefTrack()->GetTimeBase().GetNum() / (double)GetRefTrack()->GetTimeBase().GetDen()));
}

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.sort();
auto ordered_pts = _pts_reorder_list.front();
// logtd("in: %lld, out: %lld (%s), list: %d", ordered_pts, _frame->pts, (ordered_pts == _frame->pts) ? "match" : "No match", _pts_reorder_list.size());
_frame->pts = ordered_pts;
_pts_reorder_list.pop_front();
#endif

auto decoded_frame = ffmpeg::Conv::ToMediaFrame(cmn::MediaType::Video, _frame);
if (decoded_frame == nullptr)
{
Expand Down
6 changes: 6 additions & 0 deletions src/projects/transcoder/codec/decoder/decoder_avc_xma.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "../../transcoder_decoder.h"
#include <list>

class DecoderAVCxXMA : public TranscodeDecoder
{
Expand All @@ -28,4 +29,9 @@ class DecoderAVCxXMA : public TranscodeDecoder
bool ReinitCodecIfNeed();

void CodecThread() override;

private:
[[maybe_unused]]
std::list<int64_t> _pts_reorder_list;

};
21 changes: 21 additions & 0 deletions src/projects/transcoder/codec/decoder/decoder_hevc_xma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
#include <modules/bitstream/h265/h265_decoder_configuration_record.h>
#include <modules/bitstream/nalu/nal_stream_converter.h>

// The Xilinx Video SDK decoder uses a 32-bit PTS. At some point, it wrap around and becomes negative.
// To fix this, we changed it to calculate the PTS outside the codec.
#define USE_EXTERNAL_TIMESTAMP true

bool DecoderHEVCxXMA::InitCodec()
{
const AVCodec *_codec = ::avcodec_find_decoder_by_name("mpsoc_vcu_hevc");
Expand Down Expand Up @@ -91,6 +95,11 @@ void DecoderHEVCxXMA::UninitCodec()
::av_parser_close(_parser);
}
_parser = nullptr;

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.clear();
#endif

}

bool DecoderHEVCxXMA::ReinitCodecIfNeed()
Expand Down Expand Up @@ -224,6 +233,10 @@ void DecoderHEVCxXMA::CodecThread()
logte("An error occurred while sending a packet for decoding: Unhandled error (%d:%s) ", ret, err_msg);
break;
}

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.push_back(_pkt->pts);
#endif
}

OV_ASSERT(
Expand Down Expand Up @@ -289,6 +302,14 @@ void DecoderHEVCxXMA::CodecThread()
_frame->pkt_duration = (int64_t)(((double)_context->framerate.den / (double)_context->framerate.num) / ((double)GetRefTrack()->GetTimeBase().GetNum() / (double)GetRefTrack()->GetTimeBase().GetDen()));
}

#if USE_EXTERNAL_TIMESTAMP
_pts_reorder_list.sort();
auto ordered_pts = _pts_reorder_list.front();
// logtd("in: %lld, out: %lld (%s), list: %d", ordered_pts, _frame->pts, (ordered_pts == _frame->pts) ? "match" : "No match", _pts_reorder_list.size());
_frame->pts = ordered_pts;
_pts_reorder_list.pop_front();
#endif

auto decoded_frame = ffmpeg::Conv::ToMediaFrame(cmn::MediaType::Video, _frame);
if (decoded_frame == nullptr)
{
Expand Down
5 changes: 5 additions & 0 deletions src/projects/transcoder/codec/decoder/decoder_hevc_xma.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "../../transcoder_decoder.h"
#include <list>

class DecoderHEVCxXMA : public TranscodeDecoder
{
Expand All @@ -28,4 +29,8 @@ class DecoderHEVCxXMA : public TranscodeDecoder
bool ReinitCodecIfNeed();

void CodecThread() override;

private:
[[maybe_unused]]
std::list<int64_t> _pts_reorder_list;
};

0 comments on commit 68bfc9a

Please sign in to comment.