home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11.lha / ccs-lib / lib / rtp_group.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-12  |  5.4 KB  |  193 lines

  1. /*    RTP_group . C
  2. #
  3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4.  
  5. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  6. Permission is granted to reproduce this software for non-commercial
  7. purposes provided that this notice is left intact.
  8.  
  9. It is acknowledged that the U.S. Government has rights to this software
  10. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  11. and the University of California.
  12.  
  13. This software is provided as a professional and academic contribution
  14. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  15. with no warranties of any kind whatsoever, no support, no promise of
  16. updates, or printed documentation. By using this software, you
  17. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  18. University of California shall have no liability with respect to the
  19. infringement of other copyrights by any part of this software.
  20.  
  21. For further information about this notice, contact William Johnston,
  22. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  23. (wejohnston@lbl.gov)
  24.  
  25. For further information about this software, contact:
  26.     Jin Guojun
  27.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  28.     g_jin@lbl.gov
  29.  
  30. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  31. %
  32. % Author:    Jin Guojun - LBL    3/1/93
  33. */
  34.  
  35. #include "net_need.h"
  36. #include "rtp.h"
  37.  
  38. #define    RTP_OPT_LEN    ((sizeof(rtcpsdeschdr_t) + sizeof(rtcp_movie_t)) >> 2)
  39. #define    RTCP_MOVIEHDR_LEN    ((sizeof(rtphdr_t) >> 2) + RTP_OPT_LEN)
  40.  
  41. #ifndef    MaxRTPChannel
  42. #define    MaxRTPChannel    64
  43. #endif
  44.  
  45. typedef    struct    {
  46.     char    *buf;    /* buffer saves data for next group    */
  47.     int    alias,    /* channel ID does not match its index    */
  48.         len;    /* data in buffer    */
  49.     char    used;    /* for each communication channel    */
  50.     char    protocol;
  51.     char    retrans;
  52.     char    align;
  53.     } flow_ctrl;
  54.  
  55. static    flow_ctrl    rtp_resource[MaxRTPChannel];
  56.  
  57.  
  58. /* called either before start receiving or in receiving    */
  59. rtp_request_channel(flow_id, buf_size, protocol, retrans)
  60. {
  61. register int    i=flow_id;
  62. register flow_ctrl    *rrp = rtp_resource;
  63.     if (!i || i>MaxRTPChannel
  64.         || rrp[i].used && rrp[i].alias != i) /* need to use others ? */
  65.             /* it will replace old channel setting    */
  66.         for (i=0; i<MaxRTPChannel; i++)
  67.         if (!rrp[i].used)    break;
  68.     if (i >= MaxRTPChannel)    return    EOF;    /* no channel available    */
  69.     verify_buffer_size(&rrp[i].buf, buf_size, 1, "rtp");    /* can be 0 */
  70.     rrp[i].alias = rrp[i].len = 0;
  71.     if (flow_id && flow_id != i)
  72.         rrp[i].alias = flow_id;
  73.     rrp[i].protocol = protocol;
  74.     rrp[i].retrans = retrans;
  75.     rrp[i].used++;
  76. return    i;    /* return flow_id    */
  77. }
  78.  
  79. void
  80. rtp_release_channel(chan /* it's the flow_id */)
  81. register int    chan;
  82. {
  83. register flow_ctrl    *rrp = rtp_resource;
  84.     if (!rrp[chan].alias)    {
  85.     free(rrp[chan].buf);
  86.     rrp[chan].used = False;
  87.     } else {
  88.     register int    i=MaxRTPChannel;
  89.     while (i--) if (rrp[i].alias == chan)    {
  90.         free(rrp[i].buf);
  91.         rrp[i].used = rrp[i].alias = 0;
  92.         break;
  93.     }
  94.     if (i < 0)    prgmerr(0, "RTP channel %d is not released", chan);
  95.     }
  96. }
  97.  
  98.  
  99. rtp_sendbygroup(s, data, datalen, group_id, sender_id, hdr, hdr_len, linewidth)
  100. int    s;
  101. VType    *data, *hdr;
  102. {
  103. int    packet_size, i=sizeof(i), n;
  104. rtphdr_t    *rtphdrp;
  105. rtcpsdeschdr_t    *rtcp_sdp;
  106. rtcp_movie_t    *rtcp_mhp;
  107. long    *vp;
  108.  
  109.     if ((n=getsockopt(s, SOL_SOCKET, SO_SNDBUF, &packet_size, &i)) < 0)
  110.         return    n;
  111.     if (!(vp = (long*)malloc(packet_size)))
  112.         return    prgmerr(0, "rtp_sg mem");
  113.     rtphdrp = (rtphdr_t *) vp;
  114.     rtcp_sdp = (rtcpsdeschdr_t*)(rtphdrp + 1);
  115.     rtcp_mhp = (rtcp_movie_t *)(rtcp_sdp + 1);
  116.  
  117.     rtphdrp->rh_vers = 1;
  118.     rtphdrp->rh_flow = sender_id;
  119.     rtphdrp->rh_opts = True;
  120.     rtphdrp->rh_content = RTPCONT_MOVIE;
  121.     rtcp_sdp->rtsh_type = RTPOPT_SDES;
  122.     rtcp_sdp->rtsh_optlen = RTCP_MOVIEHDR_LEN;
  123.     rtcp_sdp->rtsh_class = 0;
  124.     rtcp_sdp->rtsh_msglen = RTP_OPT_LEN;
  125.     rtcp_mhp->group_id = group_id;
  126.     rtcp_mhp->ttl = 33;    /* 33 ms    */
  127.     rtcp_mhp->linewidth = linewidth;
  128.     rtcp_mhp->total_len = datalen;
  129.  
  130.     time((time_t*)&rtphdrp->rh_ts);
  131.  
  132.     for (i=0; datalen > 0; i++)    {
  133.         rtcp_mhp->fragment = i;
  134.         n = packet_size * i;
  135.         if (linewidth)    {
  136.         register int    y = n / linewidth;
  137.             rtcp_mhp->offset.cord.y = y;
  138.             rtcp_mhp->offset.cord.x = n - y * linewidth;
  139.         } else    rtcp_mhp->offset.pos = n;
  140.         if (datalen < packet_size)
  141.             packet_size = datalen,
  142.             rtphdrp->rh_sync = 1;
  143.         datalen -= packet_size;
  144.         memcpy(vp + RTCP_MOVIEHDR_LEN, (byte*)data + n, packet_size);
  145.         if (write(s, vp, packet_size) < 0)
  146.             return    prgmerr(0, "rtp gwrite");
  147.     }
  148. }
  149.  
  150. rtp_recvbygroup(s, data, datalen, group_id, tolerance, ignore_err)
  151. int    s;
  152. char    *data;
  153. int    *datalen, *group_id;
  154. {
  155. int    dsp, packet_size, i=sizeof(i), n, nrcv=0;
  156. char    *buf;
  157.  
  158.     if ((n=getsockopt(s, SOL_SOCKET, SO_RCVBUF, &packet_size, &i)) < 0)
  159.     return  n;
  160.     if (!(buf=(char *)malloc(packet_size)))
  161.     return    prgmerr(0, "rtp_rg mem");
  162.     Loop    {
  163. rtphdr_t    *rtphdrp = (rtphdr_t *)buf;
  164. rtcpsdeschdr_t    *rtcp_sdp;
  165. rtcp_movie_t    *rmopt;
  166.     i = read(s, buf, packet_size);
  167.     if (i < 0)    return    i;
  168.     dsp = rtcp_getoptions(buf, 1, RTPOPT_SDES, &rtcp_sdp);
  169.     if (!rtcp_sdp)    {
  170.         message("strange RTP group packet");
  171.         continue;
  172.     }
  173.     rmopt = (rtcp_movie_t*)(rtcp_sdp + 1);
  174.     if (rmopt->group_id < *group_id)
  175.         continue;
  176.     if (rmopt->group_id > *group_id)    {
  177.         *group_id = rmopt->group_id;
  178.         if (nrcv * packet_size * 100 > rmopt->total_len ||
  179.             !ignore_err) {
  180.             free(buf);
  181.             return    nrcv * packet_size;
  182.         }
  183.         nrcv = 0;
  184.     }
  185.     if (n=rmopt->linewidth)
  186.         n = rmopt->offset.cord.y * n + rmopt->offset.cord.x;
  187.     else    n = rmopt->offset.pos;
  188.     memcpy(data + n, buf + dsp, i - dsp);
  189.     nrcv++;
  190.     }
  191. }
  192.  
  193.