1 /*
2 * RTP VP8 Depacketizer
3 * Copyright (c) 2010 Josh Allmann
4 * Copyright (c) 2012 Martin Storsjo
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * @brief RTP support for the VP8 payload
26 * @author Josh Allmann <joshua.allmann@gmail.com>
27 * @see http://tools.ietf.org/html/draft-ietf-payload-vp8-05
28 */
29
31
33
38 /* If sequence_ok is set, we keep returning data (even if we might have
39 * lost some data, but we haven't lost any too critical data that would
40 * cause the decoder to desynchronize and output random garbage).
41 */
47 /* If sequence_dirty is set, we have lost some data (critical or
48 * non-critical) and decoding will have some sort of artefacts, and
49 * we thus should request a new keyframe.
50 */
53 };
54
56 {
59 return;
63 }
64
66 const char *msg)
67 {
72 }
73
78 {
79 int start_partition, end_packet;
80 int extended_bits, part_id;
81 int pictureid_present = 0, tl0picidx_present = 0, tid_present = 0,
82 keyidx_present = 0;
83 int pictureid = -1, pictureid_mask = 0;
84 int returned_old_frame = 0;
85 uint32_t old_timestamp = 0;
86
87 if (!buf) {
90 if (ret < 0)
95 return 0;
96 }
98 }
99
100 if (len < 1)
102
103 extended_bits = buf[0] & 0x80;
104 start_partition = buf[0] & 0x10;
105 part_id = buf[0] & 0x0f;
107 buf++;
108 len--;
109 if (extended_bits) {
110 if (len < 1)
112 pictureid_present = buf[0] & 0x80;
113 tl0picidx_present = buf[0] & 0x40;
114 tid_present = buf[0] & 0x20;
115 keyidx_present = buf[0] & 0x10;
116 buf++;
117 len--;
118 }
119 if (pictureid_present) {
120 if (len < 1)
122 if (buf[0] & 0x80) {
123 if (len < 2)
125 pictureid =
AV_RB16(buf) & 0x7fff;
126 pictureid_mask = 0x7fff;
127 buf += 2;
128 len -= 2;
129 } else {
130 pictureid = buf[0] & 0x7f;
131 pictureid_mask = 0x7f;
132 buf++;
133 len--;
134 }
135 }
136 if (tl0picidx_present) {
137 // Ignoring temporal level zero index
138 buf++;
139 len--;
140 }
141 if (tid_present || keyidx_present) {
142 // Ignoring temporal layer index, layer sync bit and keyframe index
143 buf++;
144 len--;
145 }
146 if (len < 1)
148
149 if (start_partition && part_id == 0 && len >= 3) {
151 int non_key = buf[0] & 0x01;
152 if (!non_key) {
154 // Keyframe, decoding ok again
158 } else {
165 if (pictureid >= 0) {
168 "Missed a picture, sequence broken\n");
169 } else {
170 if (vp8->
data && !can_continue)
172 "Missed a picture, sequence broken\n");
173 }
174 } else {
175 uint16_t expected_seq = vp8->
prev_seq + 1;
176 int16_t
diff = seq - expected_seq;
178 // No picture id, so we can't know if missed packets
179 // contained any new frames. If diff == 0, we did get
180 // later packets from the same frame (matching timestamp),
181 // so we know we didn't miss any frame. If diff == 1 and
182 // we still have data (not flushed by the end of frame
183 // marker), the single missed packet must have been part
184 // of the same frame.
185 if ((diff == 0 || diff == 1) && can_continue) {
186 // Proceed with what we have
187 } else {
189 "Missed too much, sequence broken\n");
190 }
191 } else {
192 if (diff != 0)
194 "Missed unknown data, sequence broken\n");
195 }
196 }
201 if (ret < 0)
204 returned_old_frame = 1;
206 } else {
207 // Shouldn't happen
209 }
210 }
211 }
214 return res;
219 } else {
220 uint16_t expected_seq = vp8->
prev_seq + 1;
221
224
226 // Missed the start of the new frame, sequence broken
228 "Received no start marker; dropping frame\n");
229 }
230
231 if (seq != expected_seq) {
234 "Missed part of a keyframe, sequence broken\n");
238 } else {
240 "Missed part of the first partition, sequence broken\n");
241 }
242 }
243 }
244
247
251
252 if (returned_old_frame) {
253 *timestamp = old_timestamp;
254 return end_packet ? 1 : 0;
255 }
256
257 if (end_packet) {
260 if (ret < 0)
264 return 0;
265 }
266
268 }
269
271 {
273 if (!vp8)
274 return NULL;
276 return vp8;
277 }
278
280 {
283 }
284
286 {
288 }
289
298 };