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 FFmpeg.
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.
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.
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
29 #include "rtpdec_formats.h"
30 #include "libavutil/attributes.h"
31 #include "libavutil/intreadwrite.h"
32 #include "libavcodec/get_bits.h"
34 struct PayloadContext
{
42 static PayloadContext
*h263_new_context(void)
44 return av_mallocz(sizeof(PayloadContext
));
47 static void h263_free_context(PayloadContext
*data
)
53 avio_close_dyn_buf(data
->buf
, &p
);
59 static av_cold
int h263_init(AVFormatContext
*ctx
, int st_index
, PayloadContext
*data
)
63 ctx
->streams
[st_index
]->need_parsing
= AVSTREAM_PARSE_FULL
;
67 static int h263_handle_packet(AVFormatContext
*ctx
, PayloadContext
*data
,
68 AVStream
*st
, AVPacket
*pkt
, uint32_t *timestamp
,
69 const uint8_t *buf
, int len
, uint16_t seq
,
72 /* Corresponding to header fields in the RFC */
73 int f
, p
, i
, sbit
, ebit
, src
, r
;
77 return ff_h263_handle_packet(ctx
, data
, st
, pkt
, timestamp
, buf
, len
,
80 if (data
->buf
&& data
->timestamp
!= *timestamp
) {
81 /* Dropping old buffered, unfinished data */
83 avio_close_dyn_buf(data
->buf
, &p
);
89 av_log(ctx
, AV_LOG_ERROR
, "Too short H.263 RTP packet: %d\n", len
);
90 return AVERROR_INVALIDDATA
;
99 r
= ((buf
[1] & 0x01) << 3) | ((buf
[2] & 0xe0) >> 5);
103 if (len
< header_size
) {
104 av_log(ctx
, AV_LOG_ERROR
,
105 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
107 return AVERROR_INVALIDDATA
;
114 if (len
< header_size
) {
115 av_log(ctx
, AV_LOG_ERROR
,
116 "Too short H.263 RTP packet: %d bytes, %d header bytes\n",
118 return AVERROR_INVALIDDATA
;
123 sbit
= (buf
[0] >> 3) & 0x7;
125 src
= (buf
[1] & 0xe0) >> 5;
126 if (!(buf
[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
127 if ((src
== 0 || src
>= 6) && r
) {
128 /* Invalid src for this format, and bits that should be zero
129 * according to RFC 2190 aren't zero. */
130 av_log(ctx
, AV_LOG_WARNING
,
131 "Interpreting H263 RTP data as RFC 2429/4629 even though "
132 "signalled with a static payload type.\n");
134 return ff_h263_handle_packet(ctx
, data
, st
, pkt
, timestamp
, buf
,
143 /* Check the picture start code, only start buffering a new frame
144 * if this is correct */
145 if (len
> 4 && AV_RB32(buf
) >> 10 == 0x20) {
146 ret
= avio_open_dyn_buf(&data
->buf
);
149 data
->timestamp
= *timestamp
;
151 /* Frame not started yet, skipping */
152 return AVERROR(EAGAIN
);
156 if (data
->endbyte_bits
|| sbit
) {
157 if (data
->endbyte_bits
== sbit
) {
158 data
->endbyte
|= buf
[0] & (0xff >> sbit
);
159 data
->endbyte_bits
= 0;
162 avio_w8(data
->buf
, data
->endbyte
);
164 /* Start/end skip bits not matching - missed packets? */
166 init_get_bits(&gb
, buf
, len
*8 - ebit
);
167 skip_bits(&gb
, sbit
);
168 if (data
->endbyte_bits
) {
169 data
->endbyte
|= get_bits(&gb
, 8 - data
->endbyte_bits
);
170 avio_w8(data
->buf
, data
->endbyte
);
172 while (get_bits_left(&gb
) >= 8)
173 avio_w8(data
->buf
, get_bits(&gb
, 8));
174 data
->endbyte_bits
= get_bits_left(&gb
);
175 if (data
->endbyte_bits
)
176 data
->endbyte
= get_bits(&gb
, data
->endbyte_bits
) <<
177 (8 - data
->endbyte_bits
);
184 avio_write(data
->buf
, buf
, len
- 1);
185 data
->endbyte_bits
= 8 - ebit
;
186 data
->endbyte
= buf
[len
- 1] & (0xff << ebit
);
188 avio_write(data
->buf
, buf
, len
);
191 if (!(flags
& RTP_FLAG_MARKER
))
192 return AVERROR(EAGAIN
);
194 if (data
->endbyte_bits
)
195 avio_w8(data
->buf
, data
->endbyte
);
196 data
->endbyte_bits
= 0;
198 ret
= ff_rtp_finalize_packet(pkt
, &data
->buf
, st
->index
);
202 pkt
->flags
|= AV_PKT_FLAG_KEY
;
207 RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler
= {
208 .codec_type
= AVMEDIA_TYPE_VIDEO
,
209 .codec_id
= AV_CODEC_ID_H263
,
211 .parse_packet
= h263_handle_packet
,
212 .alloc
= h263_new_context
,
213 .free
= h263_free_context
,
214 .static_payload_id
= 34,