2 * RTP parser for H.261 payload format (RFC 4587)
3 * Copyright (c) 2014 Thomas Volkert <thomas@homer-conferencing.com>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "rtpdec_formats.h"
24 #include "libavcodec/get_bits.h"
26 #define RTP_H261_PAYLOAD_HEADER_SIZE 4
28 struct PayloadContext
{
35 static av_cold PayloadContext
*h261_new_context(void)
37 return av_mallocz(sizeof(PayloadContext
));
40 static void h261_free_dyn_buffer(AVIOContext
**dyn_buf
)
42 uint8_t *ptr_dyn_buffer
;
43 avio_close_dyn_buf(*dyn_buf
, &ptr_dyn_buffer
);
44 av_free(ptr_dyn_buffer
);
48 static av_cold
void h261_free_context(PayloadContext
*pl_ctx
)
50 /* return if context is invalid */
54 /* free buffer if it is valid */
56 h261_free_dyn_buffer(&pl_ctx
->buf
);
63 static av_cold
int h261_init(AVFormatContext
*ctx
, int st_index
,
66 //av_log(ctx, AV_LOG_DEBUG, "h261_init() for stream %d\n", st_index);
71 ctx
->streams
[st_index
]->need_parsing
= AVSTREAM_PARSE_FULL
;
76 int ff_h261_handle_packet(AVFormatContext
*ctx
, PayloadContext
*data
,
77 AVStream
*st
, AVPacket
*pkt
, uint32_t *timestamp
,
78 const uint8_t *buf
, int len
, uint16_t seq
, int flags
)
80 int sbit
, ebit
, gobn
, mbap
, quant
;
83 /* drop data of previous packets in case of non-continuous (loss) packet stream */
84 if (data
->buf
&& data
->timestamp
!= *timestamp
) {
85 h261_free_dyn_buffer(&data
->buf
);
88 /* sanity check for size of input packet: 1 byte payload at least */
89 if (len
< RTP_H261_PAYLOAD_HEADER_SIZE
+ 1) {
90 av_log(ctx
, AV_LOG_ERROR
, "Too short RTP/H.261 packet, got %d bytes\n", len
);
91 return AVERROR_INVALIDDATA
;
95 decode the H.261 payload header according to section 4.1 of RFC 4587:
96 (uses 4 bytes between RTP header and H.261 stream per packet)
99 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
100 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101 |SBIT |EBIT |I|V| GOBN | MBAP | QUANT | HMVD | VMVD |
102 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104 Start bit position (SBIT): 3 bits
105 End bit position (EBIT): 3 bits
106 INTRA-frame encoded data (I): 1 bit
107 Motion Vector flag (V): 1 bit
108 GOB number (GOBN): 4 bits
109 Macroblock address predictor (MBAP): 5 bits
110 Quantizer (QUANT): 5 bits
111 Horizontal motion vector data (HMVD): 5 bits
112 Vertical motion vector data (VMVD): 5 bits
115 sbit
= (buf
[0] >> 5) & 0x07;
116 ebit
= (buf
[0] >> 2) & 0x07;
117 gobn
= (buf
[1] >> 4) & 0x0f;
118 mbap
= ((buf
[1] << 1) & 0x1e) | ((buf
[2] >> 7) & 0x01);
119 quant
= (buf
[2] >> 2) & 0x1f;
121 /* pass the H.261 payload header and continue with the actual payload */
122 buf
+= RTP_H261_PAYLOAD_HEADER_SIZE
;
123 len
-= RTP_H261_PAYLOAD_HEADER_SIZE
;
125 /* start frame buffering with new dynamic buffer */
127 /* sanity check: a new frame starts with gobn=0, sbit=0, mbap=0, uqnat=0 */
128 if (!gobn
&& !sbit
&& !mbap
&& !quant
){
129 res
= avio_open_dyn_buf(&data
->buf
);
132 /* update the timestamp in the frame packet with the one from the RTP packet */
133 data
->timestamp
= *timestamp
;
135 /* frame not started yet, need more packets */
136 return AVERROR(EAGAIN
);
140 /* do the "byte merging" at the boundaries of two consecutive frame fragments */
141 if (data
->endbyte_bits
|| sbit
) {
142 if (data
->endbyte_bits
== sbit
) {
143 data
->endbyte
|= buf
[0] & (0xff >> sbit
);
144 data
->endbyte_bits
= 0;
147 avio_w8(data
->buf
, data
->endbyte
);
149 /* ebit/sbit values inconsistent, assuming packet loss */
151 init_get_bits(&gb
, buf
, len
*8 - ebit
);
152 skip_bits(&gb
, sbit
);
153 if (data
->endbyte_bits
) {
154 data
->endbyte
|= get_bits(&gb
, 8 - data
->endbyte_bits
);
155 avio_w8(data
->buf
, data
->endbyte
);
157 while (get_bits_left(&gb
) >= 8)
158 avio_w8(data
->buf
, get_bits(&gb
, 8));
159 data
->endbyte_bits
= get_bits_left(&gb
);
160 if (data
->endbyte_bits
)
161 data
->endbyte
= get_bits(&gb
, data
->endbyte_bits
) <<
162 (8 - data
->endbyte_bits
);
169 avio_write(data
->buf
, buf
, len
- 1);
170 data
->endbyte_bits
= 8 - ebit
;
171 data
->endbyte
= buf
[len
- 1] & (0xff << ebit
);
173 avio_write(data
->buf
, buf
, len
);
176 /* RTP marker bit means: last fragment of current frame was received;
177 otherwise, an additional fragment is needed for the current frame */
178 if (!(flags
& RTP_FLAG_MARKER
))
179 return AVERROR(EAGAIN
);
181 /* write the completed last byte from the "byte merging" */
182 if (data
->endbyte_bits
)
183 avio_w8(data
->buf
, data
->endbyte
);
184 data
->endbyte_bits
= 0;
186 /* close frame buffering and create resulting A/V packet */
187 res
= ff_rtp_finalize_packet(pkt
, &data
->buf
, st
->index
);
194 RTPDynamicProtocolHandler ff_h261_dynamic_handler
= {
196 .codec_type
= AVMEDIA_TYPE_VIDEO
,
197 .codec_id
= AV_CODEC_ID_H261
,
199 .parse_packet
= ff_h261_handle_packet
,
200 .alloc
= h261_new_context
,
201 .free
= h261_free_context
,
202 .static_payload_id
= 31,