LCOV - code coverage report
Current view: top level - ietf - rtp_packetizer.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 188 275 68.4 %
Date: 2021-04-29 23:48:07 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2012
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
       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/internal/ietf_dev.h>
      27             : 
      28             : #ifndef GPAC_DISABLE_STREAMING
      29             : 
      30             : #include <gpac/constants.h>
      31             : #include <gpac/maths.h>
      32             : 
      33             : void InitSL_RTP(GF_SLConfig *slc);
      34             : 
      35             : 
      36             : 
      37             : 
      38             : GF_EXPORT
      39         110 : GP_RTPPacketizer *gf_rtp_builder_new(u32 rtp_payt, GF_SLConfig *slc, u32 flags,
      40             :                                      void *cbk_obj,
      41             :                                      void (*OnNewPacket)(void *cbk, GF_RTPHeader *header),
      42             :                                      void (*OnPacketDone)(void *cbk, GF_RTPHeader *header),
      43             :                                      void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig),
      44             :                                      void (*OnData)(void *cbk, u8 *data, u32 data_size, Bool is_head)
      45             :                                     )
      46             : {
      47             :         GP_RTPPacketizer *tmp;
      48         110 :         if (!rtp_payt || !cbk_obj || !OnPacketDone) return NULL;
      49             : 
      50         110 :         GF_SAFEALLOC(tmp, GP_RTPPacketizer);
      51         110 :         if (!tmp) return NULL;
      52             : 
      53         110 :         if (slc) {
      54         110 :                 memcpy(&tmp->sl_config, slc, sizeof(GF_SLConfig));
      55             :         } else {
      56           0 :                 memset(&tmp->sl_config, 0, sizeof(GF_SLConfig));
      57           0 :                 tmp->sl_config.useTimestampsFlag = 1;
      58           0 :                 tmp->sl_config.timestampLength = 32;
      59             :         }
      60         110 :         tmp->OnNewPacket = OnNewPacket;
      61         110 :         tmp->OnDataReference = OnDataReference;
      62         110 :         tmp->OnData = OnData;
      63         110 :         tmp->cbk_obj = cbk_obj;
      64         110 :         tmp->OnPacketDone = OnPacketDone;
      65         110 :         tmp->rtp_payt = rtp_payt;
      66         110 :         tmp->flags = flags;
      67             :         //default init
      68         110 :         tmp->sl_header.AU_sequenceNumber = 1;
      69         110 :         tmp->sl_header.packetSequenceNumber = 1;
      70             : 
      71             :         //we assume we start on a new AU
      72         110 :         tmp->sl_header.accessUnitStartFlag = 1;
      73         110 :         return tmp;
      74             : }
      75             : 
      76             : GF_EXPORT
      77         110 : void gf_rtp_builder_del(GP_RTPPacketizer *builder)
      78             : {
      79         110 :         if (!builder) return;
      80             : 
      81         110 :         if (builder->payload) gf_bs_del(builder->payload);
      82         110 :         if (builder->pck_hdr) gf_bs_del(builder->pck_hdr);
      83         110 :         gf_free(builder);
      84             : }
      85             : 
      86             : GF_EXPORT
      87       70383 : GF_Err gf_rtp_builder_process(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex)
      88             : {
      89       70383 :         if (!builder) return GF_BAD_PARAM;
      90             : 
      91       70383 :         switch (builder->rtp_payt) {
      92       18214 :         case GF_RTP_PAYT_MPEG4:
      93       18214 :                 return gp_rtp_builder_do_mpeg4(builder, data, data_size, IsAUEnd, FullAUSize);
      94             : #ifndef GPAC_DISABLE_AV_PARSERS
      95        2065 :         case GF_RTP_PAYT_MPEG12_VIDEO:
      96        2065 :                 return gp_rtp_builder_do_mpeg12_video(builder, data, data_size, IsAUEnd, FullAUSize);
      97             : #endif
      98        3876 :         case GF_RTP_PAYT_MPEG12_AUDIO:
      99        3876 :                 return gp_rtp_builder_do_mpeg12_audio(builder, data, data_size, IsAUEnd, FullAUSize);
     100         463 :         case GF_RTP_PAYT_H263:
     101         463 :                 return gp_rtp_builder_do_h263(builder, data, data_size, IsAUEnd, FullAUSize);
     102       21421 :         case GF_RTP_PAYT_AMR:
     103             :         case GF_RTP_PAYT_AMR_WB:
     104       21421 :                 return gp_rtp_builder_do_amr(builder, data, data_size, IsAUEnd, FullAUSize);
     105        1932 :         case GF_RTP_PAYT_3GPP_TEXT:
     106        1932 :                 return gp_rtp_builder_do_tx3g(builder, data, data_size, IsAUEnd, FullAUSize, duration, descIndex);
     107        3721 :         case GF_RTP_PAYT_H264_AVC:
     108             :         case GF_RTP_PAYT_H264_SVC:
     109        3721 :                 return gp_rtp_builder_do_avc(builder, data, data_size, IsAUEnd, FullAUSize);
     110         555 :         case GF_RTP_PAYT_QCELP:
     111         555 :                 return gp_rtp_builder_do_qcelp(builder, data, data_size, IsAUEnd, FullAUSize);
     112       15185 :         case GF_RTP_PAYT_EVRC_SMV:
     113       15185 :                 return gp_rtp_builder_do_smv(builder, data, data_size, IsAUEnd, FullAUSize);
     114          49 :         case GF_RTP_PAYT_LATM:
     115          49 :                 return gp_rtp_builder_do_latm(builder, data, data_size, IsAUEnd, FullAUSize, duration);
     116             : #if GPAC_ENABLE_3GPP_DIMS_RTP
     117             :         case GF_RTP_PAYT_3GPP_DIMS:
     118             :                 return gp_rtp_builder_do_dims(builder, data, data_size, IsAUEnd, FullAUSize, duration);
     119             : #endif
     120          61 :         case GF_RTP_PAYT_AC3:
     121          61 :                 return gp_rtp_builder_do_ac3(builder, data, data_size, IsAUEnd, FullAUSize);
     122        2786 :         case GF_RTP_PAYT_HEVC:
     123             :         case GF_RTP_PAYT_LHVC:
     124        2786 :                 return gp_rtp_builder_do_hevc(builder, data, data_size, IsAUEnd, FullAUSize);
     125          55 :         case GF_RTP_PAYT_MP2T:
     126          55 :                 return gp_rtp_builder_do_mp2t(builder, data, data_size, IsAUEnd, FullAUSize);
     127             :         default:
     128             :                 return GF_NOT_SUPPORTED;
     129             :         }
     130             : }
     131             : 
     132             : 
     133             : //Compute the #params of the slMap
     134             : GF_EXPORT
     135         110 : void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, u32 max_ptime,
     136             :                          u32 StreamType, u32 codecid, u32 PL_ID,
     137             :                          u32 avgSize, u32 maxSize,
     138             :                          u32 avgTS, u32 maxDTS,
     139             :                          u32 IV_length, u32 KI_length,
     140             :                          char *pref_mode)
     141             : {
     142             :         u32 k, ismacrypt_flags;
     143             : 
     144         110 :         memset(&builder->slMap, 0, sizeof(GP_RTPSLMap));
     145         110 :         builder->Path_MTU = PathMTU;
     146         110 :         builder->PayloadType = PayloadType;
     147         110 :         builder->slMap.StreamType = StreamType;
     148         110 :         builder->slMap.CodecID = codecid;
     149         110 :         builder->slMap.PL_ID = PL_ID;
     150         110 :         builder->max_ptime = max_ptime;
     151         110 :         if (pref_mode) strcpy(builder->slMap.mode, pref_mode);
     152             : 
     153             : 
     154             :         //some cst vars
     155         110 :         builder->rtp_header.Version = 2;
     156         110 :         builder->rtp_header.PayloadType = builder->PayloadType;
     157             : 
     158             :         /*our max config is with 1 packet only (SingleSL)*/
     159         110 :         builder->first_sl_in_rtp = GF_TRUE;
     160             :         /*no AUX data*/
     161         110 :         builder->slMap.AuxiliaryDataSizeLength = 0;
     162             : 
     163             : 
     164             :         /*just compute max aggregation size*/
     165         110 :         switch (builder->rtp_payt) {
     166           8 :         case GF_RTP_PAYT_QCELP:
     167             :         case GF_RTP_PAYT_EVRC_SMV:
     168             :         case GF_RTP_PAYT_AMR:
     169             :         case GF_RTP_PAYT_AMR_WB:
     170             :         {
     171             :                 u32 nb_pck = 1;
     172             :                 u32 block_size = 160;
     173             :                 /*compute max frames per packet - if no avg size, use max size per codec*/
     174           8 :                 if (builder->flags & GP_RTP_PCK_USE_MULTI) {
     175           0 :                         if (builder->rtp_payt == GF_RTP_PAYT_QCELP) {
     176           0 :                                 if (!avgSize) avgSize = 35;
     177           0 :                                 nb_pck = (PathMTU-1) / avgSize; /*one-byte header*/
     178           0 :                                 if (nb_pck>10) nb_pck=10;    /*cf RFC2658*/
     179           0 :                         } else if (builder->rtp_payt == GF_RTP_PAYT_EVRC_SMV) {
     180           0 :                                 if (!avgSize) avgSize = 23;
     181           0 :                                 nb_pck = (PathMTU) / avgSize;
     182           0 :                                 if (nb_pck>32) nb_pck=32;    /*cf RFC3558*/
     183           0 :                         } else if (builder->rtp_payt == GF_RTP_PAYT_AMR_WB) {
     184           0 :                                 if (!avgSize) avgSize = 61;
     185           0 :                                 nb_pck = (PathMTU-1) / avgSize;
     186             :                                 block_size = 320;
     187             :                         } else {
     188           0 :                                 if (!avgSize) avgSize = 32;
     189           0 :                                 nb_pck = (PathMTU-1) / avgSize;
     190             :                         }
     191           0 :                         if (max_ptime) {
     192           0 :                                 u32 max_pck = max_ptime / block_size;
     193           0 :                                 if (nb_pck > max_pck) nb_pck = max_pck;
     194             :                         }
     195             :                 }
     196           0 :                 if (nb_pck<=1) {
     197           8 :                         builder->flags &= ~(GP_RTP_PCK_USE_MULTI|GP_RTP_PCK_USE_INTERLEAVING);
     198           8 :                         builder->auh_size = 1;
     199             :                 } else {
     200           0 :                         builder->auh_size = nb_pck;
     201             :                 }
     202             :                 /*remove all MPEG-4 and ISMA flags */
     203           8 :                 builder->flags &= 0x07;
     204             :         }
     205           8 :         return;
     206             :         case GF_RTP_PAYT_LATM:
     207             :         case GF_RTP_PAYT_MPEG4:
     208             :                 break;
     209          49 :         default:
     210             :                 /*remove all MPEG-4 and ISMA flags */
     211          49 :                 builder->flags &= 0x07;
     212             :                 /*disable aggregation for visual streams, except for AVC where STAP/MTAP can be used*/
     213          49 :                 if (StreamType==GF_STREAM_VISUAL) {
     214          27 :                         if ((codecid != GF_CODECID_AVC) && (codecid != GF_CODECID_SVC) && (codecid != GF_CODECID_MVC) && (codecid != GF_CODECID_HEVC) && (codecid != GF_CODECID_LHVC)) {
     215           7 :                                 builder->flags &= ~GP_RTP_PCK_USE_MULTI;
     216             :                         }
     217             :                 }
     218          22 :                 else if (avgSize && (PathMTU <= avgSize) ) {
     219           0 :                         builder->flags &= ~GP_RTP_PCK_USE_MULTI;
     220             :                 }
     221             :                 return;
     222             :         }
     223             : 
     224          53 :         builder->slMap.IV_length = IV_length;
     225          53 :         builder->slMap.KI_length = KI_length;
     226             : 
     227             :         ismacrypt_flags = 0;
     228          53 :         if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) ismacrypt_flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION;
     229          53 :         if (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ismacrypt_flags |= GP_RTP_PCK_KEY_IDX_PER_AU;
     230             : 
     231             :         /*mode setup*/
     232          53 :         if (!strnicmp(builder->slMap.mode, "AAC", 3)) {
     233          25 :                 builder->flags = GP_RTP_PCK_USE_MULTI | GP_RTP_PCK_SIGNAL_SIZE | GP_RTP_PCK_SIGNAL_AU_IDX | ismacrypt_flags;
     234             :                 /*if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) */
     235          25 :                 builder->slMap.ConstantDuration = avgTS;
     236             : 
     237             :                 /*AAC LBR*/
     238          25 :                 if (maxSize < 63) {
     239             :                         strcpy(builder->slMap.mode, "AAC-lbr");
     240           0 :                         builder->slMap.IndexLength = builder->slMap.IndexDeltaLength = 2;
     241           0 :                         builder->slMap.SizeLength = 6;
     242             :                 }
     243             :                 /*AAC HBR*/
     244             :                 else {
     245             :                         strcpy(builder->slMap.mode, "AAC-hbr");
     246          25 :                         builder->slMap.IndexLength = builder->slMap.IndexDeltaLength = 3;
     247          25 :                         builder->slMap.SizeLength = 13;
     248             :                 }
     249             :                 goto check_header;
     250             :         }
     251          28 :         if (!strnicmp(builder->slMap.mode, "CELP", 4)) {
     252             :                 /*CELP-cbr*/
     253           0 :                 if (maxSize == avgSize) {
     254             :                         /*reset flags (interleaving forbidden)*/
     255           0 :                         builder->flags = GP_RTP_PCK_USE_MULTI | ismacrypt_flags;
     256             :                         strcpy(builder->slMap.mode, "CELP-cbr");
     257           0 :                         builder->slMap.ConstantSize = avgSize;
     258           0 :                         builder->slMap.ConstantDuration = avgTS;
     259             :                 }
     260             :                 /*CELP VBR*/
     261             :                 else {
     262             :                         strcpy(builder->slMap.mode, "CELP-vbr");
     263           0 :                         builder->slMap.IndexLength = builder->slMap.IndexDeltaLength = 2;
     264           0 :                         builder->slMap.SizeLength = 6;
     265           0 :                         /*if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) */builder->slMap.ConstantDuration = avgTS;
     266           0 :                         builder->flags = GP_RTP_PCK_USE_MULTI | GP_RTP_PCK_SIGNAL_SIZE | GP_RTP_PCK_SIGNAL_AU_IDX | ismacrypt_flags;
     267             :                 }
     268             :                 goto check_header;
     269             :         }
     270             : 
     271             :         /*generic setup by flags*/
     272             : 
     273             :         /*size*/
     274          28 :         if (builder->flags & GP_RTP_PCK_SIGNAL_SIZE) {
     275           0 :                 if (avgSize==maxSize) {
     276           0 :                         builder->slMap.SizeLength = 0;
     277           0 :                         builder->slMap.ConstantSize = maxSize;
     278             :                 } else {
     279           0 :                         builder->slMap.SizeLength = gf_get_bit_size(maxSize ? maxSize : PathMTU);
     280           0 :                         builder->slMap.ConstantSize = 0;
     281             :                 }
     282             :         } else {
     283          28 :                 builder->slMap.SizeLength = 0;
     284          28 :                 if (builder->flags & GP_RTP_PCK_USE_MULTI)
     285           0 :                         builder->slMap.ConstantSize = (avgSize==maxSize) ? maxSize : 0;
     286             :                 else
     287          28 :                         builder->slMap.ConstantSize = 0;
     288             :         }
     289             : 
     290             :         /*single SL per RTP*/
     291          28 :         if (!(builder->flags & GP_RTP_PCK_USE_MULTI)) {
     292          28 :                 if ( builder->sl_config.AUSeqNumLength && (builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX)) {
     293           0 :                         builder->slMap.IndexLength = builder->sl_config.AUSeqNumLength;
     294             :                 } else {
     295          28 :                         builder->slMap.IndexLength = 0;
     296             :                 }
     297             :                 /*one packet per RTP so no delta*/
     298          28 :                 builder->slMap.IndexDeltaLength = 0;
     299          28 :                 builder->slMap.IV_delta_length = 0;
     300             : 
     301             :                 /*CTS Delta is always 0 since we have one SL packet per RTP*/
     302          28 :                 builder->slMap.CTSDeltaLength = 0;
     303             : 
     304             :                 /*DTS Delta depends on the video type*/
     305          28 :                 if ((builder->flags & GP_RTP_PCK_SIGNAL_TS) && maxDTS )
     306           6 :                         builder->slMap.DTSDeltaLength = gf_get_bit_size(maxDTS);
     307             :                 else
     308          22 :                         builder->slMap.DTSDeltaLength = 0;
     309             : 
     310             :                 /*RAP*/
     311          28 :                 if (builder->sl_config.useRandomAccessPointFlag && (builder->flags & GP_RTP_PCK_SIGNAL_RAP)) {
     312           5 :                         builder->slMap.RandomAccessIndication = GF_TRUE;
     313             :                 } else {
     314          23 :                         builder->slMap.RandomAccessIndication = GF_FALSE;
     315             :                 }
     316             : 
     317             :                 /*stream state*/
     318          28 :                 if (builder->flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) {
     319           1 :                         if (!builder->sl_config.AUSeqNumLength) builder->sl_config.AUSeqNumLength = 4;
     320           1 :                         builder->slMap.StreamStateIndication = builder->sl_config.AUSeqNumLength;
     321             :                 }
     322             :                 goto check_header;
     323             :         }
     324             : 
     325             :         /*this is the avg samples we can store per RTP packet*/
     326           0 :         k = PathMTU / avgSize;
     327           0 :         if (k<=1) {
     328           0 :                 builder->flags &= ~GP_RTP_PCK_USE_MULTI;
     329             :                 /*keep TS signaling for B-frames (eg never default to M4V-ES when B-frames are present)*/
     330             :                 //builder->flags &= ~GP_RTP_PCK_SIGNAL_TS;
     331           0 :                 builder->flags &= ~GP_RTP_PCK_SIGNAL_SIZE;
     332           0 :                 builder->flags &= ~GP_RTP_PCK_SIGNAL_AU_IDX;
     333           0 :                 builder->flags &= ~GP_RTP_PCK_USE_INTERLEAVING;
     334           0 :                 builder->flags &= ~GP_RTP_PCK_KEY_IDX_PER_AU;
     335           0 :                 gf_rtp_builder_init(builder, PayloadType, PathMTU, max_ptime, StreamType, codecid, PL_ID, avgSize, maxSize, avgTS, maxDTS, IV_length, KI_length, pref_mode);
     336           0 :                 return;
     337             :         }
     338             : 
     339             :         /*multiple SL per RTP - check if we have to send TS*/
     340           0 :         builder->slMap.ConstantDuration = builder->sl_config.CUDuration;
     341           0 :         if (!builder->slMap.ConstantDuration) {
     342           0 :                 builder->flags |= GP_RTP_PCK_SIGNAL_TS;
     343             :         }
     344             :         /*if we have a constant duration and are not writting TSs, make sure we write AU IDX when interleaving*/
     345           0 :         else if (! (builder->flags & GP_RTP_PCK_SIGNAL_TS) && (builder->flags & GP_RTP_PCK_USE_INTERLEAVING)) {
     346           0 :                 builder->flags |= GP_RTP_PCK_SIGNAL_AU_IDX;
     347             :         }
     348             : 
     349           0 :         if (builder->flags & GP_RTP_PCK_SIGNAL_TS) {
     350             :                 /*compute CTS delta*/
     351           0 :                 builder->slMap.CTSDeltaLength = gf_get_bit_size(k*avgTS);
     352             : 
     353             :                 /*compute DTS delta. Delta is ALWAYS from the CTS of the same sample*/
     354           0 :                 if (maxDTS)
     355           0 :                         builder->slMap.DTSDeltaLength = gf_get_bit_size(maxDTS);
     356             :                 else
     357           0 :                         builder->slMap.DTSDeltaLength = 0;
     358             :         }
     359             : 
     360           0 :         if ((builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX) && builder->sl_config.AUSeqNumLength) {
     361           0 :                 builder->slMap.IndexLength = builder->sl_config.AUSeqNumLength;
     362             :                 /*and k-1 AUs in Delta*/
     363           0 :                 builder->slMap.IndexDeltaLength = (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) ? gf_get_bit_size(k-1) : 0;
     364             :         }
     365           0 :         else if (builder->flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) {
     366           0 :                 if (!builder->sl_config.AUSeqNumLength) builder->sl_config.AUSeqNumLength = 4;
     367           0 :                 builder->slMap.StreamStateIndication = builder->sl_config.AUSeqNumLength;
     368             :         }
     369             : 
     370             :         /*RAP*/
     371           0 :         if (builder->sl_config.useRandomAccessPointFlag && (builder->flags & GP_RTP_PCK_SIGNAL_RAP)) {
     372           0 :                 builder->slMap.RandomAccessIndication = GF_TRUE;
     373             :         } else {
     374           0 :                 builder->slMap.RandomAccessIndication = GF_FALSE;
     375             :         }
     376             : 
     377          53 : check_header:
     378             : 
     379             :         /*IV delta only if interleaving (otherwise reconstruction from IV is trivial)*/
     380          53 :         if (IV_length && (builder->flags & GP_RTP_PCK_USE_INTERLEAVING)) {
     381           0 :                 builder->slMap.IV_delta_length = gf_get_bit_size(maxSize);
     382             :         }
     383             :         /*ISMACryp video mode*/
     384          53 :         if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.CodecID==GF_CODECID_MPEG4_PART2)
     385           7 :                 && (builder->flags & GP_RTP_PCK_SIGNAL_RAP) && builder->slMap.IV_length
     386             :                 && !(builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX) && !(builder->flags & GP_RTP_PCK_SIGNAL_SIZE)
     387             :                 /*shall have SignalTS*/
     388           0 :                 && (builder->flags & GP_RTP_PCK_SIGNAL_TS) && !(builder->flags & GP_RTP_PCK_USE_MULTI)
     389             :            ) {
     390             :                 strcpy(builder->slMap.mode, "mpeg4-video");
     391             :         }
     392             :         /*ISMACryp AVC video mode*/
     393          53 :         else if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.CodecID==GF_CODECID_AVC)
     394           1 :                  && (builder->flags & GP_RTP_PCK_SIGNAL_RAP) && builder->slMap.IV_length
     395             :                  && !(builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX) && !(builder->flags & GP_RTP_PCK_SIGNAL_SIZE)
     396             :                  /*shall have SignalTS*/
     397           1 :                  && (builder->flags & GP_RTP_PCK_SIGNAL_TS) && !(builder->flags & GP_RTP_PCK_USE_MULTI)
     398             :                 ) {
     399             :                 strcpy(builder->slMap.mode, "avc-video");
     400             :         }
     401             : 
     402             :         /*check if we use AU header or not*/
     403          53 :         if (!builder->slMap.SizeLength
     404          53 :                 && !builder->slMap.IndexLength
     405             :                 && !builder->slMap.IndexDeltaLength
     406          28 :                 && !builder->slMap.DTSDeltaLength
     407             :                 && !builder->slMap.CTSDeltaLength
     408          22 :                 && !builder->slMap.RandomAccessIndication
     409             :                 && !builder->slMap.IV_length
     410          18 :                 && !builder->slMap.KI_length
     411             :            ) {
     412          18 :                 builder->has_AU_header = GF_FALSE;
     413             :         } else {
     414          35 :                 builder->has_AU_header = GF_TRUE;
     415             :         }
     416             : }
     417             : 
     418         932 : void gf_rtp_builder_set_cryp_info(GP_RTPPacketizer *builder, u64 IV, char *key_indicator, Bool is_encrypted)
     419             : {
     420         932 :         if (!builder) return;
     421         932 :         if (!key_indicator) {
     422         932 :                 if (builder->key_indicator) {
     423             :                         /*force flush if no provision for keyIndicator per AU*/
     424           0 :                         builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? GF_FALSE : GF_TRUE;
     425           0 :                         gf_free(builder->key_indicator);
     426           0 :                         builder->key_indicator = NULL;
     427             :                 }
     428           0 :         } else if (!builder->key_indicator
     429           0 :                    ||
     430           0 :                    memcmp(builder->key_indicator, key_indicator, sizeof(char)*builder->slMap.KI_length)
     431             :                   ) {
     432             :                 /*force flush if no provision for keyIndicator per AU*/
     433           0 :                 builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? GF_FALSE : GF_TRUE;
     434             : 
     435           0 :                 if (!builder->key_indicator) builder->key_indicator = (char *) gf_malloc(sizeof(char)*builder->slMap.KI_length);
     436           0 :                 memcpy(builder->key_indicator, key_indicator, sizeof(char)*builder->slMap.KI_length);
     437             :         }
     438         932 :         if (builder->IV != IV) {
     439           0 :                 builder->IV = IV;
     440           0 :                 if (builder->slMap.IV_delta_length && (builder->slMap.IV_delta_length < gf_get_bit_size((u32) (IV - builder->first_AU_IV) ))) {
     441           0 :                         builder->first_AU_IV = IV;
     442           0 :                         builder->force_flush = GF_TRUE;
     443             :                 }
     444             :         }
     445         932 :         builder->is_encrypted = is_encrypted;
     446             : }
     447             : 
     448             : GF_EXPORT
     449         182 : Bool gf_rtp_builder_get_payload_name(GP_RTPPacketizer *rtpb, char szPayloadName[20], char szMediaName[20])
     450             : {
     451         182 :         u32 flags = rtpb->flags;
     452             : 
     453         182 :         switch (rtpb->rtp_payt) {
     454          90 :         case GF_RTP_PAYT_MPEG4:
     455          90 :                 if ((rtpb->slMap.StreamType==GF_STREAM_VISUAL) && (rtpb->slMap.CodecID==GF_CODECID_MPEG4_PART2)) {
     456             :                         strcpy(szMediaName, "video");
     457             :                         /*ISMACryp video*/
     458          12 :                         if ( (flags & GP_RTP_PCK_SIGNAL_RAP) && rtpb->slMap.IV_length
     459             :                                 && !(flags & GP_RTP_PCK_SIGNAL_AU_IDX) && !(flags & GP_RTP_PCK_SIGNAL_SIZE)
     460           0 :                                 && (flags & GP_RTP_PCK_SIGNAL_TS) && !(flags & GP_RTP_PCK_USE_MULTI)
     461             :                            )
     462             :                         {
     463             :                                 strcpy(szPayloadName, "enc-mpeg4-generic");
     464           0 :                                 return GF_TRUE;
     465             :                         }
     466             :                         /*mpeg4-generic*/
     467          12 :                         if ( (flags & GP_RTP_PCK_SIGNAL_RAP) || (flags & GP_RTP_PCK_SIGNAL_AU_IDX) || (flags & GP_RTP_PCK_SIGNAL_SIZE)
     468          12 :                                 || (flags & GP_RTP_PCK_SIGNAL_TS) || (flags & GP_RTP_PCK_USE_MULTI) ) {
     469             :                                 strcpy(szPayloadName, "mpeg4-generic");
     470          10 :                                 return GF_TRUE;
     471             :                         } else {
     472             :                                 strcpy(szPayloadName, "MP4V-ES");
     473           2 :                                 return GF_TRUE;
     474             :                         }
     475             :                 }
     476             :                 /*for all other types*/
     477          78 :                 if (rtpb->slMap.StreamType==GF_STREAM_AUDIO) strcpy(szMediaName, "audio");
     478          37 :                 else if (rtpb->slMap.StreamType==GF_STREAM_MPEGJ) strcpy(szMediaName, "application");
     479             :                 else strcpy(szMediaName, "video");
     480          78 :                 strcpy(szPayloadName, rtpb->slMap.IV_length ? "enc-mpeg4-generic" : "mpeg4-generic");
     481          78 :                 return GF_TRUE;
     482             :         case GF_RTP_PAYT_MPEG12_VIDEO:
     483             :                 strcpy(szMediaName, "video");
     484             :                 strcpy(szPayloadName, "MPV");
     485           6 :                 return GF_TRUE;
     486             :         case GF_RTP_PAYT_MPEG12_AUDIO:
     487             :                 strcpy(szMediaName, "audio");
     488             :                 strcpy(szPayloadName, "MPA");
     489          16 :                 return GF_TRUE;
     490             :         case GF_RTP_PAYT_H263:
     491             :                 strcpy(szMediaName, "video");
     492             :                 strcpy(szPayloadName, "H263-1998");
     493           4 :                 return GF_TRUE;
     494             :         case GF_RTP_PAYT_AMR:
     495             :                 strcpy(szMediaName, "audio");
     496             :                 strcpy(szPayloadName, "AMR");
     497           4 :                 return GF_TRUE;
     498             :         case GF_RTP_PAYT_AMR_WB:
     499             :                 strcpy(szMediaName, "audio");
     500             :                 strcpy(szPayloadName, "AMR-WB");
     501           2 :                 return GF_TRUE;
     502             :         case GF_RTP_PAYT_3GPP_TEXT:
     503             :                 strcpy(szMediaName, "text");
     504             :                 strcpy(szPayloadName, "3gpp-tt");
     505          16 :                 return GF_TRUE;
     506             :         case GF_RTP_PAYT_H264_AVC:
     507             :                 strcpy(szMediaName, "video");
     508             :                 strcpy(szPayloadName, "H264");
     509          28 :                 return GF_TRUE;
     510             :         case GF_RTP_PAYT_QCELP:
     511             :                 strcpy(szMediaName, "audio");
     512             :                 strcpy(szPayloadName, "QCELP");
     513           4 :                 return GF_TRUE;
     514             :         case GF_RTP_PAYT_EVRC_SMV:
     515             :                 strcpy(szMediaName, "audio");
     516           2 :                 if ((rtpb->slMap.CodecID==0xA0) || (rtpb->slMap.CodecID==GF_CODECID_EVRC))
     517             :                         strcpy(szPayloadName, "EVRC");
     518             :                 else
     519             :                         strcpy(szPayloadName, "SMV");
     520             : 
     521             :                 /*header-free version*/
     522           2 :                 if (rtpb->auh_size<=1) strcat(szPayloadName, "0");
     523             :                 return GF_TRUE;
     524             :         case GF_RTP_PAYT_LATM:
     525             :                 strcpy(szMediaName, "audio");
     526             :                 strcpy(szPayloadName, "MP4A-LATM");
     527           2 :                 return GF_TRUE;
     528             : #if GPAC_ENABLE_3GPP_DIMS_RTP
     529             :         case GF_RTP_PAYT_3GPP_DIMS:
     530             :                 strcpy(szMediaName, "video");
     531             :                 strcpy(szPayloadName, "richmedia+xml");
     532             :                 return GF_TRUE;
     533             : #endif
     534             :         case GF_RTP_PAYT_AC3:
     535             :                 strcpy(szMediaName, "audio");
     536             :                 strcpy(szPayloadName, "ac3");
     537           4 :                 return GF_TRUE;
     538             :         case GF_RTP_PAYT_H264_SVC:
     539             :                 strcpy(szMediaName, "video");
     540             :                 strcpy(szPayloadName, "H264-SVC");
     541           0 :                 return GF_TRUE;
     542             :         case GF_RTP_PAYT_HEVC:
     543             :                 strcpy(szMediaName, "video");
     544             :                 strcpy(szPayloadName, "H265");
     545           4 :                 return GF_TRUE;
     546             :         case GF_RTP_PAYT_LHVC:
     547             :                 strcpy(szMediaName, "video");
     548             :                 strcpy(szPayloadName, "H265-SHVC");
     549           0 :                 return GF_TRUE;
     550             :         default:
     551             :                 strcpy(szMediaName, "");
     552             :                 strcpy(szPayloadName, "");
     553           0 :                 return GF_FALSE;
     554             :         }
     555             :         return GF_FALSE;
     556             : }
     557             : 
     558             : 
     559             : GF_EXPORT
     560          53 : GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, char *dsi, u32 dsi_size)
     561             : {
     562             :         char buffer[20100], dsiString[20000];
     563             :         u32 i, k;
     564             :         Bool is_first = GF_TRUE;
     565             : 
     566          53 :         if ((builder->rtp_payt!=GF_RTP_PAYT_MPEG4) && (builder->rtp_payt!=GF_RTP_PAYT_LATM) ) return GF_BAD_PARAM;
     567             : 
     568             : #define SDP_ADD_INT(_name, _val) { if (!is_first) strcat(sdpLine, "; "); sprintf(buffer, "%s=%d", _name, _val); strcat(sdpLine, buffer); is_first = 0;}
     569             : #define SDP_ADD_STR(_name, _val) { if (!is_first) strcat(sdpLine, "; "); sprintf(buffer, "%s=%s", _name, _val); strcat(sdpLine, buffer); is_first = 0;}
     570             : 
     571          53 :         sprintf(sdpLine, "a=fmtp:%d ", builder->PayloadType);
     572             : 
     573             :         /*mandatory fields*/
     574          53 :         if (builder->slMap.PL_ID) SDP_ADD_INT("profile-level-id", builder->slMap.PL_ID);
     575             : 
     576          53 :         if (builder->rtp_payt == GF_RTP_PAYT_LATM) SDP_ADD_INT("cpresent", 0);
     577             : 
     578          53 :         if (dsi && dsi_size) {
     579             :                 k = 0;
     580        7060 :                 for (i=0; i<dsi_size; i++) {
     581        7060 :                         sprintf(&dsiString[k], "%02x", (unsigned char) dsi[i]);
     582        7060 :                         k+=2;
     583             :                 }
     584          46 :                 dsiString[k] = 0;
     585          46 :                 SDP_ADD_STR("config", dsiString);
     586             :         }
     587          53 :         if (!strcmp(payload_name, "MP4V-ES") || (builder->rtp_payt == GF_RTP_PAYT_LATM) ) return GF_OK;
     588             : 
     589          98 :         SDP_ADD_INT("streamType", builder->slMap.StreamType);
     590          49 :         if (strcmp(builder->slMap.mode, "") && strcmp(builder->slMap.mode, "default")) {
     591          24 :                 SDP_ADD_STR("mode", builder->slMap.mode);
     592             :         } else {
     593             :                 SDP_ADD_STR("mode", "generic");
     594             :         }
     595             : 
     596             :         /*optional fields*/
     597          98 :         if (builder->slMap.CodecID) SDP_ADD_INT("objectType", builder->slMap.CodecID);
     598          49 :         if (builder->slMap.ConstantSize) SDP_ADD_INT("constantSize", builder->slMap.ConstantSize);
     599          72 :         if (builder->slMap.ConstantDuration) SDP_ADD_INT("constantDuration", builder->slMap.ConstantDuration);
     600          49 :         if (builder->slMap.maxDisplacement) SDP_ADD_INT("maxDisplacement", builder->slMap.maxDisplacement);
     601          49 :         if (builder->slMap.deinterleaveBufferSize) SDP_ADD_INT("de-interleaveBufferSize", builder->slMap.deinterleaveBufferSize);
     602          72 :         if (builder->slMap.SizeLength) SDP_ADD_INT("sizeLength", builder->slMap.SizeLength);
     603          72 :         if (builder->slMap.IndexLength) SDP_ADD_INT("indexLength", builder->slMap.IndexLength);
     604          72 :         if (builder->slMap.IndexDeltaLength) SDP_ADD_INT("indexDeltaLength", builder->slMap.IndexDeltaLength);
     605          49 :         if (builder->slMap.CTSDeltaLength) SDP_ADD_INT("CTSDeltaLength", builder->slMap.CTSDeltaLength);
     606          55 :         if (builder->slMap.DTSDeltaLength) SDP_ADD_INT("DTSDeltaLength", builder->slMap.DTSDeltaLength);
     607          54 :         if (builder->slMap.RandomAccessIndication) SDP_ADD_INT("randomAccessIndication", builder->slMap.RandomAccessIndication);
     608          50 :         if (builder->slMap.StreamStateIndication) SDP_ADD_INT("streamStateIndication", builder->slMap.StreamStateIndication);
     609          49 :         if (builder->slMap.AuxiliaryDataSizeLength) SDP_ADD_INT("auxiliaryDataSizeLength", builder->slMap.AuxiliaryDataSizeLength);
     610             : 
     611             :         /*ISMACryp config*/
     612          49 :         if (builder->slMap.IV_length) {
     613             :                 /*don't write default*/
     614             :                 /*SDP_ADD_STR("ISMACrypCryptoSuite", "AES_CTR_128");*/
     615           5 :                 if (builder->flags & GP_RTP_PCK_SELECTIVE_ENCRYPTION) SDP_ADD_INT("ISMACrypSelectiveEncryption", 1);
     616           5 :                 SDP_ADD_INT("ISMACrypIVLength", builder->slMap.IV_length);
     617           5 :                 if (builder->slMap.IV_delta_length) SDP_ADD_INT("ISMACrypDeltaIVLength", builder->slMap.IV_delta_length);
     618           5 :                 if (builder->slMap.KI_length) SDP_ADD_INT("ISMACrypKeyIndicatorLength", builder->slMap.KI_length);
     619           5 :                 if (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) SDP_ADD_INT("ISMACrypKeyIndicatorPerAU", 1);
     620             :         }
     621             :         return GF_OK;
     622             : }
     623             : 
     624             : #endif /*GPAC_DISABLE_STREAMING*/

Generated by: LCOV version 1.13