diff --git a/examples/cvf/cvf-listener.c b/examples/cvf/cvf-listener.c index 2d325a3..ddf2bbb 100644 --- a/examples/cvf/cvf-listener.c +++ b/examples/cvf/cvf-listener.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024, COVESA * Copyright (c) 2019, Intel Corporation * * Redistribution and use in source and binary forms, with or without @@ -9,9 +10,9 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -23,6 +24,8 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause */ /* CVF Listener example. @@ -67,17 +70,19 @@ #include #include #include +#include #include "avtp.h" -#include "avtp_cvf.h" -#include "common.h" +#include "avtp/cvf/Cvf.h" +#include "avtp/cvf/H264.h" #include "avtp/CommonHeader.h" +#include "common.h" -#define STREAM_ID 0xAABBCCDDEEFF0001 -#define DATA_LEN 1400 -#define AVTP_H264_HEADER_LEN (sizeof(uint32_t)) -#define AVTP_FULL_HEADER_LEN (sizeof(struct avtp_stream_pdu) + AVTP_H264_HEADER_LEN) -#define MAX_PDU_SIZE (AVTP_FULL_HEADER_LEN + DATA_LEN) +#define STREAM_ID 0xAABBCCDDEEFF0001 +#define DATA_LEN 1400 +#define AVTP_H264_HEADER_LEN (sizeof(Avtp_H264_t)) +#define AVTP_FULL_HEADER_LEN (sizeof(Avtp_Cvf_t) + sizeof(Avtp_H264_t)) +#define MAX_PDU_SIZE (AVTP_FULL_HEADER_LEN + DATA_LEN) struct nal_entry { STAILQ_ENTRY(nal_entry) entries; @@ -158,109 +163,104 @@ static int schedule_nal(int fd, struct timespec *tspec, uint8_t *nal, return 0; } -static bool is_valid_packet(struct avtp_stream_pdu *pdu) +static bool is_valid_packet(Avtp_Cvf_t* cvf) { - struct avtp_common_pdu *common = (struct avtp_common_pdu *) pdu; - uint64_t val64; - uint32_t val32; + uint64_t val; int res; - res = avtp_pdu_get(common, AVTP_FIELD_SUBTYPE, &val32); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_SUBTYPE, &val); if (res < 0) { fprintf(stderr, "Failed to get subtype field: %d\n", res); return false; } - if (val32 != AVTP_SUBTYPE_CVF) { - fprintf(stderr, "Subtype mismatch: expected %u, got %u\n", - AVTP_SUBTYPE_CVF, val32); + if (val != AVTP_SUBTYPE_CVF) { + fprintf(stderr, "Subtype mismatch: expected %u, got %"PRIu64"\n", AVTP_SUBTYPE_CVF, val); return false; } - res = avtp_pdu_get(common, AVTP_FIELD_VERSION, &val32); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_VERSION, &val); if (res < 0) { fprintf(stderr, "Failed to get version field: %d\n", res); return false; } - if (val32 != 0) { - fprintf(stderr, "Version mismatch: expected %u, got %u\n", - 0, val32); + if (val != 0) { + fprintf(stderr, "Version mismatch: expected %u, got %"PRIu64"\n", 0, val); return false; } - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_TV, &val64); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_TV, &val); if (res < 0) { fprintf(stderr, "Failed to get tv field: %d\n", res); return false; } - if (val64 != 1) { + if (val != 1) { fprintf(stderr, "tv mismatch: expected %u, got %lu\n", - 1, val64); + 1, val); return false; } - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_STREAM_ID, &val64); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_STREAM_ID, &val); if (res < 0) { fprintf(stderr, "Failed to get stream ID field: %d\n", res); return false; } - if (val64 != STREAM_ID) { + if (val != STREAM_ID) { fprintf(stderr, "Stream ID mismatch: expected %lu, got %lu\n", - STREAM_ID, val64); + STREAM_ID, val); return false; } - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_SEQ_NUM, &val64); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_SEQUENCE_NUM, &val); if (res < 0) { fprintf(stderr, "Failed to get sequence num field: %d\n", res); return false; } - if (val64 != expected_seq) { + if (val != expected_seq) { /* If we have a sequence number mismatch, we simply log the * issue and continue to process the packet. We don't want to * invalidate it since it is a valid packet after all. */ fprintf(stderr, "Sequence number mismatch: expected %u, got %lu\n", - expected_seq, val64); - expected_seq = val64; + expected_seq, val); + expected_seq = val; } expected_seq++; - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_FORMAT, &val64); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_FORMAT, &val); if (res < 0) { fprintf(stderr, "Failed to get format field: %d\n", res); return false; } - if (val64 != AVTP_CVF_FORMAT_RFC) { + if (val != AVTP_CVF_FORMAT_RFC) { fprintf(stderr, "Format mismatch: expected %u, got %lu\n", - AVTP_CVF_FORMAT_RFC, val64); + AVTP_CVF_FORMAT_RFC, val); return false; } - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE, &val64); + res = Avtp_Cvf_GetField(cvf, AVTP_CVF_FIELD_FORMAT_SUBTYPE, &val); if (res < 0) { fprintf(stderr, "Failed to get format subtype field: %d\n", res); return false; } - if (val64 != AVTP_CVF_FORMAT_SUBTYPE_H264) { + if (val != AVTP_CVF_FORMAT_SUBTYPE_H264) { fprintf(stderr, "Format mismatch: expected %u, got %lu\n", - AVTP_CVF_FORMAT_SUBTYPE_H264, val64); + AVTP_CVF_FORMAT_SUBTYPE_H264, val); return false; } return true; } -static int get_h264_data_len(struct avtp_stream_pdu *pdu, - uint16_t *stream_data_len) +static int get_h264_data_len(Avtp_Cvf_t* cvfHeader, uint16_t *stream_data_len) { int res; uint64_t val; - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, &val); + res = Avtp_Cvf_GetField(cvfHeader, AVTP_CVF_FIELD_STREAM_DATA_LENGTH, &val); if (res < 0) { fprintf(stderr, "Failed to get data_len field\n"); return -1; @@ -277,24 +277,24 @@ static int new_packet(int sk_fd, int timer_fd) uint16_t h264_data_len; uint64_t avtp_time; struct timespec tspec; - struct avtp_stream_pdu *pdu = alloca(MAX_PDU_SIZE); - struct avtp_cvf_h264_payload *h264_pay = - (struct avtp_cvf_h264_payload *)pdu->avtp_payload; + Avtp_Cvf_t* cvfHeader = alloca(MAX_PDU_SIZE); + Avtp_H264_t* h264Header = (Avtp_H264_t*)(&cvfHeader->payload); + uint8_t* h264Payload = (uint8_t*)(&h264Header->payload); - memset(pdu, 1, MAX_PDU_SIZE); + memset(cvfHeader, 1, MAX_PDU_SIZE); - n = recv(sk_fd, pdu, MAX_PDU_SIZE, 0); + n = recv(sk_fd, cvfHeader, MAX_PDU_SIZE, 0); if (n < 0 || n > MAX_PDU_SIZE) { perror("Failed to receive data"); return -1; } - if (!is_valid_packet(pdu)) { + if (!is_valid_packet(cvfHeader)) { fprintf(stderr, "Dropping packet\n"); return 0; } - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_TIMESTAMP, &avtp_time); + res = Avtp_Cvf_GetField(cvfHeader, AVTP_CVF_FIELD_AVTP_TIMESTAMP, &avtp_time); if (res < 0) { fprintf(stderr, "Failed to get AVTP time from PDU\n"); return -1; @@ -304,12 +304,11 @@ static int new_packet(int sk_fd, int timer_fd) if (res < 0) return -1; - res = get_h264_data_len(pdu, &h264_data_len); + res = get_h264_data_len(cvfHeader, &h264_data_len); if (res < 0) return -1; - res = schedule_nal(timer_fd, &tspec, h264_pay->h264_data, - h264_data_len); + res = schedule_nal(timer_fd, &tspec, h264Payload, h264_data_len); if (res < 0) return -1; diff --git a/examples/cvf/cvf-talker.c b/examples/cvf/cvf-talker.c index f10ff9e..5a36d5c 100644 --- a/examples/cvf/cvf-talker.c +++ b/examples/cvf/cvf-talker.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2024, COVESA * Copyright (c) 2019, Intel Corporation * * Redistribution and use in source and binary forms, with or without @@ -9,9 +10,9 @@ * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -23,6 +24,8 @@ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause */ /* CVF Talker example. @@ -73,15 +76,16 @@ #include #include "avtp.h" -#include "avtp_cvf.h" +#include "avtp/cvf/Cvf.h" +#include "avtp/cvf/H264.h" #include "common.h" #include "avtp/CommonHeader.h" -#define STREAM_ID 0xAABBCCDDEEFF0001 -#define DATA_LEN 1400 -#define AVTP_H264_HEADER_LEN (sizeof(uint32_t)) -#define AVTP_FULL_HEADER_LEN (sizeof(struct avtp_stream_pdu) + AVTP_H264_HEADER_LEN) -#define MAX_PDU_SIZE (AVTP_FULL_HEADER_LEN + DATA_LEN) +#define STREAM_ID 0xAABBCCDDEEFF0001 +#define DATA_LEN 1400 +#define AVTP_H264_HEADER_LEN (sizeof(Avtp_H264_t)) +#define AVTP_FULL_HEADER_LEN (sizeof(Avtp_Cvf_t) + sizeof(Avtp_H264_t)) +#define MAX_PDU_SIZE (AVTP_FULL_HEADER_LEN + DATA_LEN) static char ifname[IFNAMSIZ]; static uint8_t macaddr[ETH_ALEN]; @@ -134,36 +138,18 @@ static error_t parser(int key, char *arg, struct argp_state *state) static struct argp argp = { options, parser }; -static int init_pdu(struct avtp_stream_pdu *pdu) +static int init_pdu(Avtp_Cvf_t* cvf) { - int res; - - res = avtp_cvf_pdu_init(pdu, AVTP_CVF_FORMAT_SUBTYPE_H264); - if (res < 0) - return -1; - - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_TV, 1); - if (res < 0) - return -1; + Avtp_Cvf_Init(cvf); + Avtp_Cvf_SetField(cvf, AVTP_CVF_FIELD_FORMAT_SUBTYPE, AVTP_CVF_FORMAT_SUBTYPE_H264); + Avtp_Cvf_SetField(cvf, AVTP_CVF_FIELD_TV, 1); + Avtp_Cvf_SetField(cvf, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID); + Avtp_Cvf_SetField(cvf, AVTP_CVF_FIELD_M, 1); + Avtp_Cvf_SetField(cvf, AVTP_CVF_FIELD_PTV, 0); - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_STREAM_ID, STREAM_ID); - if (res < 0) - return -1; - - /* Just state that all data is part of the frame (M=1) */ - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_M, 1); - if (res < 0) - return -1; - - /* No H.264 timestamp now */ - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 0); - if (res < 0) - return -1; - - /* No H.264 timestamp means no PTV */ - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_H264_PTV, 0); - if (res < 0) - return -1; + Avtp_H264_t* h264 = (Avtp_H264_t*)(&cvf->payload); + Avtp_H264_Init(h264); + Avtp_H264_SetField(h264, AVTP_H264_FIELD_TIMESTAMP, 0); return 0; } @@ -203,13 +189,12 @@ static ssize_t start_code_position(size_t offset) return -1; } -static int prepare_packet(struct avtp_stream_pdu *pdu, char *nal_data, - size_t nal_data_len) +static int prepare_packet(Avtp_Cvf_t* cvfHeader, char *nal_data, size_t nal_data_len) { int res; uint32_t avtp_time; - struct avtp_cvf_h264_payload *h264_pay = - (struct avtp_cvf_h264_payload *) pdu->avtp_payload; + Avtp_H264_t* h264Header = (Avtp_H264_t*)(&cvfHeader->payload); + uint8_t* h264Payload = (uint8_t*)(&h264Header->payload); res = calculate_avtp_time(&avtp_time, max_transit_time); if (res < 0) { @@ -217,29 +202,17 @@ static int prepare_packet(struct avtp_stream_pdu *pdu, char *nal_data, return -1; } - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_TIMESTAMP, - avtp_time); - if (res < 0) - return -1; - - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_SEQ_NUM, seq_num++); - if (res < 0) - return -1; - - /* Stream data len includes AVTP H264 header, as this is part - * of the payload too*/ - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, - nal_data_len + AVTP_H264_HEADER_LEN); - if (res < 0) - return -1; + Avtp_Cvf_SetField(cvfHeader, AVTP_CVF_FIELD_AVTP_TIMESTAMP, avtp_time); + Avtp_Cvf_SetField(cvfHeader, AVTP_CVF_FIELD_SEQUENCE_NUM, seq_num++); + Avtp_Cvf_SetField(cvfHeader, AVTP_CVF_FIELD_STREAM_DATA_LENGTH, nal_data_len + AVTP_H264_HEADER_LEN); - memcpy(h264_pay->h264_data, nal_data, nal_data_len); + memcpy(h264Payload, nal_data, nal_data_len); return 0; } -static int process_nal(struct avtp_stream_pdu *pdu, bool process_last, - size_t *nal_len) +static int process_nal(Avtp_Cvf_t* pdu, bool process_last, + size_t* nal_len) { int res; ssize_t start, end; @@ -289,7 +262,8 @@ int main(int argc, char *argv[]) { int fd, res; struct sockaddr_ll sk_addr; - struct avtp_stream_pdu *pdu = alloca(MAX_PDU_SIZE); + uint8_t* pdu = alloca(MAX_PDU_SIZE); + Avtp_Cvf_t* cvf = (Avtp_Cvf_t*)pdu; argp_parse(&argp, argc, argv, 0, NULL, NULL); @@ -301,7 +275,7 @@ int main(int argc, char *argv[]) if (res < 0) goto err; - res = init_pdu(pdu); + res = init_pdu(cvf); if (res < 0) goto err; @@ -315,7 +289,7 @@ int main(int argc, char *argv[]) while (buffer_level > 0) { enum process_result pr = - process_nal(pdu, end, (size_t *)&n); + process_nal(cvf, end, (size_t *)&n); if (pr == PROCESS_ERROR) goto err; if (pr == PROCESS_NONE) diff --git a/include/avtp/cvf/Cvf.h b/include/avtp/cvf/Cvf.h new file mode 100644 index 0000000..1f10e8e --- /dev/null +++ b/include/avtp/cvf/Cvf.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +#include "avtp/Utils.h" + +#define AVTP_CVF_HEADER_LEN (6 * AVTP_QUADLET_SIZE) + +typedef struct Avtp_Cvf { + uint8_t header[AVTP_CVF_HEADER_LEN]; + uint8_t payload[0]; +} Avtp_Cvf_t; + +typedef enum Avtp_CvfField { + /* CVF header fields */ + AVTP_CVF_FIELD_SUBTYPE, + AVTP_CVF_FIELD_SV, + AVTP_CVF_FIELD_VERSION, + AVTP_CVF_FIELD_MR, + AVTP_CVF_FIELD_RESERVED, + AVTP_CVF_FIELD_TV, + AVTP_CVF_FIELD_SEQUENCE_NUM, + AVTP_CVF_FIELD_RESERVED_2, + AVTP_CVF_FIELD_TU, + AVTP_CVF_FIELD_STREAM_ID, + AVTP_CVF_FIELD_AVTP_TIMESTAMP, + AVTP_CVF_FIELD_FORMAT, + AVTP_CVF_FIELD_FORMAT_SUBTYPE, + AVTP_CVF_FIELD_RESERVED_3, + AVTP_CVF_FIELD_STREAM_DATA_LENGTH, + AVTP_CVF_FIELD_RESERVED_4, + AVTP_CVF_FIELD_PTV, + AVTP_CVF_FIELD_M, + AVTP_CVF_FIELD_EVT, + AVTP_CVF_FIELD_RESERVED_5, + /* Count number of fields for bound checks */ + AVTP_CVF_FIELD_MAX +} Avtp_CvfField_t; + +typedef enum Avtp_CvfFormat { + AVTP_CVF_FORMAT_RFC = 0x2 +} Avtp_CvfFormat_t; + +typedef enum Avtp_CvfFormatSubtype { + AVTP_CVF_FORMAT_SUBTYPE_MJPEG = 0x0, + AVTP_CVF_FORMAT_SUBTYPE_H264 = 0x1, + AVTP_CVF_FORMAT_SUBTYPE_JPEG2000 = 0x2 +} Avtp_CvfFormatSubtype_t; + +int Avtp_Cvf_Init(Avtp_Cvf_t* pdu); + +int Avtp_Cvf_GetField(Avtp_Cvf_t* pdu, Avtp_CvfField_t field, uint64_t* value); + +int Avtp_Cvf_SetField(Avtp_Cvf_t* pdu, Avtp_CvfField_t field, uint64_t value); + +/****************************************************************************** + * Legacy API (deprecated) + *****************************************************************************/ + +/** + * @deprecated + */ +int avtp_cvf_pdu_get(void* pdu, Avtp_CvfField_t field, uint64_t *val); + +/** + * @deprecated + */ +int avtp_cvf_pdu_set(void* pdu, Avtp_CvfField_t field, uint64_t val); + +/** + * @deprecated + */ +int avtp_cvf_pdu_init(void* pdu, uint8_t format_subtype); + diff --git a/include/avtp/cvf/H264.h b/include/avtp/cvf/H264.h new file mode 100644 index 0000000..ca59a96 --- /dev/null +++ b/include/avtp/cvf/H264.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +#include "avtp/Utils.h" + +#define AVTP_H246_HEADER_LEN (1 * AVTP_QUADLET_SIZE) + +typedef struct Avtp_H264 { + uint8_t header[AVTP_H246_HEADER_LEN]; + uint8_t payload[0]; +} Avtp_H264_t; + +typedef enum Avtp_H264Field { + /* H264 header fields */ + AVTP_H264_FIELD_TIMESTAMP, + /* Count number of fields for bound checks */ + AVTP_H264_FIELD_MAX, +} Avtp_H264Field_t; + +int Avtp_H264_Init(Avtp_H264_t* pdu); + +int Avtp_H264_GetField(Avtp_H264_t* pdu, Avtp_H264Field_t field, uint64_t* value); + +int Avtp_H264_SetField(Avtp_H264_t* pdu, Avtp_H264Field_t field, uint64_t value); diff --git a/include/avtp/cvf/Jpeg2000.h b/include/avtp/cvf/Jpeg2000.h new file mode 100644 index 0000000..7e5b3d0 --- /dev/null +++ b/include/avtp/cvf/Jpeg2000.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +#include "avtp/Utils.h" + +#define AVTP_JPEG2000_HEADER_LEN (2 * AVTP_QUADLET_SIZE) + +typedef struct Avtp_Jpeg2000 { + uint8_t header[AVTP_JPEG2000_HEADER_LEN]; + uint8_t payload[0]; +} Avtp_Jpeg2000_t; + +typedef enum Avtp_Jpeg2000Field { + /* MJPEG header fields */ + AVTP_JPEG2000_FIELD_TP, + AVTP_JPEG2000_FIELD_MHF, + AVTP_JPEG2000_FIELD_MH_ID, + AVTP_JPEG2000_FIELD_T, + AVTP_JPEG2000_FIELD_PRIORITY, + AVTP_JPEG2000_FIELD_TILE_NUMBER, + AVTP_JPEG2000_FIELD_RESERVED, + AVTP_JPEG2000_FIELD_FRAGMENT_OFFSET, + /* Count number of fields for bound checks */ + AVTP_JPEG2000_FIELD_MAX +} Avtp_Jpeg2000Field_t; + +int Avtp_Jpeg2000_Init(Avtp_Jpeg2000_t* pdu); + +int Avtp_Jpeg2000_GetField(Avtp_Jpeg2000_t* pdu, Avtp_Jpeg2000Field_t field, uint64_t* value); + +int Avtp_Jpeg2000_SetField(Avtp_Jpeg2000_t* pdu, Avtp_Jpeg2000Field_t field, uint64_t value); diff --git a/include/avtp/cvf/Mjpeg.h b/include/avtp/cvf/Mjpeg.h new file mode 100644 index 0000000..abeb10b --- /dev/null +++ b/include/avtp/cvf/Mjpeg.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#pragma once + +#include + +#include "avtp/Utils.h" + +#define AVTP_MJPEG_HEADER_LEN (2 * AVTP_QUADLET_SIZE) + +typedef struct Avtp_Mjpeg { + uint8_t header[AVTP_MJPEG_HEADER_LEN]; + uint8_t payload[0]; +} Avtp_Mjpeg_t; + +typedef enum Avtp_MjpegField { + /* MJPEG header fields */ + AVTP_MJPEG_FIELD_TYPE_SPECIFIC, + AVTP_MJPEG_FIELD_FRAGMENT_OFFSET, + AVTP_MJPEG_FIELD_TYPE, + AVTP_MJPEG_FIELD_Q, + AVTP_MJPEG_FIELD_WIDTH, + AVTP_MJPEG_FIELD_HEIGHT, + /* Count number of fields for bound checks */ + AVTP_MJPEG_FIELD_MAX +} Avtp_MjpegField_t; + +int Avtp_Mjpeg_Init(Avtp_Mjpeg_t* pdu); + +int Avtp_Mjpeg_GetField(Avtp_Mjpeg_t* pdu, Avtp_MjpegField_t field, uint64_t* value); + +int Avtp_Mjpeg_SetField(Avtp_Mjpeg_t* pdu, Avtp_MjpegField_t field, uint64_t value); diff --git a/include/avtp_cvf.h b/include/avtp_cvf.h deleted file mode 100644 index f2c2887..0000000 --- a/include/avtp_cvf.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* CVF 'format' field values. */ -#define AVTP_CVF_FORMAT_RFC 0x02 - -/* CVF 'format subtype' field values. */ -#define AVTP_CVF_FORMAT_SUBTYPE_MJPEG 0x00 -#define AVTP_CVF_FORMAT_SUBTYPE_H264 0x01 -#define AVTP_CVF_FORMAT_SUBTYPE_JPEG2000 0x02 - -enum avtp_cvf_field { - AVTP_CVF_FIELD_SV, - AVTP_CVF_FIELD_MR, - AVTP_CVF_FIELD_TV, - AVTP_CVF_FIELD_SEQ_NUM, - AVTP_CVF_FIELD_TU, - AVTP_CVF_FIELD_STREAM_ID, - AVTP_CVF_FIELD_TIMESTAMP, - AVTP_CVF_FIELD_STREAM_DATA_LEN, - AVTP_CVF_FIELD_FORMAT, - AVTP_CVF_FIELD_FORMAT_SUBTYPE, - AVTP_CVF_FIELD_M, - AVTP_CVF_FIELD_EVT, - AVTP_CVF_FIELD_H264_PTV, - AVTP_CVF_FIELD_H264_TIMESTAMP, - AVTP_CVF_FIELD_MAX, -}; - -struct avtp_cvf_h264_payload { - uint32_t h264_header; - uint8_t h264_data[0]; -} __attribute__((__packed__)); - -/* Get value of CVF AVTPDU field. - * @pdu: Pointer to PDU struct. - * @field: PDU field to be retrieved. - * @val: Pointer to variable which the retrieved value should be saved. - * - * Returns: - * 0: Success. - * -EINVAL: If any argument is invalid. - */ -int avtp_cvf_pdu_get(const struct avtp_stream_pdu *pdu, - enum avtp_cvf_field field, uint64_t *val); - -/* Set value of CVF AVTPDU field. - * @pdu: Pointer to PDU struct. - * @field: PDU field to be set. - * @val: Value to be set. - * - * Returns: - * 0: Success. - * -EINVAL: If any argument is invalid. - */ -int avtp_cvf_pdu_set(struct avtp_stream_pdu *pdu, enum avtp_cvf_field field, - uint64_t val); - -/* Initialize CVF AVTPDU. All AVTPDU fields are initialized with zero except - * 'subtype' (which is set to AVTP_SUBTYPE_CVF), 'sv' (which is set to 1), - * 'format' (which is set to AVTP_CVF_FORMAT_RFC) and 'format_subtype' (which is - * set to the `subtype` specified). - * @pdu: Pointer to PDU struct. - * @subtype: AVTP - * CVF Format Subtype of this AVTPDU. - * - * Return values: 0: Success. -EINVAL: If any argument is invalid. - */ -int avtp_cvf_pdu_init(struct avtp_stream_pdu *pdu, uint8_t subtype); - -#ifdef __cplusplus -} -#endif diff --git a/meson.build b/meson.build index 01cf6ea..bf4be5c 100644 --- a/meson.build +++ b/meson.build @@ -10,7 +10,6 @@ avtp_lib = library( 'open1722', [ 'src/avtp.c', - 'src/avtp_cvf.c', 'src/avtp_ieciidc.c', 'src/avtp_stream.c', @@ -28,6 +27,10 @@ avtp_lib = library( 'src/avtp/Udp.c', 'src/avtp/Rvf.c', 'src/avtp/Crf.c', + 'src/avtp/cvf/Cvf.c', + 'src/avtp/cvf/H264.c', + 'src/avtp/cvf/Jpeg2000.c', + 'src/avtp/cvf/Mjpeg.c', ], version: meson.project_version(), include_directories: include_directories('include'), @@ -67,6 +70,14 @@ install_headers( subdir : 'avtp/aaf' ) +install_headers( + 'src/avtp/cvf/Cvf.c', + 'src/avtp/cvf/H264.c', + 'src/avtp/cvf/Jpeg2000.c', + 'src/avtp/cvf/Mjpeg.c', + subdir : 'avtp/cvf' +) + pkg = import('pkgconfig') pkg.generate(avtp_lib, description: 'AVTP packetization library', diff --git a/src/avtp/cvf/Cvf.c b/src/avtp/cvf/Cvf.c new file mode 100644 index 0000000..1e537dc --- /dev/null +++ b/src/avtp/cvf/Cvf.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "avtp/cvf/Cvf.h" +#include "avtp/Utils.h" +#include "avtp/CommonHeader.h" + +static const Avtp_FieldDescriptor_t fieldDescriptors[AVTP_CVF_FIELD_MAX] = +{ + [AVTP_CVF_FIELD_SUBTYPE] = { .quadlet = 0, .offset = 0, .bits = 8 }, + [AVTP_CVF_FIELD_SV] = { .quadlet = 0, .offset = 8, .bits = 1 }, + [AVTP_CVF_FIELD_VERSION] = { .quadlet = 0, .offset = 9, .bits = 3 }, + [AVTP_CVF_FIELD_MR] = { .quadlet = 0, .offset = 12, .bits = 1 }, + [AVTP_CVF_FIELD_RESERVED] = { .quadlet = 0, .offset = 13, .bits = 2 }, + [AVTP_CVF_FIELD_TV] = { .quadlet = 0, .offset = 15, .bits = 1 }, + [AVTP_CVF_FIELD_SEQUENCE_NUM] = { .quadlet = 0, .offset = 16, .bits = 8 }, + [AVTP_CVF_FIELD_RESERVED_2] = { .quadlet = 0, .offset = 24, .bits = 7 }, + [AVTP_CVF_FIELD_TU] = { .quadlet = 0, .offset = 31, .bits = 1 }, + [AVTP_CVF_FIELD_STREAM_ID] = { .quadlet = 1, .offset = 0, .bits = 64 }, + [AVTP_CVF_FIELD_AVTP_TIMESTAMP] = { .quadlet = 3, .offset = 0, .bits = 32 }, + [AVTP_CVF_FIELD_FORMAT] = { .quadlet = 4, .offset = 0, .bits = 8 }, + [AVTP_CVF_FIELD_FORMAT_SUBTYPE] = { .quadlet = 4, .offset = 8, .bits = 8 }, + [AVTP_CVF_FIELD_RESERVED_3] = { .quadlet = 4, .offset = 16, .bits = 16 }, + [AVTP_CVF_FIELD_STREAM_DATA_LENGTH] = { .quadlet = 5, .offset = 0, .bits = 16 }, + [AVTP_CVF_FIELD_RESERVED_4] = { .quadlet = 5, .offset = 16, .bits = 2 }, + [AVTP_CVF_FIELD_PTV] = { .quadlet = 5, .offset = 18, .bits = 1 }, + [AVTP_CVF_FIELD_M] = { .quadlet = 5, .offset = 19, .bits = 1 }, + [AVTP_CVF_FIELD_EVT] = { .quadlet = 5, .offset = 20, .bits = 4 }, + [AVTP_CVF_FIELD_RESERVED_5] = { .quadlet = 5, .offset = 24, .bits = 8 }, +}; + +int Avtp_Cvf_Init(Avtp_Cvf_t* pdu) +{ + if (pdu == NULL) return -EINVAL; + + memset(pdu, 0, sizeof(Avtp_Cvf_t)); + + int ret; + ret = Avtp_Cvf_SetField(pdu, AVTP_CVF_FIELD_SUBTYPE, AVTP_SUBTYPE_CVF); + if (ret != 0) return ret; + ret = Avtp_Cvf_SetField(pdu, AVTP_CVF_FIELD_SV, 1); + if (ret != 0) return ret; + + return 0; +} + +int Avtp_Cvf_GetField(Avtp_Cvf_t* pdu, Avtp_CvfField_t field, uint64_t* value) +{ + return Avtp_GetField(fieldDescriptors, AVTP_CVF_FIELD_MAX, (uint8_t*)pdu, field, value); +} + +int Avtp_Cvf_SetField(Avtp_Cvf_t* pdu, Avtp_CvfField_t field, uint64_t value) +{ + return Avtp_SetField(fieldDescriptors, AVTP_CVF_FIELD_MAX, (uint8_t*)pdu, field, value); +} + +/****************************************************************************** + * Legacy API (deprecated) + *****************************************************************************/ + +int avtp_cvf_pdu_get(void* pdu, Avtp_CvfField_t field, uint64_t *val) +{ + return Avtp_Cvf_GetField((Avtp_Cvf_t*)pdu, field, val); +} + +int avtp_cvf_pdu_set(void* pdu, Avtp_CvfField_t field, uint64_t val) +{ + return Avtp_Cvf_SetField((Avtp_Cvf_t*)pdu, field, val); +} + +int avtp_cvf_pdu_init(void* pdu, uint8_t format_subtype) +{ + int ret; + ret = Avtp_Cvf_Init((Avtp_Cvf_t*)pdu); + if (ret != 0) return ret; + ret = Avtp_Cvf_SetField(pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE, format_subtype); + if (ret != 0) return ret; + ret = Avtp_Cvf_SetField(pdu, AVTP_CVF_FIELD_FORMAT, AVTP_CVF_FORMAT_RFC); + if (ret != 0) return ret; + + return 0; +} diff --git a/src/avtp/cvf/H264.c b/src/avtp/cvf/H264.c new file mode 100644 index 0000000..20963de --- /dev/null +++ b/src/avtp/cvf/H264.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "avtp/cvf/H264.h" +#include "avtp/Utils.h" +#include "avtp/CommonHeader.h" + +static const Avtp_FieldDescriptor_t fieldDescriptors[AVTP_H264_FIELD_MAX] = +{ + [AVTP_H264_FIELD_TIMESTAMP] = { .quadlet = 0, .offset = 0, .bits = 32 }, +}; + +int Avtp_H264_Init(Avtp_H264_t* pdu) +{ + if (pdu == NULL) return -EINVAL; + memset(pdu, 0, sizeof(Avtp_H264_t)); + return 0; +} + +int Avtp_H264_GetField(Avtp_H264_t* pdu, Avtp_H264Field_t field, uint64_t* value) +{ + return Avtp_GetField(fieldDescriptors, AVTP_H264_FIELD_MAX, (uint8_t*)pdu, field, value); +} + +int Avtp_H264_SetField(Avtp_H264_t* pdu, Avtp_H264Field_t field, uint64_t value) +{ + return Avtp_SetField(fieldDescriptors, AVTP_H264_FIELD_MAX, (uint8_t*)pdu, field, value); +} diff --git a/src/avtp/cvf/Jpeg2000.c b/src/avtp/cvf/Jpeg2000.c new file mode 100644 index 0000000..1cc0e9f --- /dev/null +++ b/src/avtp/cvf/Jpeg2000.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "avtp/cvf/Jpeg2000.h" +#include "avtp/Utils.h" +#include "avtp/CommonHeader.h" + +static const Avtp_FieldDescriptor_t fieldDescriptors[AVTP_JPEG2000_FIELD_MAX] = +{ + [AVTP_JPEG2000_FIELD_TP] = { .quadlet = 0, .offset = 0, .bits = 2 }, + [AVTP_JPEG2000_FIELD_MHF] = { .quadlet = 0, .offset = 2, .bits = 2 }, + [AVTP_JPEG2000_FIELD_MH_ID] = { .quadlet = 0, .offset = 4, .bits = 3 }, + [AVTP_JPEG2000_FIELD_T] = { .quadlet = 0, .offset = 7, .bits = 1 }, + [AVTP_JPEG2000_FIELD_PRIORITY] = { .quadlet = 0, .offset = 8, .bits = 8 }, + [AVTP_JPEG2000_FIELD_TILE_NUMBER] = { .quadlet = 0, .offset = 16, .bits = 16 }, + [AVTP_JPEG2000_FIELD_RESERVED] = { .quadlet = 1, .offset = 0, .bits = 8 }, + [AVTP_JPEG2000_FIELD_FRAGMENT_OFFSET] = { .quadlet = 1, .offset = 8, .bits = 24 }, +}; + +int Avtp_Jpeg2000_Init(Avtp_Jpeg2000_t* pdu) +{ + if (pdu == NULL) return -EINVAL; + memset(pdu, 0, sizeof(Avtp_Jpeg2000_t)); + return 0; +} + +int Avtp_Jpeg2000_GetField(Avtp_Jpeg2000_t* pdu, Avtp_Jpeg2000Field_t field, uint64_t* value) +{ + return Avtp_GetField(fieldDescriptors, AVTP_JPEG2000_FIELD_MAX, (uint8_t*)pdu, field, value); +} + +int Avtp_Jpeg2000_SetField(Avtp_Jpeg2000_t* pdu, Avtp_Jpeg2000Field_t field, uint64_t value) +{ + return Avtp_SetField(fieldDescriptors, AVTP_JPEG2000_FIELD_MAX, (uint8_t*)pdu, field, value); +} diff --git a/src/avtp/cvf/Mjpeg.c b/src/avtp/cvf/Mjpeg.c new file mode 100644 index 0000000..a108d98 --- /dev/null +++ b/src/avtp/cvf/Mjpeg.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024, COVESA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of COVESA, Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "avtp/cvf/Mjpeg.h" +#include "avtp/Utils.h" +#include "avtp/CommonHeader.h" + +static const Avtp_FieldDescriptor_t fieldDescriptors[AVTP_MJPEG_FIELD_MAX] = +{ + [AVTP_MJPEG_FIELD_TYPE_SPECIFIC] = { .quadlet = 0, .offset = 0, .bits = 8 }, + [AVTP_MJPEG_FIELD_FRAGMENT_OFFSET] = { .quadlet = 0, .offset = 8, .bits = 24 }, + [AVTP_MJPEG_FIELD_TYPE] = { .quadlet = 1, .offset = 0, .bits = 8 }, + [AVTP_MJPEG_FIELD_Q] = { .quadlet = 1, .offset = 8, .bits = 8 }, + [AVTP_MJPEG_FIELD_WIDTH] = { .quadlet = 1, .offset = 16, .bits = 8 }, + [AVTP_MJPEG_FIELD_HEIGHT] = { .quadlet = 1, .offset = 24, .bits = 8 }, +}; + +int Avtp_Mjpeg_Init(Avtp_Mjpeg_t* pdu) +{ + if (pdu == NULL) return -EINVAL; + memset(pdu, 0, sizeof(Avtp_Mjpeg_t)); + return 0; +} + +int Avtp_Mjpeg_GetField(Avtp_Mjpeg_t* pdu, Avtp_MjpegField_t field, uint64_t* value) +{ + return Avtp_GetField(fieldDescriptors, AVTP_MJPEG_FIELD_MAX, (uint8_t*)pdu, field, value); +} + +int Avtp_Mjpeg_SetField(Avtp_Mjpeg_t* pdu, Avtp_MjpegField_t field, uint64_t value) +{ + return Avtp_SetField(fieldDescriptors, AVTP_MJPEG_FIELD_MAX, (uint8_t*)pdu, field, value); +} diff --git a/src/avtp_cvf.c b/src/avtp_cvf.c deleted file mode 100644 index f91bfbd..0000000 --- a/src/avtp_cvf.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#include "avtp.h" -#include "avtp_cvf.h" -#include "avtp_stream.h" -#include "util.h" -#include "avtp/CommonHeader.h" - -#define SHIFT_FORMAT (31 - 7) -#define SHIFT_FORMAT_SUBTYPE (31 - 15) -#define SHIFT_M (31 - 19) -#define SHIFT_EVT (31 - 23) -#define SHIFT_PTV (31 - 18) - -#define MASK_FORMAT (BITMASK(8) << SHIFT_FORMAT) -#define MASK_FORMAT_SUBTYPE (BITMASK(8) << SHIFT_FORMAT_SUBTYPE) -#define MASK_M (BITMASK(1) << SHIFT_M) -#define MASK_EVT (BITMASK(4) << SHIFT_EVT) -#define MASK_PTV (BITMASK(1) << SHIFT_PTV) - -static int get_field_value(const struct avtp_stream_pdu *pdu, - enum avtp_cvf_field field, uint64_t *val) -{ - uint32_t bitmap, mask; - uint8_t shift; - - switch (field) { - case AVTP_CVF_FIELD_FORMAT: - mask = MASK_FORMAT; - shift = SHIFT_FORMAT; - bitmap = ntohl(pdu->format_specific); - break; - case AVTP_CVF_FIELD_FORMAT_SUBTYPE: - mask = MASK_FORMAT_SUBTYPE; - shift = SHIFT_FORMAT_SUBTYPE; - bitmap = ntohl(pdu->format_specific); - break; - case AVTP_CVF_FIELD_M: - mask = MASK_M; - shift = SHIFT_M; - bitmap = ntohl(pdu->packet_info); - break; - case AVTP_CVF_FIELD_EVT: - mask = MASK_EVT; - shift = SHIFT_EVT; - bitmap = ntohl(pdu->packet_info); - break; - case AVTP_CVF_FIELD_H264_PTV: - mask = MASK_PTV; - shift = SHIFT_PTV; - bitmap = ntohl(pdu->packet_info); - break; - default: - return -EINVAL; - } - - *val = BITMAP_GET_VALUE(bitmap, mask, shift); - - return 0; -} - -int avtp_cvf_pdu_get(const struct avtp_stream_pdu *pdu, - enum avtp_cvf_field field, uint64_t *val) -{ - int res; - - if (!pdu || !val) - return -EINVAL; - - switch (field) { - case AVTP_CVF_FIELD_SV: - case AVTP_CVF_FIELD_MR: - case AVTP_CVF_FIELD_TV: - case AVTP_CVF_FIELD_SEQ_NUM: - case AVTP_CVF_FIELD_TU: - case AVTP_CVF_FIELD_STREAM_DATA_LEN: - case AVTP_CVF_FIELD_TIMESTAMP: - case AVTP_CVF_FIELD_STREAM_ID: - res = avtp_stream_pdu_get(pdu, (enum avtp_stream_field) field, - val); - break; - case AVTP_CVF_FIELD_FORMAT: - case AVTP_CVF_FIELD_FORMAT_SUBTYPE: - case AVTP_CVF_FIELD_M: - case AVTP_CVF_FIELD_EVT: - case AVTP_CVF_FIELD_H264_PTV: - res = get_field_value(pdu, field, val); - break; - case AVTP_CVF_FIELD_H264_TIMESTAMP: - { - /* This field lives on H.264 header, inside avtp_payload */ - struct avtp_cvf_h264_payload *pay = - (struct avtp_cvf_h264_payload *)pdu->avtp_payload; - *val = ntohl(pay->h264_header); - res = 0; - break; - } - default: - res = -EINVAL; - break; - } - - return res; -} - -static int set_field_value(struct avtp_stream_pdu *pdu, - enum avtp_cvf_field field, uint32_t val) -{ - uint32_t bitmap, mask; - uint8_t shift; - void *ptr; - - switch (field) { - case AVTP_CVF_FIELD_FORMAT: - mask = MASK_FORMAT; - shift = SHIFT_FORMAT; - ptr = &pdu->format_specific; - break; - case AVTP_CVF_FIELD_FORMAT_SUBTYPE: - mask = MASK_FORMAT_SUBTYPE; - shift = SHIFT_FORMAT_SUBTYPE; - ptr = &pdu->format_specific; - break; - case AVTP_CVF_FIELD_M: - mask = MASK_M; - shift = SHIFT_M; - ptr = &pdu->packet_info; - break; - case AVTP_CVF_FIELD_EVT: - mask = MASK_EVT; - shift = SHIFT_EVT; - ptr = &pdu->packet_info; - break; - case AVTP_CVF_FIELD_H264_PTV: - mask = MASK_PTV; - shift = SHIFT_PTV; - ptr = &pdu->packet_info; - break; - default: - return -EINVAL; - } - - bitmap = get_unaligned_be32(ptr); - - BITMAP_SET_VALUE(bitmap, val, mask, shift); - - put_unaligned_be32(bitmap, ptr); - - return 0; -} - -int avtp_cvf_pdu_set(struct avtp_stream_pdu *pdu, enum avtp_cvf_field field, - uint64_t val) -{ - int res; - - if (!pdu) - return -EINVAL; - - switch (field) { - case AVTP_CVF_FIELD_SV: - case AVTP_CVF_FIELD_MR: - case AVTP_CVF_FIELD_TV: - case AVTP_CVF_FIELD_SEQ_NUM: - case AVTP_CVF_FIELD_TU: - case AVTP_CVF_FIELD_STREAM_DATA_LEN: - case AVTP_CVF_FIELD_TIMESTAMP: - case AVTP_CVF_FIELD_STREAM_ID: - res = avtp_stream_pdu_set(pdu, (enum avtp_stream_field) field, - val); - break; - case AVTP_CVF_FIELD_FORMAT: - case AVTP_CVF_FIELD_FORMAT_SUBTYPE: - case AVTP_CVF_FIELD_M: - case AVTP_CVF_FIELD_EVT: - case AVTP_CVF_FIELD_H264_PTV: - res = set_field_value(pdu, field, val); - break; - case AVTP_CVF_FIELD_H264_TIMESTAMP: - { - /* This field lives on H.264 header, inside avtp_payload */ - struct avtp_cvf_h264_payload *pay = - (struct avtp_cvf_h264_payload *)pdu->avtp_payload; - pay->h264_header = htonl(val); - res = 0; - break; - } - default: - res = -EINVAL; - break; - } - - return res; -} - -int avtp_cvf_pdu_init(struct avtp_stream_pdu *pdu, uint8_t subtype) -{ - int res; - - if (!pdu) - return -EINVAL; - - if (subtype > AVTP_CVF_FORMAT_SUBTYPE_JPEG2000) - return -EINVAL; - - memset(pdu, 0, sizeof(struct avtp_stream_pdu)); - - res = avtp_pdu_set((struct avtp_common_pdu *) pdu, AVTP_FIELD_SUBTYPE, - AVTP_SUBTYPE_CVF); - if (res < 0) - return res; - - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_SV, 1); - if (res < 0) - return res; - - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_FORMAT, AVTP_CVF_FORMAT_RFC); - if (res < 0) - return res; - - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_FORMAT_SUBTYPE, subtype); - if (res < 0) - return res; - - return 0; -} diff --git a/unit/test-cvf.c b/unit/test-cvf.c index 34151e5..76f1025 100644 --- a/unit/test-cvf.c +++ b/unit/test-cvf.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, Intel Corporation + * Copyright (c) 2024, COVESA * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,7 +35,8 @@ #include #include "avtp.h" -#include "avtp_cvf.h" +#include "avtp/cvf/Cvf.h" +#include "avtp/cvf/H264.h" static void cvf_get_field_null_pdu(void **state) { @@ -121,7 +123,7 @@ static void cvf_get_field_seq_num(void **state) /* Set 'sequence_num' field to 0x55. */ pdu.subtype_data = htonl(0x00005500); - res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_SEQ_NUM, &val); + res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_SEQUENCE_NUM, &val); assert_int_equal(res, 0); assert_true(val == 0x55); @@ -166,7 +168,7 @@ static void cvf_get_field_timestamp(void **state) /* Set 'avtp_timestamp' field to 0x80C0FFEE. */ pdu.avtp_time = htonl(0x80C0FFEE); - res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_TIMESTAMP, &val); + res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_AVTP_TIMESTAMP, &val); assert_int_equal(res, 0); assert_true(val == 0x80C0FFEE); @@ -211,7 +213,7 @@ static void cvf_get_field_data_len(void **state) /* Set 'stream_data_length' field to 0xAAAA. */ pdu.packet_info = htonl(0xAAAA0000); - res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, &val); + res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_STREAM_DATA_LENGTH, &val); assert_int_equal(res, 0); assert_true(val == 0xAAAA); @@ -316,7 +318,7 @@ static void cvf_set_field_seq_num(void **state) int res; struct avtp_stream_pdu pdu = { 0 }; - res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_SEQ_NUM, 0x55); + res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_SEQUENCE_NUM, 0x55); assert_int_equal(res, 0); assert_true(ntohl(pdu.subtype_data) == 0x00005500); @@ -362,7 +364,7 @@ static void cvf_set_field_timestamp(void **state) int res; struct avtp_stream_pdu pdu = { 0 }; - res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_TIMESTAMP, 0x80C0FFEE); + res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_AVTP_TIMESTAMP, 0x80C0FFEE); assert_int_equal(res, 0); assert_true(ntohl(pdu.avtp_time) == 0x80C0FFEE); @@ -409,7 +411,7 @@ static void cvf_set_field_data_len(void **state) int res; struct avtp_stream_pdu pdu = { 0 }; - res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_STREAM_DATA_LEN, 0xAAAA); + res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_STREAM_DATA_LENGTH, 0xAAAA); assert_int_equal(res, 0); assert_true(ntohl(pdu.packet_info) == 0xAAAA0000); @@ -457,15 +459,6 @@ static void cvf_pdu_init_null_pdu(void **state) assert_int_equal(res, -EINVAL); } -static void cvf_pdu_init_invalid_subtype(void **state) -{ - int res; - struct avtp_stream_pdu pdu; - - res = avtp_cvf_pdu_init(&pdu, AVTP_CVF_FORMAT_SUBTYPE_JPEG2000 + 1); - assert_int_equal(res, -EINVAL); -} - static void cvf_pdu_init(void **state) { int res; @@ -481,9 +474,7 @@ static void cvf_pdu_init(void **state) assert_true(pdu.packet_info == 0); } -/**** Tests for H.264 fields ****/ - -static void cvf_get_field_h264_ptv(void **state) +static void cvf_get_field_ptv(void **state) { int res; uint64_t val; @@ -492,64 +483,55 @@ static void cvf_get_field_h264_ptv(void **state) /* Set 'ptv' field to 1. */ pdu.packet_info = htonl(0x00002000); - res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_H264_PTV, &val); + res = avtp_cvf_pdu_get(&pdu, AVTP_CVF_FIELD_PTV, &val); assert_int_equal(res, 0); assert_true(val == 1); } -static void cvf_get_field_h264_timestamp(void **state) +static void cvf_set_field_ptv(void **state) { int res; - uint64_t val; - struct avtp_stream_pdu *pdu = - alloca(sizeof(struct avtp_stream_pdu) + sizeof(uint32_t)); - struct avtp_cvf_h264_payload *pay = - (struct avtp_cvf_h264_payload *)pdu->avtp_payload; - - /* Set 'h264_timestamp' field (which lives in h264_header) to - * 0x80C0FFEE. */ - pay->h264_header = htonl(0x80C0FFEE); + struct avtp_stream_pdu pdu = { 0 }; - res = avtp_cvf_pdu_get(pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, &val); + res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_PTV, 1); assert_int_equal(res, 0); - assert_true(val == 0x80C0FFEE); + assert_true(pdu.subtype_data == 0); + assert_true(pdu.stream_id == 0); + assert_true(pdu.avtp_time == 0); + assert_true(pdu.format_specific == 0); + assert_true(ntohl(pdu.packet_info) == 0x00002000); } -static void cvf_set_field_h264_ptv(void **state) +/**** Tests for H.264 fields ****/ + +static void cvf_get_field_h264_timestamp(void **state) { int res; - struct avtp_stream_pdu pdu = { 0 }; + uint64_t val; + Avtp_H264_t pdu; - res = avtp_cvf_pdu_set(&pdu, AVTP_CVF_FIELD_H264_PTV, 1); + /* Set 'h264_timestamp' field (which lives in h264_header) to + * 0x80C0FFEE. */ + uint32_t value = htonl(0x80C0FFEE); + memcpy(&pdu.header, &value, 4); + + res = Avtp_H264_GetField(&pdu, AVTP_H264_FIELD_TIMESTAMP, &val); assert_int_equal(res, 0); - assert_true(pdu.subtype_data == 0); - assert_true(pdu.stream_id == 0); - assert_true(pdu.avtp_time == 0); - assert_true(pdu.format_specific == 0); - assert_true(ntohl(pdu.packet_info) == 0x00002000); + assert_true(val == 0x80C0FFEE); } static void cvf_set_field_h264_timestamp(void **state) { int res; - struct avtp_stream_pdu *pdu = - alloca(sizeof(struct avtp_stream_pdu) + sizeof(uint32_t)); - struct avtp_cvf_h264_payload *pay = - (struct avtp_cvf_h264_payload *)pdu->avtp_payload; - memset(pdu, 0, sizeof(struct avtp_stream_pdu) + sizeof(uint32_t)); + Avtp_H264_t pdu; - res = avtp_cvf_pdu_set(pdu, AVTP_CVF_FIELD_H264_TIMESTAMP, 0x80C0FFEE); + res = Avtp_H264_SetField(&pdu, AVTP_H264_FIELD_TIMESTAMP, 0x80C0FFEE); assert_int_equal(res, 0); - assert_true(pdu->avtp_time == 0); - assert_true(pdu->subtype_data == 0); - assert_true(pdu->stream_id == 0); - assert_true(pdu->format_specific == 0); - assert_true(pdu->packet_info == 0); - assert_true(ntohl(pay->h264_header) == 0x80C0FFEE); + assert_true(ntohl(*(uint32_t*)(&pdu.header)) == 0x80C0FFEE); } int main(void) @@ -570,7 +552,7 @@ int main(void) cmocka_unit_test(cvf_get_field_data_len), cmocka_unit_test(cvf_get_field_m), cmocka_unit_test(cvf_get_field_evt), - cmocka_unit_test(cvf_get_field_h264_ptv), + cmocka_unit_test(cvf_get_field_ptv), cmocka_unit_test(cvf_get_field_h264_timestamp), cmocka_unit_test(cvf_set_field_null_pdu), cmocka_unit_test(cvf_set_field_invalid_field), @@ -586,10 +568,9 @@ int main(void) cmocka_unit_test(cvf_set_field_data_len), cmocka_unit_test(cvf_set_field_m), cmocka_unit_test(cvf_set_field_evt), - cmocka_unit_test(cvf_set_field_h264_ptv), + cmocka_unit_test(cvf_set_field_ptv), cmocka_unit_test(cvf_set_field_h264_timestamp), cmocka_unit_test(cvf_pdu_init_null_pdu), - cmocka_unit_test(cvf_pdu_init_invalid_subtype), cmocka_unit_test(cvf_pdu_init), };