1 /*
2 * GStreamer AVTP Plugin
3 * Copyright (C) 2019 Intel Corporation
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
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20 #include <avtp.h>
21 #include <avtp_aaf.h>
22 #include <avtp_cvf.h>
23 #include <glib.h>
24
25 #include "gstavtpcrfutil.h"
26
27 #define AVTP_CVF_H264_HEADER_SIZE (sizeof(struct avtp_stream_pdu) + sizeof(guint32))
28
29 gboolean
buffer_size_valid(GstMapInfo * info)30 buffer_size_valid (GstMapInfo * info)
31 {
32 struct avtp_stream_pdu *pdu;
33 guint64 subtype;
34 guint32 type;
35 int res;
36
37 if (info->size < sizeof (struct avtp_stream_pdu))
38 return FALSE;
39
40 pdu = (struct avtp_stream_pdu *) info->data;
41
42 res =
43 avtp_pdu_get ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, &type);
44 g_assert (res == 0);
45 res = avtp_cvf_pdu_get (pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE, &subtype);
46 g_assert (res == 0);
47
48 if (type == AVTP_SUBTYPE_CVF && subtype == AVTP_CVF_FORMAT_SUBTYPE_H264
49 && info->size < AVTP_CVF_H264_HEADER_SIZE)
50 return FALSE;
51
52 return TRUE;
53 }
54
55 GstClockTime
get_avtp_tstamp(GstAvtpCrfBase * avtpcrfbase,struct avtp_stream_pdu * pdu)56 get_avtp_tstamp (GstAvtpCrfBase * avtpcrfbase, struct avtp_stream_pdu * pdu)
57 {
58 guint64 tstamp = GST_CLOCK_TIME_NONE, tstamp_valid;
59 guint32 type;
60 int res;
61
62 res =
63 avtp_pdu_get ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, &type);
64 g_assert (res == 0);
65
66 switch (type) {
67 case AVTP_SUBTYPE_AAF:
68 res = avtp_aaf_pdu_get (pdu, AVTP_AAF_FIELD_TV, &tstamp_valid);
69 g_assert (res == 0);
70 if (!tstamp_valid)
71 break;
72
73 res = avtp_aaf_pdu_get (pdu, AVTP_AAF_FIELD_TIMESTAMP, &tstamp);
74 g_assert (res == 0);
75 break;
76 case AVTP_SUBTYPE_CVF:
77 res = avtp_cvf_pdu_get (pdu, AVTP_CVF_FIELD_TV, &tstamp_valid);
78 g_assert (res == 0);
79 if (!tstamp_valid)
80 break;
81
82 res = avtp_cvf_pdu_get (pdu, AVTP_CVF_FIELD_TIMESTAMP, &tstamp);
83 g_assert (res == 0);
84 break;
85 default:
86 GST_INFO_OBJECT (avtpcrfbase, "type 0x%x not supported.\n", type);
87 break;
88 }
89
90 return (GstClockTime) tstamp;
91 }
92
93 gboolean
h264_tstamp_valid(struct avtp_stream_pdu * pdu)94 h264_tstamp_valid (struct avtp_stream_pdu * pdu)
95 {
96 guint64 subtype, h264_time_valid;
97 guint32 type;
98 int res;
99
100 /*
101 * Validate H264 timestamp for H264 format. For more details about the
102 * timestamp look at IEEE 1722-2016 Section 8.5.3.1
103 */
104 res =
105 avtp_pdu_get ((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, &type);
106 g_assert (res == 0);
107 if (type == AVTP_SUBTYPE_CVF) {
108 res = avtp_cvf_pdu_get (pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE, &subtype);
109 g_assert (res == 0);
110 res = avtp_cvf_pdu_get (pdu, AVTP_CVF_FIELD_H264_PTV, &h264_time_valid);
111 g_assert (res == 0);
112
113 if (subtype == AVTP_CVF_FORMAT_SUBTYPE_H264 && h264_time_valid)
114 return TRUE;
115 }
116 return FALSE;
117 }
118