From b1e343adc86aa8b79a93bdc600b1d5a9ceab77b7 Mon Sep 17 00:00:00 2001 From: Lynne Date: Fri, 24 May 2024 05:35:56 +0200 Subject: [PATCH] Add tests for the new packet merger --- libavtransport/merger.c | 17 +-- libavtransport/tests/merger.c | 250 ++++++++++++++++++++++++++++++++++ 2 files changed, 259 insertions(+), 8 deletions(-) create mode 100644 libavtransport/tests/merger.c diff --git a/libavtransport/merger.c b/libavtransport/merger.c index d7ce82c..801dce2 100644 --- a/libavtransport/merger.c +++ b/libavtransport/merger.c @@ -89,7 +89,7 @@ static inline int fill_ranges(AVTMerger *m, bool is_parity, break; } else if (seg_off > (r->offset + r->size)) { /* New segment. Pick its index here for ordering. */ - dst_idx = i + 1; + dst_idx = i; } } @@ -113,7 +113,8 @@ static inline int fill_ranges(AVTMerger *m, bool is_parity, } } - memmove(&ranges[dst_idx + 1], &ranges[dst_idx], nb_ranges - dst_idx - 1); + memmove(&ranges[dst_idx + 1], &ranges[dst_idx], + (nb_ranges - dst_idx - 1)*sizeof(AVTMerger)); nb_ranges++; *nb_ranges_dst = nb_ranges; return 0; @@ -191,7 +192,7 @@ static int validate_packet(void *log_ctx, AVTMerger *m, AVTPktd *p, int srs, uint32_t tot_size, bool is_parity) { /* Check for length mismatch */ - if (m->target_tot_len && (tot_size != m->target_tot_len)) + if (m->target_tot_len && tot_size && (tot_size != m->target_tot_len)) return AVT_ERROR(EINVAL); /* Check for segmentation issues */ @@ -264,12 +265,12 @@ int avt_pkt_merge_seg(void *log_ctx, AVTMerger *m, AVTPktd *p) if (m->active) { uint32_t target; - if (srs > 0) - target = p->pkt.generic_segment.target_seq; - else if (!is_parity) - target = p->pkt.generic_segment.target_seq; - else + if (srs == 1) + target = p->pkt.seq; + else if (is_parity) target = p->pkt.generic_parity.target_seq; + else + target = p->pkt.generic_segment.target_seq; if (target != m->target) return AVT_ERROR(EBUSY); diff --git a/libavtransport/tests/merger.c b/libavtransport/tests/merger.c new file mode 100644 index 0000000..7a84803 --- /dev/null +++ b/libavtransport/tests/merger.c @@ -0,0 +1,250 @@ +/* + * Copyright © 2024, Lynne + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 "merger.h" +#include "buffer.h" +#include "utils_packet.h" + +int main(void) +{ + int ret; + AVTMerger s = { }; + AVTPktd hdr = { }; + AVTPktd seg = { }; + uint8_t *hdr_data; + + { + fprintf(stderr, "Testing noop merge...\n"); + hdr = (AVTPktd) { + .pkt = AVT_STREAM_DATA_HDR( + .frame_type = AVT_FRAME_TYPE_KEY, + .pkt_in_fec_group = 0, + .field_id = 0, + .pkt_compression = AVT_DATA_COMPRESSION_NONE, + .stream_id = 0, + .pts = 0, + .duration = 1, + ), + }; + + hdr_data = avt_buffer_quick_alloc(&hdr.pl, 64); + if (!hdr_data) + return ENOMEM; + avt_packet_change_size(&hdr, 0, 64, 64); + + /* One full packet in, one full packet out */ + ret = avt_pkt_merge_seg(NULL, &s, &hdr); + if (ret < 0) + goto end; + + /* Output generated, have to free it */ + avt_buffer_quick_unref(&hdr.pl); + } + + { + fprintf(stderr, "Testing packet + segment merger...\n"); + hdr = (AVTPktd) { + .pkt = AVT_STREAM_DATA_HDR( + .frame_type = AVT_FRAME_TYPE_KEY, + .pkt_in_fec_group = 0, + .field_id = 0, + .pkt_compression = AVT_DATA_COMPRESSION_NONE, + .stream_id = 0, + .pts = 0, + .duration = 1, + ), + }; + + hdr_data = avt_buffer_quick_alloc(&hdr.pl, 64); + if (!hdr_data) + return ENOMEM; + avt_packet_change_size(&hdr, 0, 64, 128); + + ret = avt_pkt_merge_seg(NULL, &s, &hdr); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* No output yet */ + + seg.pkt = avt_packet_create_segment(&hdr, 1, 64, 64, 128); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); + avt_buffer_quick_unref(&seg.pl); + if (ret < 0) + goto end; + + ret = 0; + } + + { + fprintf(stderr, "Testing packet + segment + segment merger...\n"); + hdr = (AVTPktd) { + .pkt = AVT_STREAM_DATA_HDR( + .frame_type = AVT_FRAME_TYPE_KEY, + .pkt_in_fec_group = 0, + .field_id = 0, + .pkt_compression = AVT_DATA_COMPRESSION_NONE, + .stream_id = 0, + .pts = 0, + .duration = 1, + ), + }; + + hdr_data = avt_buffer_quick_alloc(&hdr.pl, 64); + if (!hdr_data) + return ENOMEM; + avt_packet_change_size(&hdr, 0, 64, 192); + + ret = avt_pkt_merge_seg(NULL, &s, &hdr); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* No output yet */ + seg.pkt = avt_packet_create_segment(&hdr, 1, 64, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* Output */ + seg.pkt = avt_packet_create_segment(&hdr, 2, 128, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); + avt_buffer_quick_unref(&seg.pl); + if (ret < 0) + goto end; + + ret = 0; + } + + { + fprintf(stderr, "Testing packet + segment + segment merger + reorder...\n"); + hdr = (AVTPktd) { + .pkt = AVT_STREAM_DATA_HDR( + .frame_type = AVT_FRAME_TYPE_KEY, + .pkt_in_fec_group = 0, + .field_id = 0, + .pkt_compression = AVT_DATA_COMPRESSION_NONE, + .stream_id = 0, + .pts = 0, + .duration = 1, + ), + }; + + hdr_data = avt_buffer_quick_alloc(&hdr.pl, 64); + if (!hdr_data) + return ENOMEM; + avt_packet_change_size(&hdr, 0, 64, 192); + + ret = avt_pkt_merge_seg(NULL, &s, &hdr); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* No output yet */ + seg.pkt = avt_packet_create_segment(&hdr, 1, 128, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* Output */ + seg.pkt = avt_packet_create_segment(&hdr, 2, 64, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); avt_buffer_quick_unref(&seg.pl); + if (ret < 0) + goto end; + + ret = 0; + } + + { + fprintf(stderr, "Testing packet + segment + segment merger + reorder + reorder...\n"); + hdr = (AVTPktd) { + .pkt = AVT_STREAM_DATA_HDR( + .frame_type = AVT_FRAME_TYPE_KEY, + .pkt_in_fec_group = 0, + .field_id = 0, + .pkt_compression = AVT_DATA_COMPRESSION_NONE, + .stream_id = 0, + .pts = 0, + .duration = 1, + ), + }; + + hdr_data = avt_buffer_quick_alloc(&hdr.pl, 64); + if (!hdr_data) + return ENOMEM; + avt_packet_change_size(&hdr, 0, 64, 192); + + /* No output yet */ + seg.pkt = avt_packet_create_segment(&hdr, 1, 128, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + ret = avt_pkt_merge_seg(NULL, &s, &hdr); + if (ret != AVT_ERROR(EAGAIN)) + goto end; + + /* Output */ + seg.pkt = avt_packet_create_segment(&hdr, 2, 64, 64, 192); + hdr_data = avt_buffer_quick_alloc(&seg.pl, 64); + if (!hdr_data) + return ENOMEM; + + ret = avt_pkt_merge_seg(NULL, &s, &seg); avt_buffer_quick_unref(&seg.pl); + if (ret < 0) + goto end; + + ret = 0; + } + + +end: + avt_pkt_merge_free(&s); + return AVT_ERROR(ret); +}