1 /*
2 * RTP Depacketization of RAW video (TR-03)
3 * Copyright (c) 2016 Savoir-faire Linux, Inc
4 *
5 * This file is part of FFmpeg.
6 *
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.
11 *
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.
16 *
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
20 */
21
22 /* Development sponsored by CBC/Radio-Canada */
23
32
41
44 unsigned int pgroup;
/* size of the pixel group in bytes */
46
48 };
49
51 {
55
56 if (!strncmp(
data->sampling,
"YCbCr-4:2:2", 11)) {
59
60 if (
data->depth == 8) {
64 }
else if (
data->depth == 10) {
68 } else {
70 }
71 }
else if (!strncmp(
data->sampling,
"YCbCr-4:2:0", 11)) {
74
75 if (
data->depth == 8) {
79 } else {
81 }
82 }
else if (!strncmp(
data->sampling,
"RGB", 3)) {
84 if (
data->depth == 8) {
89 } else {
91 }
92 }
else if (!strncmp(
data->sampling,
"BGR", 3)) {
94 if (
data->depth == 8) {
99 } else {
101 }
102 } else {
104 }
105
111
112 if (
data->interlaced)
114 else
116
117 if (
data->framerate.den > 0) {
120 }
121
122 return 0;
123 }
124
128 {
129 if (!strncmp(attr, "width", 5))
131 else if (!strncmp(attr, "height", 6))
133 else if (
data->sampling ==
NULL && !strncmp(attr,
"sampling", 8))
135 else if (!strncmp(attr, "depth", 5))
137 else if (!strncmp(attr, "interlace", 9))
138 data->interlaced = 1;
139 else if (!strncmp(attr, "exactframerate", 14)) {
142 } else if (!strncmp(attr, "TCS", 3)) {
143 if (!strncmp(
value,
"SDR", 3))
145 else if (!strncmp(
value,
"PQ", 2))
147 else if (!strncmp(
value,
"HLG", 3))
149 else if (!strncmp(
value,
"LINEAR", 6))
151 else if (!strncmp(
value,
"ST428-1", 7))
153 else
155 } else if (!strncmp(attr, "colorimetry", 11)) {
156 if (!strncmp(
value,
"BT601", 5)) {
159 }
else if (!strncmp(
value,
"BT709", 5)) {
162 }
else if (!strncmp(
value,
"BT2020", 6)) {
165 }
166 } else if (!strncmp(attr, "RANGE", 5)) {
167 if (!strncmp(
value,
"NARROW", 6))
169 else if (!strncmp(
value,
"FULL", 4))
171 }
172
173 return 0;
174 }
175
178 {
180
181 if (st_index < 0)
182 return 0;
183
185
190
193
196
200
203
211 }
212
213 return 0;
214 }
215
217 int stream_index)
218 {
220
222 if (!
data->interlaced ||
data->field) {
226 }
228 }
229
231
233 }
234
237 const uint8_t * buf,
int len,
238 uint16_t seq,
int flags)
239 {
241 const uint8_t *
headers = buf + 2;
/* skip extended seqnum */
242 const uint8_t *payload = buf + 2;
243 int payload_len =
len - 2;
244 int missed_last_packet = 0;
245
246 uint8_t *dest;
247
248 if (*timestamp !=
data->timestamp) {
249 if (
data->frame && (!
data->interlaced ||
data->field)) {
250 /*
251 * if we're here, it means that we missed the cue to return
252 * the previous AVPacket, that cue being the RTP_FLAG_MARKER
253 * in the last packet of either the previous frame (progressive)
254 * or the previous second field (interlace). Let's finalize the
255 * previous frame (or pair of fields) anyway by filling the AVPacket.
256 */
258 missed_last_packet = 1;
260 }
261
264
265 data->timestamp = *timestamp;
266
270 }
271 }
272
273 /*
274 * looks for the 'Continuation bit' in scan lines' headers
275 * to find where data start
276 */
277 do {
278 if (payload_len < 6)
280
281 cont = payload[4] & 0x80;
282 payload += 6;
283 payload_len -= 6;
284 } while (cont);
285
286 /* and now iterate over every scan lines */
287 do {
288 int copy_offset;
289
290 if (payload_len < data->pgroup)
292
300
301 if (!
data->pgroup || length %
data->pgroup)
303
304 if (length > payload_len)
305 length = payload_len;
306
307 if (
data->interlaced)
309
312
313 /* prevent ill-formed packets to write after buffer's end */
315 if (copy_offset + length >
data->frame_size || !
data->frame)
317
318 dest =
data->frame + copy_offset;
319 memcpy(dest, payload, length);
320
321 payload += length;
322 payload_len -= length;
323 } while (cont);
324
327 } else if (missed_last_packet) {
328 return 0;
329 }
330
332 }
333
341 };