1/*
2 * Copyright (C) 2016 Metrological Group B.V.
3 * Copyright (C) 2016 Igalia S.L
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * aint with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22#include "GStreamerMediaSample.h"
23
24#include "GStreamerUtilities.h"
25
26#if ENABLE(VIDEO) && USE(GSTREAMER) && ENABLE(MEDIA_SOURCE) && ENABLE(VIDEO_TRACK)
27
28namespace WebCore {
29
30GStreamerMediaSample::GStreamerMediaSample(GstSample* sample, const FloatSize& presentationSize, const AtomicString& trackId)
31 : MediaSample()
32 , m_pts(MediaTime::zeroTime())
33 , m_dts(MediaTime::zeroTime())
34 , m_duration(MediaTime::zeroTime())
35 , m_trackId(trackId)
36 , m_size(0)
37 , m_presentationSize(presentationSize)
38 , m_flags(MediaSample::IsSync)
39{
40
41 if (!sample)
42 return;
43
44 GstBuffer* buffer = gst_sample_get_buffer(sample);
45 if (!buffer)
46 return;
47
48 auto createMediaTime =
49 [](GstClockTime time) -> MediaTime {
50 return MediaTime(GST_TIME_AS_USECONDS(time), G_USEC_PER_SEC);
51 };
52
53 if (GST_BUFFER_PTS_IS_VALID(buffer))
54 m_pts = createMediaTime(GST_BUFFER_PTS(buffer));
55 if (GST_BUFFER_DTS_IS_VALID(buffer))
56 m_dts = createMediaTime(GST_BUFFER_DTS(buffer));
57 if (GST_BUFFER_DURATION_IS_VALID(buffer))
58 m_duration = createMediaTime(GST_BUFFER_DURATION(buffer));
59
60 m_size = gst_buffer_get_size(buffer);
61 m_sample = sample;
62
63 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT))
64 m_flags = MediaSample::None;
65
66 if (GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DECODE_ONLY))
67 m_flags = (MediaSample::SampleFlags) (m_flags | MediaSample::NonDisplaying);
68}
69
70PassRefPtr<GStreamerMediaSample> GStreamerMediaSample::create(GstSample* sample, const FloatSize& presentationSize, const AtomicString& trackId)
71{
72 return adoptRef(new GStreamerMediaSample(sample, presentationSize, trackId));
73}
74
75PassRefPtr<GStreamerMediaSample> GStreamerMediaSample::createFakeSample(GstCaps*, MediaTime pts, MediaTime dts, MediaTime duration, const FloatSize& presentationSize, const AtomicString& trackId)
76{
77 GStreamerMediaSample* gstreamerMediaSample = new GStreamerMediaSample(nullptr, presentationSize, trackId);
78 gstreamerMediaSample->m_pts = pts;
79 gstreamerMediaSample->m_dts = dts;
80 gstreamerMediaSample->m_duration = duration;
81 gstreamerMediaSample->m_flags = MediaSample::NonDisplaying;
82 return adoptRef(gstreamerMediaSample);
83}
84
85void GStreamerMediaSample::applyPtsOffset(MediaTime timestampOffset)
86{
87 if (m_pts > timestampOffset) {
88 m_duration = m_duration + (m_pts - timestampOffset);
89 m_pts = timestampOffset;
90 }
91}
92
93void GStreamerMediaSample::offsetTimestampsBy(const MediaTime& timestampOffset)
94{
95 if (!timestampOffset)
96 return;
97 m_pts += timestampOffset;
98 m_dts += timestampOffset;
99 GstBuffer* buffer = gst_sample_get_buffer(m_sample.get());
100 if (buffer) {
101 GST_BUFFER_PTS(buffer) = toGstClockTime(m_pts.toFloat());
102 GST_BUFFER_DTS(buffer) = toGstClockTime(m_dts.toFloat());
103 }
104}
105
106GStreamerMediaSample::~GStreamerMediaSample()
107{
108}
109
110} // namespace WebCore.
111
112#endif // USE(GSTREAMER)