Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * RTP H.263 Depacketizer, RFC 2190
  3.  * Copyright (c) 2012 Martin Storsjo
  4.  * Based on the GStreamer H.263 Depayloder:
  5.  * Copyright 2005 Wim Taymans
  6.  * Copyright 2007 Edward Hervey
  7.  * Copyright 2007 Nokia Corporation
  8.  * Copyright 2007 Collabora Ltd, Philippe Kalaf
  9.  * Copyright 2010 Mark Nauwelaerts
  10.  *
  11.  * This file is part of FFmpeg.
  12.  *
  13.  * FFmpeg is free software; you can redistribute it and/or
  14.  * modify it under the terms of the GNU Lesser General Public
  15.  * License as published by the Free Software Foundation; either
  16.  * version 2.1 of the License, or (at your option) any later version.
  17.  *
  18.  * FFmpeg is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21.  * Lesser General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU Lesser General Public
  24.  * License along with FFmpeg; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  26.  */
  27.  
  28. #include "avformat.h"
  29. #include "avio_internal.h"
  30. #include "rtpdec_formats.h"
  31. #include "libavutil/attributes.h"
  32. #include "libavutil/intreadwrite.h"
  33. #include "libavcodec/get_bits.h"
  34.  
  35. struct PayloadContext {
  36.     AVIOContext *buf;
  37.     uint8_t      endbyte;
  38.     int          endbyte_bits;
  39.     uint32_t     timestamp;
  40.     int          newformat;
  41. };
  42.  
  43. static void h263_close_context(PayloadContext *data)
  44. {
  45.     ffio_free_dyn_buf(&data->buf);
  46. }
  47.  
  48. static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
  49.                               AVStream *st, AVPacket *pkt, uint32_t *timestamp,
  50.                               const uint8_t *buf, int len, uint16_t seq,
  51.                               int flags)
  52. {
  53.     /* Corresponding to header fields in the RFC */
  54.     int f, p, i, sbit, ebit, src, r;
  55.     int header_size, ret;
  56.  
  57.     if (data->newformat)
  58.         return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
  59.                                      seq, flags);
  60.  
  61.     if (data->buf && data->timestamp != *timestamp) {
  62.         /* Dropping old buffered, unfinished data */
  63.         ffio_free_dyn_buf(&data->buf);
  64.         data->endbyte_bits = 0;
  65.     }
  66.  
  67.     if (len < 4) {
  68.         av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len);
  69.         return AVERROR_INVALIDDATA;
  70.     }
  71.  
  72.     f = buf[0] & 0x80;
  73.     p = buf[0] & 0x40;
  74.     if (!f) {
  75.         /* Mode A */
  76.         header_size = 4;
  77.         i = buf[1] & 0x10;
  78.         r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
  79.     } else if (!p) {
  80.         /* Mode B */
  81.         header_size = 8;
  82.         if (len < header_size) {
  83.             av_log(ctx, AV_LOG_ERROR,
  84.                    "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
  85.                    len, header_size);
  86.             return AVERROR_INVALIDDATA;
  87.         }
  88.         r = buf[3] & 0x03;
  89.         i = buf[4] & 0x80;
  90.     } else {
  91.         /* Mode C */
  92.         header_size = 12;
  93.         if (len < header_size) {
  94.             av_log(ctx, AV_LOG_ERROR,
  95.                    "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
  96.                    len, header_size);
  97.             return AVERROR_INVALIDDATA;
  98.         }
  99.         r = buf[3] & 0x03;
  100.         i = buf[4] & 0x80;
  101.     }
  102.     sbit = (buf[0] >> 3) & 0x7;
  103.     ebit =  buf[0]       & 0x7;
  104.     src  = (buf[1] & 0xe0) >> 5;
  105.     if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
  106.         if ((src == 0 || src >= 6) && r) {
  107.             /* Invalid src for this format, and bits that should be zero
  108.              * according to RFC 2190 aren't zero. */
  109.             av_log(ctx, AV_LOG_WARNING,
  110.                    "Interpreting H263 RTP data as RFC 2429/4629 even though "
  111.                    "signalled with a static payload type.\n");
  112.             data->newformat = 1;
  113.             return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
  114.                                          len, seq, flags);
  115.         }
  116.     }
  117.  
  118.     buf += header_size;
  119.     len -= header_size;
  120.  
  121.     if (!data->buf) {
  122.         /* Check the picture start code, only start buffering a new frame
  123.          * if this is correct */
  124.         if (len > 4 && AV_RB32(buf) >> 10 == 0x20) {
  125.             ret = avio_open_dyn_buf(&data->buf);
  126.             if (ret < 0)
  127.                 return ret;
  128.             data->timestamp = *timestamp;
  129.         } else {
  130.             /* Frame not started yet, skipping */
  131.             return AVERROR(EAGAIN);
  132.         }
  133.     }
  134.  
  135.     if (data->endbyte_bits || sbit) {
  136.         if (data->endbyte_bits == sbit) {
  137.             data->endbyte |= buf[0] & (0xff >> sbit);
  138.             data->endbyte_bits = 0;
  139.             buf++;
  140.             len--;
  141.             avio_w8(data->buf, data->endbyte);
  142.         } else {
  143.             /* Start/end skip bits not matching - missed packets? */
  144.             GetBitContext gb;
  145.             init_get_bits(&gb, buf, len*8 - ebit);
  146.             skip_bits(&gb, sbit);
  147.             if (data->endbyte_bits) {
  148.                 data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits);
  149.                 avio_w8(data->buf, data->endbyte);
  150.             }
  151.             while (get_bits_left(&gb) >= 8)
  152.                 avio_w8(data->buf, get_bits(&gb, 8));
  153.             data->endbyte_bits = get_bits_left(&gb);
  154.             if (data->endbyte_bits)
  155.                 data->endbyte = get_bits(&gb, data->endbyte_bits) <<
  156.                                 (8 - data->endbyte_bits);
  157.             ebit = 0;
  158.             len = 0;
  159.         }
  160.     }
  161.     if (ebit) {
  162.         if (len > 0)
  163.             avio_write(data->buf, buf, len - 1);
  164.         data->endbyte_bits = 8 - ebit;
  165.         data->endbyte = buf[len - 1] & (0xff << ebit);
  166.     } else {
  167.         avio_write(data->buf, buf, len);
  168.     }
  169.  
  170.     if (!(flags & RTP_FLAG_MARKER))
  171.         return AVERROR(EAGAIN);
  172.  
  173.     if (data->endbyte_bits)
  174.         avio_w8(data->buf, data->endbyte);
  175.     data->endbyte_bits = 0;
  176.  
  177.     ret = ff_rtp_finalize_packet(pkt, &data->buf, st->index);
  178.     if (ret < 0)
  179.         return ret;
  180.     if (!i)
  181.         pkt->flags   |= AV_PKT_FLAG_KEY;
  182.  
  183.     return 0;
  184. }
  185.  
  186. RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
  187.     .codec_type        = AVMEDIA_TYPE_VIDEO,
  188.     .codec_id          = AV_CODEC_ID_H263,
  189.     .need_parsing      = AVSTREAM_PARSE_FULL,
  190.     .parse_packet      = h263_handle_packet,
  191.     .priv_data_size    = sizeof(PayloadContext),
  192.     .close             = h263_close_context,
  193.     .static_payload_id = 34,
  194. };
  195.