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
11 * This file is part of Libav.
13 * Libav 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.
18 * Libav 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.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with Libav; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "avio_internal.h"
30 #include "rtpdec_formats.h"
31 #include "libavutil/attributes.h"
32 #include "libavutil/intreadwrite.h"
34 #include "libavcodec/bitstream.h"
36 struct PayloadContext {
44 static void h263_close_context(PayloadContext *data)
46 ffio_free_dyn_buf(&data->buf);
49 static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
50 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
51 const uint8_t *buf, int len, uint16_t seq,
54 /* Corresponding to header fields in the RFC */
55 int f, p, i, sbit, ebit, src, r;
59 return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
62 if (data->buf && data->timestamp != *timestamp) {
63 /* Dropping old buffered, unfinished data */
64 ffio_free_dyn_buf(&data->buf);
65 data->endbyte_bits = 0;
69 av_log(ctx, AV_LOG_ERROR, "Too short H.263 RTP packet: %d\n", len);
70 return AVERROR_INVALIDDATA;
79 r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
83 if (len < header_size) {
84 av_log(ctx, AV_LOG_ERROR,
85 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
87 return AVERROR_INVALIDDATA;
94 if (len < header_size) {
95 av_log(ctx, AV_LOG_ERROR,
96 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
98 return AVERROR_INVALIDDATA;
103 sbit = (buf[0] >> 3) & 0x7;
105 src = (buf[1] & 0xe0) >> 5;
106 if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
107 if ((src == 0 || src >= 6) && r) {
108 /* Invalid src for this format, and bits that should be zero
109 * according to RFC 2190 aren't zero. */
110 av_log(ctx, AV_LOG_WARNING,
111 "Interpreting H.263 RTP data as RFC 2429/4629 even though "
112 "signalled with a static payload type.\n");
114 return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
123 /* Check the picture start code, only start buffering a new frame
124 * if this is correct */
125 if (len > 4 && AV_RB32(buf) >> 10 == 0x20) {
126 ret = avio_open_dyn_buf(&data->buf);
129 data->timestamp = *timestamp;
131 /* Frame not started yet, skipping */
132 return AVERROR(EAGAIN);
136 if (data->endbyte_bits || sbit) {
137 if (data->endbyte_bits == sbit) {
138 data->endbyte |= buf[0] & (0xff >> sbit);
139 data->endbyte_bits = 0;
142 avio_w8(data->buf, data->endbyte);
144 /* Start/end skip bits not matching - missed packets? */
146 bitstream_init(&bc, buf, len * 8 - ebit);
147 bitstream_skip(&bc, sbit);
148 if (data->endbyte_bits) {
149 data->endbyte |= bitstream_read(&bc, 8 - data->endbyte_bits);
150 avio_w8(data->buf, data->endbyte);
152 while (bitstream_bits_left(&bc) >= 8)
153 avio_w8(data->buf, bitstream_read(&bc, 8));
154 data->endbyte_bits = bitstream_bits_left(&bc);
155 if (data->endbyte_bits)
156 data->endbyte = bitstream_read(&bc, data->endbyte_bits) <<
157 (8 - data->endbyte_bits);
164 avio_write(data->buf, buf, len - 1);
165 data->endbyte_bits = 8 - ebit;
166 data->endbyte = buf[len - 1] & (0xff << ebit);
168 avio_write(data->buf, buf, len);
171 if (!(flags & RTP_FLAG_MARKER))
172 return AVERROR(EAGAIN);
174 if (data->endbyte_bits)
175 avio_w8(data->buf, data->endbyte);
176 data->endbyte_bits = 0;
178 ret = ff_rtp_finalize_packet(pkt, &data->buf, st->index);
182 pkt->flags |= AV_PKT_FLAG_KEY;
187 RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler = {
188 .codec_type = AVMEDIA_TYPE_VIDEO,
189 .codec_id = AV_CODEC_ID_H263,
190 .need_parsing = AVSTREAM_PARSE_FULL,
191 .parse_packet = h263_handle_packet,
192 .priv_data_size = sizeof(PayloadContext),
193 .close = h263_close_context,
194 .static_payload_id = 34,