Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Xiph RTP Protocols
  3.  * Copyright (c) 2009 Colin McQuillian
  4.  * Copyright (c) 2010 Josh Allmann
  5.  *
  6.  * This file is part of FFmpeg.
  7.  *
  8.  * FFmpeg is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2.1 of the License, or (at your option) any later version.
  12.  *
  13.  * FFmpeg is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Lesser General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with FFmpeg; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21.  */
  22.  
  23. /**
  24.  * @file
  25.  * @brief Xiph / RTP Code
  26.  * @author Colin McQuillan <m.niloc@gmail.com>
  27.  * @author Josh Allmann <joshua.allmann@gmail.com>
  28.  */
  29.  
  30. #include "libavutil/attributes.h"
  31. #include "libavutil/avassert.h"
  32. #include "libavutil/avstring.h"
  33. #include "libavutil/base64.h"
  34. #include "libavcodec/bytestream.h"
  35.  
  36. #include "internal.h"
  37. #include "rtpdec.h"
  38. #include "rtpdec_formats.h"
  39.  
  40. /**
  41.  * RTP/Xiph specific private data.
  42.  */
  43. struct PayloadContext {
  44.     unsigned ident;             ///< 24-bit stream configuration identifier
  45.     uint32_t timestamp;
  46.     AVIOContext* fragment;    ///< buffer for split payloads
  47.     uint8_t *split_buf;
  48.     int split_pos, split_buf_len, split_buf_size;
  49.     int split_pkts;
  50. };
  51.  
  52. static PayloadContext *xiph_new_context(void)
  53. {
  54.     return av_mallocz(sizeof(PayloadContext));
  55. }
  56.  
  57. static inline void free_fragment_if_needed(PayloadContext * data)
  58. {
  59.     if (data->fragment) {
  60.         uint8_t* p;
  61.         avio_close_dyn_buf(data->fragment, &p);
  62.         av_free(p);
  63.         data->fragment = NULL;
  64.     }
  65. }
  66.  
  67. static void xiph_free_context(PayloadContext * data)
  68. {
  69.     free_fragment_if_needed(data);
  70.     av_free(data->split_buf);
  71.     av_free(data);
  72. }
  73.  
  74. static av_cold int xiph_vorbis_init(AVFormatContext *ctx, int st_index,
  75.                                     PayloadContext *data)
  76. {
  77.     if (st_index < 0)
  78.         return 0;
  79.     ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_HEADERS;
  80.     return 0;
  81. }
  82.  
  83.  
  84. static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data,
  85.                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
  86.                               const uint8_t *buf, int len, uint16_t seq,
  87.                               int flags)
  88. {
  89.  
  90.     int ident, fragmented, tdt, num_pkts, pkt_len;
  91.  
  92.     if (!buf) {
  93.         if (!data->split_buf || data->split_pos + 2 > data->split_buf_len ||
  94.             data->split_pkts <= 0) {
  95.             av_log(ctx, AV_LOG_ERROR, "No more data to return\n");
  96.             return AVERROR_INVALIDDATA;
  97.         }
  98.         pkt_len = AV_RB16(data->split_buf + data->split_pos);
  99.         data->split_pos += 2;
  100.         if (data->split_pos + pkt_len > data->split_buf_len) {
  101.             av_log(ctx, AV_LOG_ERROR, "Not enough data to return\n");
  102.             return AVERROR_INVALIDDATA;
  103.         }
  104.         if (av_new_packet(pkt, pkt_len)) {
  105.             av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
  106.             return AVERROR(ENOMEM);
  107.         }
  108.         pkt->stream_index = st->index;
  109.         memcpy(pkt->data, data->split_buf + data->split_pos, pkt_len);
  110.         data->split_pos += pkt_len;
  111.         data->split_pkts--;
  112.         return data->split_pkts > 0;
  113.     }
  114.  
  115.     if (len < 6) {
  116.         av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
  117.         return AVERROR_INVALIDDATA;
  118.     }
  119.  
  120.     // read xiph rtp headers
  121.     ident       = AV_RB24(buf);
  122.     fragmented  = buf[3] >> 6;
  123.     tdt         = (buf[3] >> 4) & 3;
  124.     num_pkts    = buf[3] & 0xf;
  125.     pkt_len     = AV_RB16(buf + 4);
  126.  
  127.     if (pkt_len > len - 6) {
  128.         av_log(ctx, AV_LOG_ERROR,
  129.                "Invalid packet length %d in %d byte packet\n", pkt_len,
  130.                len);
  131.         return AVERROR_INVALIDDATA;
  132.     }
  133.  
  134.     if (ident != data->ident) {
  135.         av_log(ctx, AV_LOG_ERROR,
  136.                "Unimplemented Xiph SDP configuration change detected\n");
  137.         return AVERROR_PATCHWELCOME;
  138.     }
  139.  
  140.     if (tdt) {
  141.         av_log(ctx, AV_LOG_ERROR,
  142.                "Unimplemented RTP Xiph packet settings (%d,%d,%d)\n",
  143.                fragmented, tdt, num_pkts);
  144.         return AVERROR_PATCHWELCOME;
  145.     }
  146.  
  147.     buf += 6; // move past header bits
  148.     len -= 6;
  149.  
  150.     if (fragmented == 0) {
  151.         if (av_new_packet(pkt, pkt_len)) {
  152.             av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
  153.             return AVERROR(ENOMEM);
  154.         }
  155.         pkt->stream_index = st->index;
  156.         memcpy(pkt->data, buf, pkt_len);
  157.         buf += pkt_len;
  158.         len -= pkt_len;
  159.         num_pkts--;
  160.  
  161.         if (num_pkts > 0) {
  162.             if (len > data->split_buf_size || !data->split_buf) {
  163.                 av_freep(&data->split_buf);
  164.                 data->split_buf_size = 2 * len;
  165.                 data->split_buf = av_malloc(data->split_buf_size);
  166.                 if (!data->split_buf) {
  167.                     av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
  168.                     av_free_packet(pkt);
  169.                     return AVERROR(ENOMEM);
  170.                 }
  171.             }
  172.             memcpy(data->split_buf, buf, len);
  173.             data->split_buf_len = len;
  174.             data->split_pos = 0;
  175.             data->split_pkts = num_pkts;
  176.             return 1;
  177.         }
  178.  
  179.         return 0;
  180.  
  181.     } else if (fragmented == 1) {
  182.         // start of xiph data fragment
  183.         int res;
  184.  
  185.         // end packet has been lost somewhere, so drop buffered data
  186.         free_fragment_if_needed(data);
  187.  
  188.         if((res = avio_open_dyn_buf(&data->fragment)) < 0)
  189.             return res;
  190.  
  191.         avio_write(data->fragment, buf, pkt_len);
  192.         data->timestamp = *timestamp;
  193.  
  194.     } else {
  195.         av_assert1(fragmented < 4);
  196.         if (data->timestamp != *timestamp) {
  197.             // skip if fragmented timestamp is incorrect;
  198.             // a start packet has been lost somewhere
  199.             free_fragment_if_needed(data);
  200.             av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match!\n");
  201.             return AVERROR_INVALIDDATA;
  202.         }
  203.         if (!data->fragment) {
  204.             av_log(ctx, AV_LOG_WARNING,
  205.                    "Received packet without a start fragment; dropping.\n");
  206.             return AVERROR(EAGAIN);
  207.         }
  208.  
  209.         // copy data to fragment buffer
  210.         avio_write(data->fragment, buf, pkt_len);
  211.  
  212.         if (fragmented == 3) {
  213.             // end of xiph data packet
  214.             int ret = ff_rtp_finalize_packet(pkt, &data->fragment, st->index);
  215.             if (ret < 0) {
  216.                 av_log(ctx, AV_LOG_ERROR,
  217.                        "Error occurred when getting fragment buffer.");
  218.                 return ret;
  219.             }
  220.  
  221.             return 0;
  222.         }
  223.     }
  224.  
  225.    return AVERROR(EAGAIN);
  226. }
  227.  
  228. /**
  229.  * Length encoding described in RFC5215 section 3.1.1.
  230.  */
  231. static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
  232. {
  233.     int n = 0;
  234.     for (; *buf < buf_end; ++*buf) {
  235.         n <<= 7;
  236.         n += **buf & 0x7f;
  237.         if (!(**buf & 0x80)) {
  238.             ++*buf;
  239.             return n;
  240.         }
  241.     }
  242.     return 0;
  243. }
  244.  
  245. /**
  246.  * Based off parse_packed_headers in Vorbis RTP
  247.  */
  248. static int
  249. parse_packed_headers(const uint8_t * packed_headers,
  250.                      const uint8_t * packed_headers_end,
  251.                      AVCodecContext * codec, PayloadContext * xiph_data)
  252. {
  253.  
  254.     unsigned num_packed, num_headers, length, length1, length2, extradata_alloc;
  255.     uint8_t *ptr;
  256.  
  257.     if (packed_headers_end - packed_headers < 9) {
  258.         av_log(codec, AV_LOG_ERROR,
  259.                "Invalid %td byte packed header.",
  260.                packed_headers_end - packed_headers);
  261.         return AVERROR_INVALIDDATA;
  262.     }
  263.  
  264.     num_packed         = bytestream_get_be32(&packed_headers);
  265.     xiph_data->ident   = bytestream_get_be24(&packed_headers);
  266.     length             = bytestream_get_be16(&packed_headers);
  267.     num_headers        = get_base128(&packed_headers, packed_headers_end);
  268.     length1            = get_base128(&packed_headers, packed_headers_end);
  269.     length2            = get_base128(&packed_headers, packed_headers_end);
  270.  
  271.     if (num_packed != 1 || num_headers > 3) {
  272.         av_log(codec, AV_LOG_ERROR,
  273.                "Unimplemented number of headers: %d packed headers, %d headers\n",
  274.                num_packed, num_headers);
  275.         return AVERROR_PATCHWELCOME;
  276.     }
  277.  
  278.     if (packed_headers_end - packed_headers != length ||
  279.         length1 > length || length2 > length - length1) {
  280.         av_log(codec, AV_LOG_ERROR,
  281.                "Bad packed header lengths (%d,%d,%td,%d)\n", length1,
  282.                length2, packed_headers_end - packed_headers, length);
  283.         return AVERROR_INVALIDDATA;
  284.     }
  285.  
  286.     /* allocate extra space:
  287.      * -- length/255 +2 for xiphlacing
  288.      * -- one for the '2' marker
  289.      * -- FF_INPUT_BUFFER_PADDING_SIZE required */
  290.     extradata_alloc = length + length/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE;
  291.  
  292.     if (ff_alloc_extradata(codec, extradata_alloc)) {
  293.         av_log(codec, AV_LOG_ERROR, "Out of memory\n");
  294.         return AVERROR(ENOMEM);
  295.     }
  296.     ptr = codec->extradata;
  297.     *ptr++ = 2;
  298.     ptr += av_xiphlacing(ptr, length1);
  299.     ptr += av_xiphlacing(ptr, length2);
  300.     memcpy(ptr, packed_headers, length);
  301.     ptr += length;
  302.     codec->extradata_size = ptr - codec->extradata;
  303.     // clear out remaining parts of the buffer
  304.     memset(ptr, 0, extradata_alloc - codec->extradata_size);
  305.  
  306.     return 0;
  307. }
  308.  
  309. static int xiph_parse_fmtp_pair(AVStream* stream,
  310.                                 PayloadContext *xiph_data,
  311.                                 char *attr, char *value)
  312. {
  313.     AVCodecContext *codec = stream->codec;
  314.     int result = 0;
  315.  
  316.     if (!strcmp(attr, "sampling")) {
  317.         if (!strcmp(value, "YCbCr-4:2:0")) {
  318.             codec->pix_fmt = AV_PIX_FMT_YUV420P;
  319.         } else if (!strcmp(value, "YCbCr-4:4:2")) {
  320.             codec->pix_fmt = AV_PIX_FMT_YUV422P;
  321.         } else if (!strcmp(value, "YCbCr-4:4:4")) {
  322.             codec->pix_fmt = AV_PIX_FMT_YUV444P;
  323.         } else {
  324.             av_log(codec, AV_LOG_ERROR,
  325.                    "Unsupported pixel format %s\n", attr);
  326.             return AVERROR_INVALIDDATA;
  327.         }
  328.     } else if (!strcmp(attr, "width")) {
  329.         /* This is an integer between 1 and 1048561
  330.          * and MUST be in multiples of 16. */
  331.         codec->width = atoi(value);
  332.         return 0;
  333.     } else if (!strcmp(attr, "height")) {
  334.         /* This is an integer between 1 and 1048561
  335.          * and MUST be in multiples of 16. */
  336.         codec->height = atoi(value);
  337.         return 0;
  338.     } else if (!strcmp(attr, "delivery-method")) {
  339.         /* Possible values are: inline, in_band, out_band/specific_name. */
  340.         return AVERROR_PATCHWELCOME;
  341.     } else if (!strcmp(attr, "configuration-uri")) {
  342.         /* NOTE: configuration-uri is supported only under 2 conditions:
  343.          *--after the delivery-method tag
  344.          * --with a delivery-method value of out_band */
  345.         return AVERROR_PATCHWELCOME;
  346.     } else if (!strcmp(attr, "configuration")) {
  347.         /* NOTE: configuration is supported only AFTER the delivery-method tag
  348.          * The configuration value is a base64 encoded packed header */
  349.         uint8_t *decoded_packet = NULL;
  350.         int packet_size;
  351.         size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
  352.  
  353.         if (decoded_alloc <= INT_MAX) {
  354.             decoded_packet = av_malloc(decoded_alloc);
  355.             if (decoded_packet) {
  356.                 packet_size =
  357.                     av_base64_decode(decoded_packet, value, decoded_alloc);
  358.  
  359.                 result = parse_packed_headers
  360.                     (decoded_packet, decoded_packet + packet_size, codec,
  361.                     xiph_data);
  362.             } else {
  363.                 av_log(codec, AV_LOG_ERROR,
  364.                        "Out of memory while decoding SDP configuration.\n");
  365.                 result = AVERROR(ENOMEM);
  366.             }
  367.         } else {
  368.             av_log(codec, AV_LOG_ERROR, "Packet too large\n");
  369.             result = AVERROR_INVALIDDATA;
  370.         }
  371.         av_free(decoded_packet);
  372.     }
  373.     return result;
  374. }
  375.  
  376. static int xiph_parse_sdp_line(AVFormatContext *s, int st_index,
  377.                                PayloadContext *data, const char *line)
  378. {
  379.     const char *p;
  380.  
  381.     if (st_index < 0)
  382.         return 0;
  383.  
  384.     if (av_strstart(line, "fmtp:", &p)) {
  385.         return ff_parse_fmtp(s->streams[st_index], data, p,
  386.                              xiph_parse_fmtp_pair);
  387.     }
  388.  
  389.     return 0;
  390. }
  391.  
  392. RTPDynamicProtocolHandler ff_theora_dynamic_handler = {
  393.     .enc_name         = "theora",
  394.     .codec_type       = AVMEDIA_TYPE_VIDEO,
  395.     .codec_id         = AV_CODEC_ID_THEORA,
  396.     .parse_sdp_a_line = xiph_parse_sdp_line,
  397.     .alloc            = xiph_new_context,
  398.     .free             = xiph_free_context,
  399.     .parse_packet     = xiph_handle_packet
  400. };
  401.  
  402. RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
  403.     .enc_name         = "vorbis",
  404.     .codec_type       = AVMEDIA_TYPE_AUDIO,
  405.     .codec_id         = AV_CODEC_ID_VORBIS,
  406.     .init             = xiph_vorbis_init,
  407.     .parse_sdp_a_line = xiph_parse_sdp_line,
  408.     .alloc            = xiph_new_context,
  409.     .free             = xiph_free_context,
  410.     .parse_packet     = xiph_handle_packet
  411. };
  412.