LCOV - code coverage report
Current view: top level - libavformat - rtpenc_xiph.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 59 0.0 %
Date: 2017-12-12 11:08:38 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*
       2             :  * RTP packetization for Xiph audio and video
       3             :  * Copyright (c) 2010 Josh Allmann
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "libavutil/avassert.h"
      23             : #include "libavutil/intreadwrite.h"
      24             : 
      25             : #include "avformat.h"
      26             : #include "rtpenc.h"
      27             : 
      28             : /**
      29             :  * Packetize Xiph frames into RTP according to
      30             :  * RFC 5215 (Vorbis) and the Theora RFC draft.
      31             :  * (http://svn.xiph.org/trunk/theora/doc/draft-ietf-avt-rtp-theora-00.txt)
      32             :  */
      33           0 : void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size)
      34             : {
      35           0 :     RTPMuxContext *s = s1->priv_data;
      36           0 :     AVStream *st = s1->streams[0];
      37             :     int max_pkt_size, xdt, frag;
      38             :     uint8_t *q;
      39             : 
      40           0 :     max_pkt_size = s->max_payload_size - 6; // ident+frag+tdt/vdt+pkt_num+pkt_length
      41             : 
      42             :     // set xiph data type
      43           0 :     switch (*buff) {
      44           0 :     case 0x01:   // vorbis id
      45             :     case 0x05:   // vorbis setup
      46             :     case 0x80:   // theora header
      47             :     case 0x82:   // theora tables
      48           0 :         xdt = 1; // packed config payload
      49           0 :         break;
      50           0 :     case 0x03:   // vorbis comments
      51             :     case 0x81:   // theora comments
      52           0 :         xdt = 2; // comment payload
      53           0 :         break;
      54           0 :     default:
      55           0 :         xdt = 0; // raw data payload
      56           0 :         break;
      57             :     }
      58             : 
      59             :     // Set ident.
      60             :     // Probably need a non-fixed way of generating
      61             :     // this, but it has to be done in SDP and passed in from there.
      62           0 :     q = s->buf;
      63           0 :     *q++ = (RTP_XIPH_IDENT >> 16) & 0xff;
      64           0 :     *q++ = (RTP_XIPH_IDENT >>  8) & 0xff;
      65           0 :     *q++ = (RTP_XIPH_IDENT      ) & 0xff;
      66             : 
      67             :     // set fragment
      68             :     // 0 - whole frame (possibly multiple frames)
      69             :     // 1 - first fragment
      70             :     // 2 - fragment continuation
      71             :     // 3 - last fragment
      72           0 :     frag = size <= max_pkt_size ? 0 : 1;
      73             : 
      74           0 :     if (!frag && !xdt) { // do we have a whole frame of raw data?
      75           0 :         uint8_t *end_ptr = s->buf + 6 + max_pkt_size; // what we're allowed to write
      76           0 :         uint8_t *ptr     = s->buf_ptr + 2 + size; // what we're going to write
      77           0 :         int remaining    = end_ptr - ptr;
      78             : 
      79             :         av_assert1(s->num_frames <= s->max_frames_per_packet);
      80           0 :         if (s->num_frames > 0 &&
      81           0 :             (remaining < 0 ||
      82           0 :              s->num_frames == s->max_frames_per_packet ||
      83           0 :              av_compare_ts(s->cur_timestamp - s->timestamp, st->time_base,
      84           0 :                            s1->max_delay, AV_TIME_BASE_Q) >= 0)) {
      85             :             // send previous packets now; no room for new data, or too much delay
      86           0 :             ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
      87           0 :             s->num_frames = 0;
      88             :         }
      89             : 
      90             :         // buffer current frame to send later
      91           0 :         if (0 == s->num_frames)
      92           0 :             s->timestamp = s->cur_timestamp;
      93           0 :         s->num_frames++;
      94             : 
      95             :         // Set packet header. Normally, this is OR'd with frag and xdt,
      96             :         // but those are zero, so omitted here
      97           0 :         *q++ = s->num_frames;
      98             : 
      99           0 :         if (s->num_frames > 1)
     100           0 :             q = s->buf_ptr; // jump ahead if needed
     101           0 :         AV_WB16(q, size);
     102           0 :         q += 2;
     103           0 :         memcpy(q, buff, size);
     104           0 :         q += size;
     105           0 :         s->buf_ptr = q;
     106             : 
     107           0 :         return;
     108           0 :     } else if (s->num_frames) {
     109             :         // immediately send buffered frames if buffer is not raw data,
     110             :         // or if current frame is fragmented.
     111           0 :         ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
     112             :     }
     113             : 
     114           0 :     s->timestamp = s->cur_timestamp;
     115           0 :     s->num_frames = 0;
     116           0 :     s->buf_ptr = q;
     117           0 :     while (size > 0) {
     118           0 :         int len = (!frag || frag == 3) ? size : max_pkt_size;
     119           0 :         q = s->buf_ptr;
     120             : 
     121             :         // set packet headers
     122           0 :         *q++ = (frag << 6) | (xdt << 4); // num_frames = 0
     123           0 :         AV_WB16(q, len);
     124           0 :         q += 2;
     125             :         // set packet body
     126           0 :         memcpy(q, buff, len);
     127           0 :         q += len;
     128           0 :         buff += len;
     129           0 :         size -= len;
     130             : 
     131           0 :         ff_rtp_send_data(s1, s->buf, q - s->buf, 0);
     132             : 
     133           0 :         frag = size <= max_pkt_size ? 3 : 2;
     134             :     }
     135             : }

Generated by: LCOV version 1.13