LCOV - code coverage report
Current view: top level - filters - unit_test_filter.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 441 483 91.3 %
Date: 2021-04-29 23:48:07 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2017-2021
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / unit test filters
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/filters.h>
      27             : #include <gpac/list.h>
      28             : 
      29             : typedef struct
      30             : {
      31             :         GF_FilterPid *src_pid;
      32             :         GF_FilterPid *dst_pid;
      33             :         GF_SHA1Context *sha_ctx;
      34             :         u32 nb_packets, pck_del;
      35             : 
      36             :         GF_FilterFrameInterface frame_ifce;
      37             :         u8 ifce_data[10];
      38             : } PIDCtx;
      39             : 
      40             : enum
      41             : {
      42             :         UTF_MODE_SOURCE=0,
      43             :         UTF_MODE_SINK,
      44             :         UTF_MODE_FILTER,
      45             : };
      46             : typedef struct
      47             : {
      48             :         GF_List *pids;
      49             : 
      50             :         //0: source, 1: sink, 2: filter
      51             :         u32 mode;
      52             :         u32 max_pck;
      53             :         s32 max_out;
      54             :         const char *pid_att;
      55             :         Bool alloc;
      56             :         u32 nb_pids;
      57             :         u32 fwd;
      58             :         u32 framing;
      59             :         Bool cov;
      60             :         Bool norecfg;
      61             :         const char *update;
      62             : 
      63             :         Bool gsftest;
      64             :         GF_Fraction64 dummy1;
      65             : } GF_UnitTestFilter;
      66             : 
      67       23418 : static void test_pck_del(GF_Filter *filter, GF_FilterPid *pid, GF_FilterPacket *pck)
      68             : {
      69       23418 :         PIDCtx *stack = (PIDCtx *) gf_filter_pid_get_udta(pid);
      70       23416 :         stack->pck_del++;
      71             :         assert(stack->nb_packets >= stack->pck_del);
      72       23416 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_APP, ("%s: Packet deleted - %d out there (%d sent %d destroyed)\n", gf_filter_get_name(filter), stack->nb_packets - stack->pck_del, stack->nb_packets, stack->pck_del));
      73       23417 : }
      74             : 
      75             : 
      76       25640 : void dump_properties(GF_FilterPacket *pck, u32 nb_pck)
      77             : {
      78       25640 :         u32 idx = 0;
      79       30280 :         while (1) {
      80             :                 u32 p4cc;
      81             :                 const char *pname;
      82       55920 :                 const GF_PropertyValue *p = gf_filter_pck_enum_properties(pck, &idx, &p4cc, &pname);
      83       55919 :                 if (!p) break;
      84             :                 //dump_property(pck, nb_pck, p4cc, pname, p);
      85             :         }
      86       25639 :         if (nb_pck==1) {
      87         212 :                 gf_filter_pck_get_property(pck, GF_4CC('c','u','s','t'));
      88         209 :                 gf_filter_pck_get_property_str(pck, "custom");
      89             :         }
      90       25640 : }
      91             : 
      92         385 : static void ut_filter_finalize(GF_Filter *filter)
      93             : {
      94             :         u32 i, count;
      95             :         u8 digest[GF_SHA1_DIGEST_SIZE];
      96         385 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
      97             : 
      98         385 :         count = gf_list_count(stack->pids);
      99         825 :         for (i=0; i<count; i++) {
     100         440 :                 PIDCtx *pidctx = gf_list_get(stack->pids, i);
     101         440 :                 if (pidctx->sha_ctx && (stack->mode!=UTF_MODE_SOURCE) ) {
     102         281 :                         gf_sha1_finish(pidctx->sha_ctx, digest);
     103             : 
     104         281 :                         if (!pidctx->src_pid) {
     105           0 :                                 GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[%s] Pid %d Source PID not available while dumping SHA1\n", gf_filter_get_name(filter), i+1 ));
     106             :                         } else {
     107         281 :                                 const GF_PropertyValue *p = gf_filter_pid_get_property(pidctx->src_pid, GF_4CC('s','h','a','1') );
     108         281 :                                 if (!p) {
     109           0 :                                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[%s] Pid %d sha1 property not found on input pid\n", gf_filter_get_name(filter), i+1 ));
     110         281 :                                 } else if (p->value.data.size != GF_SHA1_DIGEST_SIZE) {
     111           0 :                                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[%s] Pid %d wrong size for sha1 property\n", gf_filter_get_name(filter), i+1 ));
     112         281 :                                 } else if (memcmp(p->value.data.ptr, digest, p->value.data.size )) {
     113           0 :                                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[%s] Pid %d wrong hash after execution\n", gf_filter_get_name(filter), i+1 ));
     114             :                                 } else {
     115         281 :                                         GF_LOG(GF_LOG_WARNING, GF_LOG_APP, ("[%s] Pid %d hash OK after execution\n", gf_filter_get_name(filter), i+1 ));
     116             :                                 }
     117             :                         }
     118             :                 }
     119         440 :                 gf_free(pidctx);
     120             :         }
     121         385 :         gf_list_del(stack->pids);
     122         385 : }
     123             : 
     124       21952 : static void ut_filter_send_update(GF_Filter *filter, u32 nb_pck)
     125             : {
     126       21952 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     127             : 
     128       21952 :         if (stack->update && (nb_pck==stack->max_pck/2) ) {
     129             :                 char *sep, *fid;
     130           9 :                 char *cmd = gf_strdup(stack->update);
     131             :                 fid = cmd;
     132           9 :                 sep = strchr(cmd, ',');
     133           9 :                 if (sep) {
     134             :                         char *name, *val;
     135           9 :                         sep[0]=0;
     136           9 :                         sep+=1;
     137             :                         name=sep;
     138           9 :                         sep = strchr(name, ',');
     139           9 :                         if (sep) {
     140           9 :                                 sep[0]=0;
     141           9 :                                 val = sep+1;
     142             :                         } else {
     143             :                                 val=NULL;
     144             :                         }
     145           9 :                         gf_filter_send_update(filter, fid, name, val, 0);
     146             :                 }
     147           9 :                 gf_free(cmd);
     148             :         }
     149       21952 : }
     150             : 
     151             : 
     152       12823 : static GF_Err ut_filter_process_filter(GF_Filter *filter)
     153             : {
     154             :         u32 size, i, j, count, nb_loops;
     155             :         u32 fwd;
     156             :         GF_FilterPacket *pck_dst;
     157       12823 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     158             : 
     159       12823 :         count = gf_list_count(stack->pids);
     160       20131 :         for (i=0; i<count; i++) {
     161       12823 :                 PIDCtx *pidctx = gf_list_get(stack->pids, i);
     162       12823 :                 GF_FilterPacket *pck = gf_filter_pid_get_packet(pidctx->src_pid);
     163       12823 :                 if (!pck)
     164             :                         return GF_OK;
     165             : 
     166        7308 :                 if ((stack-> max_out>=0) && (pidctx->nb_packets - pidctx->pck_del >= (u32) stack->max_out) ) {
     167           0 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_APP, ("TestSource: No packets to emit, waiting for destruction\n"));
     168             :                         return GF_OK;
     169             :                 }
     170             :         }
     171             : 
     172             :         //loop on each PID
     173        7308 :         for (i=0; i<count; i++) {
     174             :                 const u8 *data;
     175             :                 u32 pck_size;
     176             :                 u8 *data_ptr;
     177             :                 u32 data_offset=0;
     178        7308 :                 PIDCtx *pidctx = gf_list_get(stack->pids, i);
     179        7308 :                 GF_FilterPacket *pck = gf_filter_pid_get_packet(pidctx->src_pid);
     180             :                 assert (pck);
     181             :                 assert(pidctx == gf_filter_pid_get_udta(pidctx->src_pid));
     182             : 
     183        7308 :                 data = gf_filter_pck_get_data(pck, &size);
     184        7308 :                 gf_sha1_update(pidctx->sha_ctx, (u8*)data, size);
     185             : 
     186        7308 :                 nb_loops = stack->framing ? 3 : 1;
     187        7308 :                 pck_size = stack->framing ? size/nb_loops : size;
     188             :                 data_ptr = (u8 *)data;
     189             : 
     190       14632 :                 for (j=0; j<nb_loops; j++) {
     191             : 
     192             :                 //adjust last packet size
     193        7324 :                 if ((j+1) == nb_loops) {
     194        7308 :                         pck_size = size - j*pck_size;
     195             :                 }
     196             : 
     197        7324 :                 fwd = stack->fwd;
     198        7324 :                 if (fwd==3) fwd = pidctx->nb_packets % 3;
     199             : 
     200             :                 //shared memory
     201        7324 :                 if (fwd==0) {
     202        3269 :                         pck_dst = gf_filter_pck_new_shared(pidctx->dst_pid, data_ptr, pck_size, test_pck_del);
     203             :                 }
     204             :                 //copy memory
     205        4055 :                 else if (fwd==1) {
     206             :                         u8 *data_dst;
     207        2256 :                         pck_dst = gf_filter_pck_new_alloc(pidctx->dst_pid, pck_size, &data_dst);
     208        2256 :                         if (pck_dst) {
     209        2256 :                                 memcpy(data_dst, data_ptr, pck_size);
     210             :                         }
     211             :                 }
     212             :                 //packet reference
     213             :                 else {
     214        1799 :                         if (stack->framing) {
     215           8 :                                 pck_dst = gf_filter_pck_new_ref(pidctx->dst_pid, data_offset, pck_size, pck);
     216             :                         } else {
     217        1791 :                                 pck_dst = gf_filter_pck_new_ref(pidctx->dst_pid, 0, 0, pck);
     218             :                         }
     219             :                 }
     220             : 
     221             : 
     222        7324 :                 if (pck_dst) {
     223             :                         Bool is_start, is_end;
     224             :                         //get source packet framing
     225        7324 :                         gf_filter_pck_get_framing(pck, &is_start, &is_end);
     226             :                         //adjust flags given our framing
     227        7324 :                         if (is_start && j) is_start = GF_FALSE;
     228        7324 :                         if (is_end && (j+1 < nb_loops) ) is_end = GF_FALSE;
     229        7324 :                         if (stack->framing==2) is_start = GF_FALSE;
     230        7324 :                         if (stack->framing==3) is_end = GF_FALSE;
     231             : 
     232        7324 :                         gf_filter_pck_set_framing(pck_dst, is_start, is_end);
     233             :                         
     234        7324 :                         pidctx->nb_packets++;
     235             :                         //copy over src props to dst
     236        7324 :                         gf_filter_pck_merge_properties(pck, pck_dst);
     237        7324 :                         gf_filter_pck_send(pck_dst);
     238             :                 }
     239             :                 //move our data pointer
     240        7324 :                 data_ptr += pck_size;
     241        7324 :                 data_offset += pck_size;
     242             : 
     243             :                 } //end framing loop
     244             : 
     245        7308 :                 gf_filter_pid_drop_packet(pidctx->src_pid);
     246             : 
     247             :         } //end PID loop
     248             : 
     249             :         return GF_OK;
     250             : 
     251             : }
     252             : 
     253           1 : static void ut_source_pck_del(GF_Filter *filter, GF_FilterPid *pid, GF_FilterPacket *pck)
     254             : {
     255             : 
     256           1 : }
     257             : 
     258           1 : static GF_Err ut_source_ifce_get_plane(struct _gf_filter_frame_interface *frame, u32 plane_idx, const u8 **outPlane, u32 *outStride)
     259             : {
     260           1 :         PIDCtx *pctx = frame->user_data;
     261           1 :         memset(pctx->ifce_data, 0, 10);
     262           1 :         if (plane_idx) return GF_BAD_PARAM;
     263           1 :         *outPlane = pctx->ifce_data;
     264           1 :         *outStride = 5;
     265           1 :         return GF_OK;
     266             : }
     267             : 
     268       22083 : static GF_Err ut_filter_process_source(GF_Filter *filter)
     269             : {
     270             :         GF_PropertyValue p;
     271             :         GF_FilterPacket *pck;
     272             :         u32 i, count, nb_eos;
     273       22083 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     274             : 
     275             :         nb_eos = 0;
     276       22083 :         count = gf_list_count(stack->pids);
     277       44317 :         for (i=0; i<count; i++) {
     278       22234 :                 PIDCtx *pidctx=gf_list_get(stack->pids, i);
     279             : 
     280       22234 :                 if (pidctx->nb_packets==stack->max_pck) {
     281         282 :                         if (stack->gsftest) {
     282           2 :                                 if (pidctx->dst_pid) {
     283           1 :                                         gf_filter_pid_remove(pidctx->dst_pid);
     284           1 :                                         pidctx->dst_pid = NULL;
     285             :                                 }
     286             :                         }
     287         282 :                         nb_eos++;
     288         282 :                         continue;
     289             :                 }
     290             : 
     291       21952 :                 if ((stack->max_out>=0) && (pidctx->nb_packets - pidctx->pck_del >= (u32) stack->max_out) ) {
     292           0 :                         GF_LOG(GF_LOG_DEBUG, GF_LOG_APP, ("TestSource: No packets to emit, waiting for destruction\n"));
     293           0 :                         continue;
     294             :                 }
     295       21952 :                 pidctx->nb_packets++;
     296             : 
     297       21952 :                 if (stack->gsftest && pidctx->nb_packets==4) {
     298           1 :                         pidctx->frame_ifce.get_plane = ut_source_ifce_get_plane;
     299           1 :                         pidctx->frame_ifce.user_data = pidctx;
     300           1 :                         pck = gf_filter_pck_new_frame_interface(pidctx->dst_pid, &pidctx->frame_ifce, ut_source_pck_del);
     301       21951 :                 } else if (stack->alloc) {
     302             :                         u8 *data;
     303        1800 :                         pck = gf_filter_pck_new_alloc(pidctx->dst_pid, 10, &data);
     304        1800 :                         memcpy(data, "PacketCopy", 10);
     305        1800 :                         gf_sha1_update(pidctx->sha_ctx, "PacketCopy", 10);
     306             :                 } else {
     307       20151 :                         pck = gf_filter_pck_new_shared(pidctx->dst_pid, "PacketShared", 12, test_pck_del);
     308       20151 :                         gf_sha1_update(pidctx->sha_ctx, "PacketShared", 12);
     309             :                 }
     310       21952 :                 GF_LOG(GF_LOG_DEBUG, GF_LOG_APP, ("TestSource: pck %d PacketShared\n", pidctx->nb_packets));
     311             : 
     312       21952 :                 gf_filter_pck_set_cts(pck, pidctx->nb_packets);
     313             : 
     314       21952 :                 p.type = GF_PROP_NAME;
     315       21952 :                 p.value.string = "custom_value";
     316       21952 :                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','t'), &p);
     317             : 
     318             :                 //try all our properties
     319       21952 :                 if (pidctx->nb_packets==1) {
     320         159 :                         u32 val=1;
     321         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','1'), &PROP_BOOL(GF_TRUE) );
     322         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','2'), &PROP_SINT(-1));
     323         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','3'), &PROP_UINT(1));
     324         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','4'), &PROP_LONGSINT(-1));
     325         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','5'), &PROP_LONGUINT(1));
     326         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','6'), &PROP_FLOAT(1.0f));
     327         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','7'), &PROP_DOUBLE(1.0));
     328         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','8'), &PROP_FRAC_INT(1,1));
     329         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','8'), &PROP_FRAC64_INT(1,1));
     330         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','9'), &PROP_POINTER(pck));
     331             : 
     332         159 :                         if (stack->gsftest) {
     333           1 :                                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','a'), &PROP_DATA(pidctx->ifce_data, 8));
     334           1 :                                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','b'), &PROP_CONST_DATA(pidctx->ifce_data, 8));
     335             :                         } else {
     336         158 :                                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','a'), &PROP_DATA((char *) pidctx, sizeof(pidctx)));
     337         158 :                                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','b'), &PROP_CONST_DATA((char *) pidctx, sizeof(pidctx)));
     338             :                         }
     339         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','c'), &PROP_STRING("custom"));
     340         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','d'), &PROP_STRING("custom"));
     341             :                         memset(&p, 0, sizeof(GF_PropertyValue));
     342         159 :                         p.type = GF_PROP_VEC2;
     343         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','e'), &p);
     344         159 :                         p.type = GF_PROP_VEC2I;
     345         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','f'), &p);
     346         159 :                         p.type = GF_PROP_VEC3I;
     347         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','h'), &p);
     348         159 :                         p.type = GF_PROP_VEC4I;
     349         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','j'), &p);
     350         159 :                         p.type = GF_PROP_STRING_LIST;
     351         159 :                         p.value.string_list.nb_items = 1;
     352         159 :                         p.value.string_list.vals = gf_malloc(sizeof(char *));
     353         159 :                         p.value.string_list.vals[0] = gf_strdup("custom");
     354         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','k'), &p);
     355         159 :                         p.type = GF_PROP_UINT_LIST;
     356         159 :                         p.value.uint_list.nb_items = 1;
     357         159 :                         p.value.uint_list.vals = &val;
     358         159 :                         gf_filter_pck_set_property(pck, GF_4CC('c','u','s','l'), &p);
     359             : 
     360         159 :                         gf_filter_pck_set_property_str(pck, "cusd", &PROP_BOOL(GF_TRUE) );
     361         159 :                         gf_filter_pck_set_property_dyn(pck, "cuse", &PROP_BOOL(GF_TRUE) );
     362             :                 }
     363       21952 :                 if (stack->gsftest) {
     364        1000 :                         gf_filter_pck_set_dts(pck, pidctx->nb_packets-1);
     365        1000 :                         gf_filter_pck_set_cts(pck, pidctx->nb_packets-1);
     366        1000 :                         gf_filter_pck_set_duration(pck, 1);
     367        1000 :                         if (pidctx->nb_packets==2) {
     368           1 :                                 gf_filter_pck_set_seek_flag(pck, GF_TRUE);
     369           1 :                                 gf_filter_pck_set_carousel_version(pck, 1);
     370           1 :                                 gf_filter_pck_set_interlaced(pck, GF_TRUE);
     371           1 :                                 gf_filter_pck_set_sap(pck, GF_FILTER_SAP_3);
     372           1 :                                 gf_filter_pck_set_dependency_flags(pck, 0xFF);
     373           1 :                                 gf_filter_pck_set_property(pck, GF_PROP_PCK_SENDER_NTP, &PROP_LONGUINT(0) );
     374             :                         }
     375         999 :                         else if (pidctx->nb_packets==3) {
     376           1 :                                 gf_filter_pck_set_sap(pck, GF_FILTER_SAP_4);
     377           1 :                                 gf_filter_pck_set_roll_info(pck, 1);
     378           1 :                                 gf_filter_pck_set_byte_offset(pck, 20);
     379             :                         }
     380             :                 }
     381             : 
     382       21952 :                 ut_filter_send_update(filter, pidctx->nb_packets);
     383             : 
     384       21952 :                 if (pidctx->nb_packets==stack->max_pck) {
     385         159 :                         if (pidctx->sha_ctx) {
     386             :                                 u8 digest[GF_SHA1_DIGEST_SIZE];
     387         159 :                                 gf_sha1_finish(pidctx->sha_ctx, digest);
     388         159 :                                 pidctx->sha_ctx = NULL;
     389         159 :                                 p.type = GF_PROP_DATA;
     390         159 :                                 p.value.data.size = GF_SHA1_DIGEST_SIZE;
     391         159 :                                 p.value.data.ptr = (char *) digest;
     392             :                                 //with this we test both:
     393             :                                 //- SHA of send data is correct at the receiver side
     394             :                                 //- property update on a PID
     395         159 :                                 gf_filter_pid_set_property(pidctx->dst_pid, GF_4CC('s','h','a','1'), &p);
     396             :                         }
     397             :                 }
     398             :                 //just for coverage: check keeping a reference to the packet
     399       21952 :                 gf_filter_pck_ref(& pck);
     400             : 
     401       21952 :                 gf_filter_pck_send(pck);
     402             : 
     403             :                 //and destroy the reference
     404       21952 :                 gf_filter_pck_unref(pck);
     405             : 
     406             :         }
     407       22083 :         if (nb_eos==count) return GF_EOS;
     408       21880 :         return GF_OK;
     409             : }
     410             : 
     411             : 
     412       25850 : static GF_Err ut_filter_process_sink(GF_Filter *filter)
     413             : {
     414             :         u32 size, i, count, nb_eos;
     415             :         const char *data;
     416       25850 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     417             : 
     418       25850 :         count = gf_list_count(stack->pids);
     419             :         nb_eos=0;
     420             : 
     421       55719 :         for (i=0; i<count; i++) {
     422       29869 :         PIDCtx *pidctx=gf_list_get(stack->pids, i);
     423             : 
     424       29869 :         GF_FilterPacket *pck = gf_filter_pid_get_packet(pidctx->src_pid);
     425       29869 :         if (!pck) {
     426        4230 :                 if (gf_filter_pid_is_eos(pidctx->src_pid)) nb_eos++;
     427        4230 :                 continue;
     428             :         }
     429             : 
     430       25639 :         data = gf_filter_pck_get_data(pck, &size);
     431             : 
     432       25639 :         if (stack->cov && !pidctx->nb_packets) {
     433             :                 GF_PropertyValue p;
     434           2 :                 Bool old_strict = gf_log_set_strict_error(GF_FALSE);
     435           2 :                 gf_filter_pck_send(pck);
     436           2 :                 gf_filter_pck_set_property(pck, GF_4CC('c','u','s','t'), &p);
     437           2 :                 gf_filter_pck_merge_properties(pck, pck);
     438           2 :                 gf_filter_pck_set_framing(pck, GF_TRUE, GF_FALSE);
     439           2 :                 gf_log_set_strict_error(old_strict);
     440             :         }
     441             : 
     442       25639 :         gf_sha1_update(pidctx->sha_ctx, (u8*)data, size);
     443             : 
     444       25640 :         pidctx->nb_packets++;
     445       25640 :         GF_LOG(GF_LOG_DEBUG, GF_LOG_APP, ("TestSink: Consuming packet %d bytes\n", size));
     446             : 
     447       25640 :         dump_properties(pck, pidctx->nb_packets);
     448             : 
     449       25640 :         gf_filter_pid_drop_packet(pidctx->src_pid);
     450             : 
     451             :         } //end PID loop
     452             : 
     453       25850 :         if (nb_eos==count) return GF_EOS;
     454             :         
     455       25850 :         return GF_OK;
     456             : }
     457             : 
     458             : 
     459         558 : static GF_Err ut_filter_config_input(GF_Filter *filter, GF_FilterPid *pid, Bool is_remove)
     460             : {
     461             :         const GF_PropertyValue *format;
     462             :         GF_PropertyValue p;
     463             :         PIDCtx *pidctx;
     464             :         u32 i, count;
     465         558 :         GF_UnitTestFilter  *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     466             : 
     467         559 :         if (stack->mode==UTF_MODE_SOURCE) {
     468           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error: Attempt to connect PID on source filter\n"));
     469             :                 return GF_BAD_PARAM;
     470             :         }
     471             :         //for both filter and sink modes, check input format
     472             : 
     473         559 :         count = gf_list_count(stack->pids);
     474         632 :         for (i=0; i<count; i++) {
     475         351 :                 pidctx = gf_list_get(stack->pids, i);
     476             : 
     477             :                 //something is being reconfigured. We check we have the same custum arg, otherwise we do not support
     478         353 :                 if (pidctx->src_pid == pid) {
     479         279 :                         format = gf_filter_pid_get_property(pidctx->src_pid, GF_4CC('c','u','s','t') );
     480         279 :                         if (!format || !format->value.string || strcmp(format->value.string, stack->pid_att)) {
     481             :                                 return GF_NOT_SUPPORTED;
     482             :                         }
     483             :                         //filter mode, set properties on output
     484         279 :                         if (stack->mode==UTF_MODE_FILTER) {
     485             :                                 //this is not needed since copy_properties does that, used for coverage/tests
     486          68 :                                 gf_filter_pid_reset_properties(pidctx->dst_pid);
     487          68 :                                 gf_filter_pid_copy_properties(pidctx->dst_pid, pidctx->src_pid);
     488             :                         }
     489             :                         return GF_OK;
     490             :                 }
     491             :         }
     492             : 
     493             :         //check our functions
     494         281 :         format = gf_filter_pid_get_property_str(pid, "custom1");
     495         281 :         if (!format) {
     496           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("%s: expecting property string custom1 on PID\n", gf_filter_get_name(filter) ));
     497             :         }
     498         281 :         format = gf_filter_pid_get_property_str(pid, "custom2");
     499         281 :         if (!format) {
     500           0 :                 GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("%s: expecting property string custom2 on PID\n", gf_filter_get_name(filter) ));
     501             :         }
     502             : 
     503         281 :         format = gf_filter_pid_get_property(pid, GF_4CC('c','u','s','t') );
     504         281 :         if (!format || !format->value.string || strcmp(format->value.string, stack->pid_att)) {
     505             :                 return GF_NOT_SUPPORTED;
     506             :         }
     507             : 
     508             :         //new PID
     509         281 :         GF_SAFEALLOC(pidctx, PIDCtx);
     510         281 :         if (!pidctx) return GF_OUT_OF_MEM;
     511         281 :         pidctx->src_pid = pid;
     512         281 :         gf_list_add(stack->pids, pidctx);
     513             :         assert(pidctx->src_pid);
     514             :         
     515             :         //coverage mode
     516         281 :         if (stack->cov) {
     517             :                 u8 *data;
     518           3 :                 Bool old_strict = gf_log_set_strict_error(GF_FALSE);
     519           3 :                 gf_filter_pid_set_property(pidctx->src_pid, GF_4CC('s','h','a','1'), format);
     520           3 :                 gf_filter_pid_reset_properties(pidctx->src_pid);
     521           3 :                 gf_filter_pck_new_alloc(pidctx->src_pid, 20, &data);
     522           3 :                 gf_filter_pck_new_shared(pidctx->src_pid, "foo", 3, NULL);
     523           3 :                 gf_filter_pck_new_ref(pidctx->src_pid, 0, 3, NULL);
     524           3 :                 gf_log_set_strict_error(old_strict);
     525             :         }
     526             : 
     527             :         //filter mode, setup output
     528         281 :         if (stack->mode==UTF_MODE_FILTER) {
     529          68 :                 pidctx->dst_pid = gf_filter_pid_new(filter);
     530          68 :                 p.type=GF_PROP_NAME;
     531          68 :                 p.value.string = (char *) stack->pid_att;
     532          68 :                 gf_filter_pid_copy_properties(pidctx->dst_pid, pidctx->src_pid);
     533             : 
     534          68 :                 if (stack->cov) {
     535           1 :                         Bool old_strict = gf_log_set_strict_error(GF_FALSE);
     536           1 :                         gf_filter_pid_copy_properties(pidctx->src_pid, pidctx->dst_pid);
     537           1 :                         gf_filter_pid_get_packet(pidctx->dst_pid);
     538           1 :                         gf_filter_pid_drop_packet(pidctx->dst_pid);
     539           1 :                         gf_filter_pid_drop_packet(pidctx->src_pid);
     540           1 :                         gf_log_set_strict_error(old_strict);
     541             :                 }
     542             : 
     543          68 :                 gf_filter_pid_set_property(pidctx->dst_pid, GF_4CC('c','u','s','t'), &p);
     544             : 
     545          68 :                 gf_filter_pid_set_udta(pidctx->dst_pid, pidctx);
     546          68 :                 gf_filter_pid_set_udta(pidctx->src_pid, pidctx);
     547             : 
     548          68 :                 gf_filter_pid_set_framing_mode(pidctx->src_pid, GF_TRUE);
     549          68 :                 pidctx->sha_ctx = gf_sha1_starts();
     550             :         }
     551             :         //sink mode, request full reconstruction of input blocks or not depending on framing mode 
     552             :         else {
     553             :                 GF_FilterEvent evt;
     554         213 :                 gf_filter_pid_set_framing_mode(pidctx->src_pid, stack->framing ? GF_FALSE : GF_TRUE);
     555         212 :                 pidctx->sha_ctx = gf_sha1_starts();
     556         213 :                 GF_FEVT_INIT(evt, GF_FEVT_PLAY, pid);
     557         213 :                 gf_filter_pid_send_event(pid, &evt);
     558             :         }
     559             : 
     560             :         return GF_OK;
     561             : }
     562             : 
     563             : 
     564         141 : static GF_Err ut_filter_config_source(GF_Filter *filter)
     565             : {
     566             :         GF_PropertyValue p;
     567             :         PIDCtx *pidctx;
     568             :         u32 i;
     569         141 :         GF_UnitTestFilter *stack = (GF_UnitTestFilter *) gf_filter_get_udta(filter);
     570             : 
     571         300 :         for (i=0; i<stack->nb_pids; i++) {
     572             :                 //create a pid
     573         159 :                 GF_SAFEALLOC(pidctx, PIDCtx);
     574         159 :                 if (!pidctx) return GF_OUT_OF_MEM;
     575         159 :                 gf_list_add(stack->pids, pidctx);
     576         159 :                 pidctx->dst_pid = gf_filter_pid_new(filter);
     577         159 :                 gf_filter_pid_set_udta(pidctx->dst_pid, pidctx);
     578             : 
     579             :                 //set a custum property
     580         159 :                 p.type = GF_PROP_NAME;
     581         159 :                 p.value.string = (char *) stack->pid_att;
     582         159 :                 gf_filter_pid_set_property(pidctx->dst_pid, GF_4CC('c','u','s','t'), &p);
     583             : 
     584             :                 //for coverage
     585         159 :                 gf_filter_pid_set_property_str(pidctx->dst_pid, "custom1", &p);
     586         159 :                 gf_filter_pid_set_property_dyn(pidctx->dst_pid, "custom2", &p);
     587             : 
     588         159 :                 if (stack->cov) {
     589           1 :                         Bool old_strict = gf_log_set_strict_error(GF_FALSE);
     590           1 :                         gf_filter_pid_set_framing_mode(pidctx->dst_pid, GF_TRUE);
     591           1 :                         gf_log_set_strict_error(old_strict);
     592             :                 }
     593             : 
     594         159 :                 pidctx->sha_ctx = gf_sha1_starts();
     595             : 
     596         159 :                 if (stack->gsftest) {
     597           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_STREAM_TYPE, &PROP_UINT(GF_STREAM_VISUAL) );
     598           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_WIDTH, &PROP_UINT(5) );
     599           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_HEIGHT, &PROP_UINT(2) );
     600           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_FPS, &PROP_FRAC_INT(25,1) );
     601           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_CODECID, &PROP_UINT(GF_CODECID_RAW) );
     602           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_PIXFMT, &PROP_UINT(GF_PIXEL_GREYSCALE) );
     603           1 :                         gf_filter_pid_set_property_str(pidctx->dst_pid, "gsfdummy", &p);
     604           1 :                         gf_filter_pid_set_property(pidctx->dst_pid, GF_PROP_PID_TIMESCALE, &PROP_UINT(25) );
     605             :                 }
     606             : 
     607             :         }
     608             :         return GF_OK;
     609             : }
     610             : 
     611             : 
     612           9 : static GF_Err ut_filter_update_arg(GF_Filter *filter, const char *arg_name, const GF_PropertyValue *arg_val)
     613             : {
     614           9 :         return GF_OK;
     615             : }
     616             : 
     617         385 : GF_Err utfilter_initialize(GF_Filter *filter)
     618             : {
     619             :         GF_PropertyValue p;
     620         385 :         GF_UnitTestFilter *stack = gf_filter_get_udta(filter);
     621             : 
     622         385 :         stack->pids = gf_list_new();
     623             : 
     624         385 :         if (stack->cov) {
     625             :                 Bool old_strict;
     626             :                 char szFmt[40];
     627             :                 s64 val;
     628             :                 u32 i;
     629             :                 GF_PropertyValue p2;
     630           3 :                 p = gf_props_parse_value(GF_PROP_BOOL, "prop", "true", NULL, 0);
     631           3 :                 if (p.value.boolean != GF_TRUE) {
     632           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing boolean value\n"));
     633             :                 }
     634           3 :                 p = gf_props_parse_value(GF_PROP_BOOL, "prop", "yes", NULL, 0);
     635           3 :                 if (p.value.boolean != GF_TRUE) {
     636           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing boolean value\n"));
     637             :                 }
     638           3 :                 p = gf_props_parse_value(GF_PROP_BOOL, "prop", "no", NULL, 0);
     639           3 :                 if (p.value.boolean != GF_FALSE) {
     640           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing boolean value\n"));
     641             :                 }
     642           3 :                 p = gf_props_parse_value(GF_PROP_BOOL, "prop", "false", NULL, 0);
     643           3 :                 if (p.value.boolean != GF_FALSE) {
     644           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing boolean value\n"));
     645             :                 }
     646           3 :                 p = gf_props_parse_value(GF_PROP_SINT, "prop", "-1", NULL, 0);
     647           3 :                 if (p.value.sint != -1) {
     648           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing sint value\n"));
     649             :                 }
     650           3 :                 p = gf_props_parse_value(GF_PROP_SINT, "prop", "-1k", NULL, 0);
     651           3 :                 if (p.value.sint != -1000) {
     652           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing sint value\n"));
     653             :                 }
     654           3 :                 p = gf_props_parse_value(GF_PROP_UINT, "prop", "1", NULL, 0);
     655           3 :                 if (p.value.uint != 1) {
     656           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing uint value\n"));
     657             :                 }
     658           3 :                 p = gf_props_parse_value(GF_PROP_UINT, "prop", "1m", NULL, 0);
     659           3 :                 if (p.value.uint != 1000000) {
     660           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing uint 1m value\n"));
     661             :                 }
     662           3 :                 p = gf_props_parse_value(GF_PROP_UINT, "prop", "0x10000000", NULL, 0);
     663           3 :                 if (p.value.uint != 0x10000000) {
     664           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing uint hex value\n"));
     665             :                 }
     666           3 :                 p = gf_props_parse_value(GF_PROP_UINT, "prop", "moof", NULL, 0);
     667           3 :                 if (p.value.uint != GF_4CC('m','o','o','f')) {
     668           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing uint 4CC value\n"));
     669             :                 }
     670             :                 val = 0xFFFFFFFF;
     671             :                 val *= 2;
     672             :                 sprintf(szFmt, ""LLD, -val);
     673           3 :                 p = gf_props_parse_value(GF_PROP_LSINT, "prop", szFmt, NULL, 0);
     674           3 :                 if (p.value.longsint != -val) {
     675           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing longsint value\n"));
     676             :                 }
     677           3 :                 p = gf_props_parse_value(GF_PROP_LSINT, "prop", "-1m", NULL, 0);
     678           3 :                 if (p.value.longsint != -1000000) {
     679           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing longsint value\n"));
     680             :                 }
     681             :                 sprintf(szFmt, ""LLU, val);
     682           3 :                 p = gf_props_parse_value(GF_PROP_LUINT, "prop", szFmt, NULL, 0);
     683           3 :                 if (p.value.longuint != val) {
     684           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing longuint value\n"));
     685             :                 }
     686           3 :                 p = gf_props_parse_value(GF_PROP_LUINT, "prop", "1k", NULL, 0);
     687           3 :                 if (p.value.longuint != 1000) {
     688           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing longuint value\n"));
     689             :                 }
     690           3 :                 p = gf_props_parse_value(GF_PROP_FLOAT, "prop", "1.0", NULL, 0);
     691           3 :                 if (p.value.fnumber != FIX_ONE) {
     692           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing float value\n"));
     693             :                 }
     694           3 :                 p = gf_props_parse_value(GF_PROP_DOUBLE, "prop", "1.0", NULL, 0);
     695           3 :                 if (p.value.number != 1.0) {
     696           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing double value\n"));
     697             :                 }
     698           3 :                 p = gf_props_parse_value(GF_PROP_DOUBLE, "prop", "1.0m", NULL, 0);
     699           3 :                 if (p.value.number != 1000000.0) {
     700           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing double value\n"));
     701             :                 }
     702           3 :                 p = gf_props_parse_value(GF_PROP_FRACTION, "prop", "1000/1", NULL, 0);
     703           3 :                 if ((p.value.frac.den != 1) || (p.value.frac.num != 1000)) {
     704           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing fraction value\n"));
     705             :                 }
     706           3 :                 p = gf_props_parse_value(GF_PROP_FRACTION, "prop", "1000", NULL, 0);
     707           3 :                 if ((p.value.frac.den != 1) || (p.value.frac.num != 1000)) {
     708           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing fraction value\n"));
     709             :                 }
     710           3 :                 p = gf_props_parse_value(GF_PROP_FRACTION, "prop", "1.001", NULL, 0);
     711           3 :                 if (p.value.frac.num * 1000 != 1001 * p.value.frac.den) {
     712           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing fraction fp value\n"));
     713             :                 }
     714           3 :                 p = gf_props_parse_value(GF_PROP_STRING, "prop", "test", NULL, 0);
     715           3 :                 if (!p.value.string || strcmp(p.value.string, "test")) {
     716           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing fraction value\n"));
     717             :                 }
     718           3 :                 if (p.value.string) gf_free(p.value.string);
     719             : 
     720           3 :                 p = gf_props_parse_value(GF_PROP_FRACTION64, "prop", "1.001", NULL, 0);
     721           3 :                 if (p.value.lfrac.num * 1000 != p.value.lfrac.den * 1001) {
     722           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing fraction64 fp value\n"));
     723             :                 }
     724           3 :                 p = gf_props_parse_value(GF_PROP_VEC2I, "prop", "1x1", NULL, 0);
     725           3 :                 if ((p.value.vec2i.x != 1) || (p.value.vec2i.y != 1) ) {
     726           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing vec2i value\n"));
     727             :                 }
     728           3 :                 p = gf_props_parse_value(GF_PROP_VEC2, "prop", "1x1", NULL, 0);
     729           3 :                 if ((p.value.vec2.x != 1.0) || (p.value.vec2.y != 1.0) ) {
     730           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing vec2 value\n"));
     731             :                 }
     732           3 :                 p = gf_props_parse_value(GF_PROP_VEC3I, "prop", "1x1x1", NULL, 0);
     733           3 :                 if ((p.value.vec3i.x != 1) || (p.value.vec3i.y != 1) || (p.value.vec3i.z != 1)) {
     734           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing vec3i value\n"));
     735             :                 }
     736           3 :                 p = gf_props_parse_value(GF_PROP_VEC4I, "prop", "1x1x1x1", NULL, 0);
     737           3 :                 if ((p.value.vec4i.x != 1) || (p.value.vec4i.y != 1) || (p.value.vec4i.z != 1) || (p.value.vec4i.w != 1)) {
     738           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing vec4i value\n"));
     739             :                 }
     740           3 :                 p = gf_props_parse_value(GF_PROP_PIXFMT, "prop", "rgb", NULL, 0);
     741           3 :                 if (p.value.uint != GF_PIXEL_RGB) {
     742           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing pixfmt value\n"));
     743             :                 }
     744           3 :                 p = gf_props_parse_value(GF_PROP_PCMFMT, "prop", "pcm", NULL, 0);
     745           3 :                 if (p.value.uint != GF_AUDIO_FMT_S16) {
     746           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing pcmfmt value\n"));
     747             :                 }
     748             : 
     749             :                 sprintf(szFmt, "%d@%p", (u32) sizeof(stack), stack);
     750           3 :                 p = gf_props_parse_value(GF_PROP_DATA, "prop", szFmt, NULL, 0);
     751           3 :                 if ((p.value.data.size != (u32) sizeof(stack)) || memcmp(p.value.data.ptr, (char *) stack, sizeof(stack))) {
     752           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing data value\n"));
     753             :                 }
     754           3 :                 p = gf_props_parse_value(GF_PROP_CONST_DATA, "prop", szFmt, NULL, 0);
     755           3 :                 if ((p.value.data.ptr != (u8 *) stack) || (p.value.data.size != (u32) sizeof(stack))) {
     756           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing data value\n"));
     757             :                 }
     758           3 :                 p = gf_props_parse_value(GF_PROP_CONST_DATA, "prop", "0xABCDEF", NULL, 0);
     759           3 :                 if (!p.value.data.ptr || (p.value.data.size != 3) || (p.value.data.ptr[0] != 0xAB) ) {
     760           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing data value\n"));
     761             :                 }
     762           3 :                 if (p.value.data.ptr) gf_free(p.value.data.ptr);
     763             : 
     764             :                 sprintf(szFmt, "%p", stack);
     765           3 :                 p = gf_props_parse_value(GF_PROP_POINTER, "prop", szFmt, NULL, 0);
     766           3 :                 if (p.value.ptr != stack) {
     767           0 :                         GF_LOG(GF_LOG_ERROR, GF_LOG_APP, ("[UTFilter] Error parsing data value\n"));
     768             :                 }
     769             : 
     770           3 :                 old_strict = gf_log_set_strict_error(GF_FALSE);
     771             :                 //negative tests
     772           3 :                 gf_props_parse_value(GF_PROP_STRING, "prop", "file@_no_exist", NULL, 0);
     773           3 :                 gf_props_parse_value(GF_PROP_STRING, "prop", "bxml@_no_exist", NULL, 0);
     774           3 :                 gf_props_parse_value(GF_PROP_DATA, "prop", "file@_no_exist", NULL, 0);
     775           3 :                 gf_props_parse_value(GF_PROP_DATA, "prop", "bxml@_no_exist", NULL, 0);
     776           3 :                 gf_props_parse_value(GF_PROP_BOOL, "prop", "", NULL, 0);
     777           3 :                 gf_props_parse_value(GF_PROP_SINT, "prop", "", NULL, 0);
     778           3 :                 gf_props_parse_value(GF_PROP_UINT, "prop", "", NULL, 0);
     779           3 :                 gf_props_parse_value(GF_PROP_LSINT, "prop", "", NULL, 0);
     780           3 :                 gf_props_parse_value(GF_PROP_LUINT, "prop", "", NULL, 0);
     781           3 :                 gf_props_parse_value(GF_PROP_FLOAT, "prop", "", NULL, 0);
     782           3 :                 gf_props_parse_value(GF_PROP_DOUBLE, "prop", "", NULL, 0);
     783           3 :                 gf_props_parse_value(GF_PROP_FRACTION, "prop", "", NULL, 0);
     784           3 :                 gf_props_parse_value(GF_PROP_FRACTION, "prop", "", NULL, 0);
     785           3 :                 gf_props_parse_value(GF_PROP_STRING, "prop", NULL, NULL, 0);
     786           3 :                 gf_props_parse_value(GF_PROP_DATA, "prop", "", NULL, 0);
     787           3 :                 gf_props_parse_value(GF_PROP_CONST_DATA, "prop", "", NULL, 0);
     788           3 :                 gf_props_parse_value(GF_PROP_POINTER, "prop", "", NULL, 0);
     789           3 :                 gf_props_parse_value(GF_PROP_BOOL, "prop", NULL, NULL, 0);
     790           3 :                 gf_props_parse_value(GF_PROP_SINT, "prop", NULL, NULL, 0);
     791           3 :                 gf_props_parse_value(GF_PROP_UINT, "prop", NULL, NULL, 0);
     792           3 :                 gf_props_parse_value(GF_PROP_LSINT, "prop", NULL, NULL, 0);
     793           3 :                 gf_props_parse_value(GF_PROP_LUINT, "prop", NULL, NULL, 0);
     794           3 :                 gf_props_parse_value(GF_PROP_FLOAT, "prop", NULL, NULL, 0);
     795           3 :                 gf_props_parse_value(GF_PROP_DOUBLE, "prop", NULL, NULL, 0);
     796           3 :                 gf_props_parse_value(GF_PROP_FRACTION, "prop", NULL, NULL, 0);
     797           3 :                 gf_props_parse_value(GF_PROP_FRACTION64, "prop", NULL, NULL, 0);
     798           3 :                 gf_props_parse_value(GF_PROP_VEC2I, "prop", NULL, NULL, 0);
     799           3 :                 gf_props_parse_value(GF_PROP_VEC2, "prop", NULL, NULL, 0);
     800           3 :                 gf_props_parse_value(GF_PROP_VEC3I, "prop", NULL, NULL, 0);
     801           3 :                 gf_props_parse_value(GF_PROP_VEC4I, "prop", NULL, NULL, 0);
     802           3 :                 gf_props_parse_value(GF_PROP_STRING, "prop", NULL, NULL, 0);
     803           3 :                 gf_props_parse_value(GF_PROP_DATA, "prop", NULL, NULL, 0);
     804           3 :                 gf_props_parse_value(GF_PROP_CONST_DATA, "prop", NULL, NULL, 0);
     805           3 :                 gf_props_parse_value(GF_PROP_POINTER, "prop", NULL, NULL, 0);
     806           3 :                 gf_props_parse_value(GF_PROP_UINT, "prop", "test", "foo|bar", 0);
     807           3 :                 gf_props_parse_value(100, "prop", "test", NULL, 0);
     808             : 
     809             :                 memset(&p, 0, sizeof(GF_PropertyValue));
     810           3 :                 p2=p;
     811         138 :                 for (i=GF_PROP_FORBIDEN; i<GF_PROP_LAST_DEFINED; i++) {
     812             :                         char dump[GF_PROP_DUMP_ARG_SIZE];
     813         135 :                         gf_props_get_type_name(i);
     814         135 :                         p.type = p2.type = i;
     815         135 :                         gf_props_equal(&p, &p2);
     816         135 :                         gf_props_dump_val(&p, dump, GF_PROP_DUMP_DATA_NONE, NULL);
     817             :                 }
     818           3 :                 p.type = GF_PROP_DATA;
     819           3 :                 p.value.data.size = 4;
     820           3 :                 p.value.data.ptr = "test";
     821           3 :                 p2 = p;
     822           3 :                 p2.value.data.ptr = NULL;
     823           3 :                 gf_props_equal(&p, &p2);
     824           3 :                 p2.value.data.size = 3;
     825           3 :                 p2.value.data.ptr = "test";
     826           3 :                 gf_props_equal(&p, &p2);
     827           3 :                 p2.value.data.size = 4;
     828           3 :                 gf_props_equal(&p, &p2);
     829             : 
     830           3 :                 p.type = GF_PROP_UINT_LIST;
     831           3 :                 i=0;
     832           3 :                 p.value.uint_list.nb_items=1;
     833           3 :                 p.value.uint_list.vals = &i;
     834           3 :                 p2 = p;
     835           3 :                 gf_props_equal(&p, &p2);
     836             : 
     837             : 
     838           3 :                 gf_log_set_strict_error(old_strict);
     839             :         }
     840             : 
     841         385 :         if (! strcmp( "UTSink", gf_filter_get_name(filter))) {
     842         176 :                 stack->mode=UTF_MODE_SINK;
     843         176 :                 gf_filter_set_max_extra_input_pids(filter, 10);
     844             :         }
     845         209 :         else if (! strcmp( "UTFilter", gf_filter_get_name(filter))) stack->mode=UTF_MODE_FILTER;
     846             :         else {
     847         141 :                 stack->mode=UTF_MODE_SOURCE;
     848         141 :                 return ut_filter_config_source(filter);
     849             :         }
     850             :         return GF_OK;
     851             : }
     852             : 
     853             : #define OFFS(_n)        #_n, offsetof(GF_UnitTestFilter, _n)
     854             : static const GF_FilterArgs UTFilterArgs[] =
     855             : {
     856             :         { OFFS(pid_att), "set default value for PID `cust` attribute", GF_PROP_NAME, "UTSourceData", NULL, 0},
     857             :         { OFFS(max_pck), "maximum number of packets to send in source mode", GF_PROP_UINT, "1000", NULL, 0},
     858             :         { OFFS(nb_pids), "number of PIDs in source mode", GF_PROP_UINT, "1", "1-+I", 0},
     859             :         { OFFS(max_out), "maximum number of shared packets not yet released in source/filter mode, no limit if -1", GF_PROP_SINT, "-1", NULL, GF_FS_ARG_UPDATE},
     860             :         { OFFS(alloc), "use allocated memory packets in source mode", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
     861             :         { OFFS(fwd), "indicate packet forward mode for filter.\n"
     862             :         "- shared: use shared memory (dangerous)\n"
     863             :         "- copy: use copy\n"
     864             :         "- ref: use references to source packet\n"
     865             :         "- mix: change mode at each packet sent", GF_PROP_UINT, "shared", "shared|copy|ref|mix", GF_FS_ARG_UPDATE},
     866             :         { OFFS(framing), "packet framing.\n"
     867             :         "- none: disable packet split\n"
     868             :         "- default: divide packets in 3 for filter mode and allows partial blocks for sink mode\n"
     869             :         "- nostart: same as default but does not signal packet start flag\n"
     870             :         "- noend: same as default but does not signal packet end flag"
     871             :         "", GF_PROP_UINT, "none", "none|default|nostart|noend", GF_FS_ARG_UPDATE},
     872             :         { OFFS(update), "send update message after half packet send. Update format is FID,argname,argval", GF_PROP_STRING, NULL, NULL, GF_FS_ARG_UPDATE},
     873             :         { OFFS(cov), "dump options and exercise error cases for code coverage", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
     874             :         { OFFS(norecfg), "disable reconfig on input pid in filter/sink mode", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
     875             :         { OFFS(gsftest), "dispatch a fake single video pid with props and packet props for GSF testing", GF_PROP_BOOL, "false", NULL, GF_FS_ARG_UPDATE},
     876             : 
     877             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_LSINT, "0", NULL, GF_FS_ARG_UPDATE},
     878             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_LUINT, "0", NULL, GF_FS_ARG_UPDATE},
     879             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_FLOAT, "0", NULL, GF_FS_ARG_UPDATE},
     880             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_DOUBLE, "0", NULL, GF_FS_ARG_UPDATE},
     881             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_FRACTION, "0", NULL, GF_FS_ARG_UPDATE},
     882             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_POINTER, "0", NULL, GF_FS_ARG_UPDATE},
     883             :         { OFFS(dummy1), "dummy for coverage", GF_PROP_FRACTION64, "0", NULL, GF_FS_ARG_UPDATE},
     884             :         { NULL }
     885             : };
     886             : 
     887             : #define UT_CAP_CODE             GF_4CC('c','u','s','t')
     888             : static const GF_FilterCapability UTFilterCaps[] =
     889             : {
     890             :         CAP_STRING(GF_CAPS_INPUT, UT_CAP_CODE, "UTSourceData"),
     891             :         CAP_STRING(GF_CAPS_INPUT, UT_CAP_CODE, "UTFilterData"),
     892             :         CAP_STRING(GF_CAPS_OUTPUT, UT_CAP_CODE, "UTSourceData"),
     893             :         CAP_STRING(GF_CAPS_OUTPUT, UT_CAP_CODE, "UTFilterData"),
     894             : };
     895             : 
     896             : static const GF_FilterCapability UTSinkInputs[] =
     897             : {
     898             :         CAP_STRING(GF_CAPS_INPUT, UT_CAP_CODE, "UTSourceData"),
     899             : };
     900             : 
     901             : static const GF_FilterCapability UTSink2Inputs[] =
     902             : {
     903             :         CAP_STRING(GF_CAPS_INPUT, UT_CAP_CODE, "UTFilterData"),
     904             : };
     905             : 
     906             : static const GF_FilterCapability UTSourceOutputs[] =
     907             : {
     908             :         CAP_STRING(GF_CAPS_OUTPUT, UT_CAP_CODE, "UTSourceData"),
     909             : };
     910             : 
     911             : 
     912             : const GF_FilterRegister UTFilterRegister = {
     913             :         .name = "UTFilter",
     914             :         GF_FS_SET_DESCRIPTION("Unit Test Filter")
     915             :         GF_FS_SET_HELP("This filter is only used for unit testing of filter framework")
     916             :         .private_size = sizeof(GF_UnitTestFilter),
     917             :         .flags = GF_FS_REG_EXPLICIT_ONLY,
     918             :         SETCAPS( UTFilterCaps),
     919             :         .args = UTFilterArgs,
     920             :         .initialize = utfilter_initialize,
     921             :         .finalize = ut_filter_finalize,
     922             :         .process = ut_filter_process_filter,
     923             :         .configure_pid = ut_filter_config_input,
     924             :         .update_arg = ut_filter_update_arg
     925             : };
     926             : 
     927             : 
     928             : const GF_FilterRegister UTSinkRegister = {
     929             :         .name = "UTSink",
     930             :         GF_FS_SET_DESCRIPTION("Unit Test Sink")
     931             :         GF_FS_SET_HELP("This filter is only used for unit testing of filter framework")
     932             :         .private_size = sizeof(GF_UnitTestFilter),
     933             :         .flags = GF_FS_REG_EXPLICIT_ONLY,
     934             :         SETCAPS(UTSinkInputs),
     935             :         .args = UTFilterArgs,
     936             :         .initialize = utfilter_initialize,
     937             :         .finalize = ut_filter_finalize,
     938             :         .process = ut_filter_process_sink,
     939             :         .configure_pid = ut_filter_config_input,
     940             :         .update_arg = ut_filter_update_arg
     941             : };
     942             : 
     943             : const GF_FilterRegister UTSink2Register = {
     944             :         .name = "UTSink2",
     945             :         GF_FS_SET_DESCRIPTION("Unit Test Sink2")
     946             :         GF_FS_SET_HELP("This filter is only used for unit testing of filter framework")
     947             :         .private_size = sizeof(GF_UnitTestFilter),
     948             :         .flags = GF_FS_REG_EXPLICIT_ONLY,
     949             :         SETCAPS(UTSink2Inputs),
     950             :         .args = UTFilterArgs,
     951             :         .initialize = utfilter_initialize,
     952             :         .finalize = ut_filter_finalize,
     953             :         .process = ut_filter_process_sink,
     954             :         .configure_pid = ut_filter_config_input,
     955             :         .update_arg = ut_filter_update_arg
     956             : };
     957             : 
     958             : const GF_FilterRegister UTSourceRegister = {
     959             :         .name = "UTSource",
     960             :         GF_FS_SET_DESCRIPTION("Unit Test Source")
     961             :         GF_FS_SET_HELP("This filter is only used for unit testing of filter framework")
     962             :         .private_size = sizeof(GF_UnitTestFilter),
     963             :         .flags = GF_FS_REG_EXPLICIT_ONLY,
     964             :         SETCAPS(UTSourceOutputs),
     965             :         .args = UTFilterArgs,
     966             :         .initialize = utfilter_initialize,
     967             :         .finalize = ut_filter_finalize,
     968             :         .process = ut_filter_process_source,
     969             :         .update_arg = ut_filter_update_arg
     970             : };
     971             : 
     972             : 
     973         142 : const GF_FilterRegister *ut_filter_register(GF_FilterSession *session, Bool load_meta_filters)
     974             : {
     975         142 :         return &UTFilterRegister;
     976             : }
     977         142 : const GF_FilterRegister *ut_source_register(GF_FilterSession *session, Bool load_meta_filters)
     978             : {
     979         142 :         return &UTSourceRegister;
     980             : }
     981         142 : const GF_FilterRegister *ut_sink_register(GF_FilterSession *session, Bool load_meta_filters)
     982             : {
     983         142 :         return &UTSinkRegister;
     984             : }
     985         142 : const GF_FilterRegister *ut_sink2_register(GF_FilterSession *session, Bool load_meta_filters)
     986             : {
     987         142 :         return &UTSink2Register;
     988             : }
     989             : 
     990             : 
     991             : 

Generated by: LCOV version 1.13