Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 "avformat.h"
  24. #include "rtpenc.h"
  25.  
  26. /**
  27.  * Packetize Xiph frames into RTP according to
  28.  * RFC 5215 (Vorbis) and the Theora RFC draft.
  29.  * (http://svn.xiph.org/trunk/theora/doc/draft-ietf-avt-rtp-theora-00.txt)
  30.  */
  31. void ff_rtp_send_xiph(AVFormatContext *s1, const uint8_t *buff, int size)
  32. {
  33.     RTPMuxContext *s = s1->priv_data;
  34.     int max_pkt_size, xdt, frag;
  35.     uint8_t *q;
  36.  
  37.     max_pkt_size = s->max_payload_size;
  38.  
  39.     // set xiph data type
  40.     switch (*buff) {
  41.     case 0x01:   // vorbis id
  42.     case 0x05:   // vorbis setup
  43.     case 0x80:   // theora header
  44.     case 0x82:   // theora tables
  45.         xdt = 1; // packed config payload
  46.         break;
  47.     case 0x03:   // vorbis comments
  48.     case 0x81:   // theora comments
  49.         xdt = 2; // comment payload
  50.         break;
  51.     default:
  52.         xdt = 0; // raw data payload
  53.         break;
  54.     }
  55.  
  56.     // Set ident.
  57.     // Probably need a non-fixed way of generating
  58.     // this, but it has to be done in SDP and passed in from there.
  59.     q = s->buf;
  60.     *q++ = (RTP_XIPH_IDENT >> 16) & 0xff;
  61.     *q++ = (RTP_XIPH_IDENT >>  8) & 0xff;
  62.     *q++ = (RTP_XIPH_IDENT      ) & 0xff;
  63.  
  64.     // set fragment
  65.     // 0 - whole frame (possibly multiple frames)
  66.     // 1 - first fragment
  67.     // 2 - fragment continuation
  68.     // 3 - last fragmement
  69.     frag = size <= max_pkt_size ? 0 : 1;
  70.  
  71.     if (!frag && !xdt) { // do we have a whole frame of raw data?
  72.         uint8_t *end_ptr = s->buf + 6 + max_pkt_size; // what we're allowed to write
  73.         uint8_t *ptr     = s->buf_ptr + 2 + size; // what we're going to write
  74.         int remaining    = end_ptr - ptr;
  75.  
  76.         av_assert1(s->num_frames <= s->max_frames_per_packet);
  77.         if ((s->num_frames > 0 && remaining < 0) ||
  78.             s->num_frames == s->max_frames_per_packet) {
  79.             // send previous packets now; no room for new data
  80.             ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
  81.             s->num_frames = 0;
  82.         }
  83.  
  84.         // buffer current frame to send later
  85.         if (0 == s->num_frames) s->timestamp = s->cur_timestamp;
  86.         s->num_frames++;
  87.  
  88.         // Set packet header. Normally, this is OR'd with frag and xdt,
  89.         // but those are zero, so omitted here
  90.         *q++ = s->num_frames;
  91.  
  92.         if (s->num_frames > 1) q = s->buf_ptr; // jump ahead if needed
  93.         *q++ = (size >> 8) & 0xff;
  94.         *q++ = size & 0xff;
  95.         memcpy(q, buff, size);
  96.         q += size;
  97.         s->buf_ptr = q;
  98.  
  99.         return;
  100.     } else if (s->num_frames) {
  101.         // immediately send buffered frames if buffer is not raw data,
  102.         // or if current frame is fragmented.
  103.         ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 0);
  104.     }
  105.  
  106.     s->timestamp = s->cur_timestamp;
  107.     s->num_frames = 0;
  108.     s->buf_ptr = q;
  109.     while (size > 0) {
  110.         int len = (!frag || frag == 3) ? size : max_pkt_size;
  111.         q = s->buf_ptr;
  112.  
  113.         // set packet headers
  114.         *q++ = (frag << 6) | (xdt << 4); // num_frames = 0
  115.         *q++ = (len >> 8) & 0xff;
  116.         *q++ = len & 0xff;
  117.         // set packet body
  118.         memcpy(q, buff, len);
  119.         q += len;
  120.         buff += len;
  121.         size -= len;
  122.  
  123.         ff_rtp_send_data(s1, s->buf, q - s->buf, 0);
  124.  
  125.         frag = size <= max_pkt_size ? 3 : 2;
  126.     }
  127. }
  128.