/*
 * RTP H.263 Depacketizer, RFC 2190
 * Copyright (c) 2012 Martin Storsjo
 * Based on the GStreamer H.263 Depayloder:
 * Copyright 2005 Wim Taymans
 * Copyright 2007 Edward Hervey
 * Copyright 2007 Nokia Corporation
 * Copyright 2007 Collabora Ltd, Philippe Kalaf
 * Copyright 2010 Mark Nauwelaerts
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "avformat.h"
#include "avio_internal.h"
#include "rtpdec_formats.h"
#include "libavutil/attributes.h"
#include "libavutil/intreadwrite.h"
#include "libavcodec/get_bits.h"

struct PayloadContext {
    AVIOContext *buf;
    uint8_t      endbyte;
    int          endbyte_bits;
    uint32_t     timestamp;
    int          newformat;
};

static void h263_close_context(PayloadContext *data)
{
    ffio_free_dyn_buf(&data->buf);
}

static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
                              const uint8_t *buf, int len, uint16_t seq,
                              int flags)
{
    /* Corresponding to header fields in the RFC */
    int f, p, i, sbit, ebit, src, r;
    int header_size, ret;

    if (data->newformat)
        return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
                                     seq, flags);

    if (data->buf && data->timestamp != *timestamp) {
        /* Dropping old buffered, unfinished data */
        ffio_free_dyn_buf(&data->buf);
        data->endbyte_bits = 0;
    }

    if (len < 4) {
        av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len);
        return AVERROR_INVALIDDATA;
    }

    f = buf[0] & 0x80;
    p = buf[0] & 0x40;
    if (!f) {
        /* Mode A */
        header_size = 4;
        i = buf[1] & 0x10;
        r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
    } else if (!p) {
        /* Mode B */
        header_size = 8;
        if (len < header_size) {
            av_log(ctx, AV_LOG_ERROR,
                   "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
                   len, header_size);
            return AVERROR_INVALIDDATA;
        }
        r = buf[3] & 0x03;
        i = buf[4] & 0x80;
    } else {
        /* Mode C */
        header_size = 12;
        if (len < header_size) {
            av_log(ctx, AV_LOG_ERROR,
                   "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
                   len, header_size);
            return AVERROR_INVALIDDATA;
        }
        r = buf[3] & 0x03;
        i = buf[4] & 0x80;
    }
    sbit = (buf[0] >> 3) & 0x7;
    ebit =  buf[0]       & 0x7;
    src  = (buf[1] & 0xe0) >> 5;
    if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
        if ((src == 0 || src >= 6) && r) {
            /* Invalid src for this format, and bits that should be zero
             * according to RFC 2190 aren't zero. */
            av_log(ctx, AV_LOG_WARNING,
                   "Interpreting H263 RTP data as RFC 2429/4629 even though "
                   "signalled with a static payload type.\n");
            data->newformat = 1;
            return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
                                         len, seq, flags);
        }
    }

    buf += header_size;
    len -= header_size;

    if (!data->buf) {
        /* Check the picture start code, only start buffering a new frame
         * if this is correct */
        if (len > 4 && AV_RB32(buf) >> 10 == 0x20) {
            ret = avio_open_dyn_buf(&data->buf);
            if (ret < 0)
                return ret;
            data->timestamp = *timestamp;
        } else {
            /* Frame not started yet, skipping */
            return AVERROR(EAGAIN);
        }
    }

    if (data->endbyte_bits || sbit) {
        if (data->endbyte_bits == sbit) {
            data->endbyte |= buf[0] & (0xff >> sbit);
            data->endbyte_bits = 0;
            buf++;
            len--;
            avio_w8(data->buf, data->endbyte);
        } else {
            /* Start/end skip bits not matching - missed packets? */
            GetBitContext gb;
            init_get_bits(&gb, buf, len*8 - ebit);
            skip_bits(&gb, sbit);
            if (data->endbyte_bits) {
                data->endbyte |= get_bits(&gb, 8 - data->endbyte_bits);
                avio_w8(data->buf, data->endbyte);
            }
            while (get_bits_left(&gb) >= 8)
                avio_w8(data->buf, get_bits(&gb, 8));
            data->endbyte_bits = get_bits_left(&gb);
            if (data->endbyte_bits)
                data->endbyte = get_bits(&gb, data->endbyte_bits) <<
                                (8 - data->endbyte_bits);
            ebit = 0;
            len = 0;
        }
    }
    if (ebit) {
        if (len > 0)
            avio_write(data->buf, buf, len - 1);
        data->endbyte_bits = 8 - ebit;
        data->endbyte = buf[len - 1] & (0xff << ebit);
    } else {
        avio_write(data->buf, buf, len);
    }

    if (!(flags & RTP_FLAG_MARKER))
        return AVERROR(EAGAIN);

    if (data->endbyte_bits)
        avio_w8(data->buf, data->endbyte);
    data->endbyte_bits = 0;

    ret = ff_rtp_finalize_packet(pkt, &data->buf, st->index);
    if (ret < 0)
        return ret;
    if (!i)
        pkt->flags   |= AV_PKT_FLAG_KEY;

    return 0;
}

RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
    .codec_type        = AVMEDIA_TYPE_VIDEO,
    .codec_id          = AV_CODEC_ID_H263,
    .need_parsing      = AVSTREAM_PARSE_FULL,
    .parse_packet      = h263_handle_packet,
    .priv_data_size    = sizeof(PayloadContext),
    .close             = h263_close_context,
    .static_payload_id = 34,
};
