Gstreamer: in output video sample dts differs from pts

Igor igor.vl.bondarenko at gmail.com
Thu Jul 12 09:48:34 UTC 2018


I'm new in GStreamer. I'm working on part of corporate's solution. I'm
receiving some video stream from module A, and send it to module B.

I have this code:

   g_signal_connect(m_videoSource, "need-data", (GCallback)pushVideoData,
this);

 ...

    static gboolean pushVideoData(GstElement*, guint, gpointer h)
    {
        auto handler = GetSink(h);
        if (!handler || handler->m_finished)
                return false;

        return handler->onNeedVideoData();
    }

    gboolean onNeedVideoData()
    {
        //Getting sample from module A
        NMMSS::PSample sample = m_videoSink->GetSample(m_streamStartTime);

        GstBuffer* buf =
gst_buffer_new_and_alloc(sample->Header().nBodySize);

        boost::posix_time::ptime currentTime =
NMMSS::PtimeFromQword(sample->Header().dtTimeBegin);
        //_log_ << "Video sample time: " <<
boost::posix_time::to_iso_string(currentTime);

        if (m_videoLastTime == boost::posix_time::neg_infin)
        {
            GST_BUFFER_DURATION(buf) = 0;
        }
        else
        {
            GST_BUFFER_DURATION(buf) = (currentTime -
m_videoLastTime).total_nanoseconds();
        }


         // !!! important part
        GST_BUFFER_PTS(buf) = GST_BUFFER_DTS(buf) = (currentTime -
m_streamStartTime).total_nanoseconds();

        GST_META_MARKING_ADD(buf, sample->Header().dtTimeBegin);

        m_videoLastTime = currentTime;

        GstMapInfo map;
        gst_buffer_map(buf, &map, GST_MAP_WRITE);

        memcpy(map.data, sample->GetBody(), sample->Header().nBodySize);

        gst_buffer_unmap(buf, &map);

        GstFlowReturn ret;
        g_signal_emit_by_name(m_videoSource, "push-buffer", buf, &ret);

        gst_buffer_unref(buf);

    }

In some video streams (let's call them "bad streams"), in output samples
there're different pts and dts, although i explicitly set

GST_BUFFER_PTS(buf) = GST_BUFFER_DTS(buf) = (currentTime -
m_streamStartTime).total_nanoseconds();
And video renders with jumps. Others video streams works well.

  [FRAME]
  media_type=video
  stream_index=0
  key_frame=0
  pkt_pts=5200
  pkt_pts_time=0.520000
  pkt_dts=6400
  pkt_dts_time=0.640000
  best_effort_timestamp=6400
  best_effort_timestamp_time=0.640000
  pkt_duration=N/A
  pkt_duration_time=N/A 
  pkt_pos=973496
  pkt_size=39016
  width=1920
  height=1440
  pix_fmt=yuv420p
  sample_aspect_ratio=1:1
  pict_type=P
  coded_picture_number=13
  display_picture_number=0
  interlaced_frame=0
  top_field_first=0
  repeat_pict=0
  color_range=unknown
  color_space=unknown
  color_primaries=unknown
  color_transfer=unknown
  chroma_location=left
  [/FRAME]

Logged with ffprobe.

Both GST_BUFFER_DTS_IS_VALID and GST_BUFFER_PTS_IS_VALID returns true;

If I hardcode

        if (!IsDeltaFrame(sample.Get()))
            GST_BUFFER_TIMESTAMP(buf) = (currentTime -
m_streamStartTime).total_nanoseconds();
        else
            GST_BUFFER_TIMESTAMP(buf) = (currentTime -
m_streamStartTime).total_nanoseconds() + 120 * 1000000;

one of such "bad streams" renders smoother.

The questions are:

1) why pts and dts in output samples differs, although i explicitly assign
same value. Does GStreamer gets information about pts/dts from binary h264
bytestream?

2) How can I fix this? My goal: all streams ("good" and "bad") render
smooth.

Thanks!




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/


More information about the gstreamer-devel mailing list