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
29
38
41 unsigned int pgroup;
/* size of the pixel group in bytes */
43
45 };
46
48 {
52
53 if (!strncmp(
data->sampling,
"YCbCr-4:2:2", 11)) {
56
57 if (
data->depth == 8) {
61 }
else if (
data->depth == 10) {
65 } else {
67 }
68 }
else if (!strncmp(
data->sampling,
"YCbCr-4:2:0", 11)) {
71
72 if (
data->depth == 8) {
76 } else {
78 }
79 }
else if (!strncmp(
data->sampling,
"RGB", 3)) {
81 if (
data->depth == 8) {
86 } else {
88 }
89 }
else if (!strncmp(
data->sampling,
"BGR", 3)) {
91 if (
data->depth == 8) {
96 } else {
98 }
99 } else {
101 }
102
108
109 if (
data->interlaced)
111 else
113
114 if (
data->framerate.den > 0) {
117 }
118
119 return 0;
120 }
121
125 {
126 if (!strncmp(attr, "width", 5))
128 else if (!strncmp(attr, "height", 6))
130 else if (!strncmp(attr, "sampling", 8))
132 else if (!strncmp(attr, "depth", 5))
134 else if (!strncmp(attr, "interlace", 9))
135 data->interlaced = 1;
136 else if (!strncmp(attr, "exactframerate", 14)) {
139 } else if (!strncmp(attr, "TCS", 3)) {
140 if (!strncmp(
value,
"SDR", 3))
142 else if (!strncmp(
value,
"PQ", 2))
144 else if (!strncmp(
value,
"HLG", 3))
146 else if (!strncmp(
value,
"LINEAR", 6))
148 else if (!strncmp(
value,
"ST428-1", 7))
150 else
152 } else if (!strncmp(attr, "colorimetry", 11)) {
153 if (!strncmp(
value,
"BT601", 5)) {
156 }
else if (!strncmp(
value,
"BT709", 5)) {
159 }
else if (!strncmp(
value,
"BT2020", 6)) {
162 }
163 } else if (!strncmp(attr, "RANGE", 5)) {
164 if (!strncmp(
value,
"NARROW", 6))
166 else if (!strncmp(
value,
"FULL", 4))
168 }
169
170 return 0;
171 }
172
175 {
176 const char *p;
177
178 if (st_index < 0)
179 return 0;
180
184
187
188
191
194
197
199 }
200
201 return 0;
202 }
203
205 int stream_index)
206 {
208
210 if (!
data->interlaced ||
data->field) {
214 }
216 }
217
219
221 }
222
225 const uint8_t * buf,
int len,
226 uint16_t seq,
int flags)
227 {
229 const uint8_t *
headers = buf + 2;
/* skip extended seqnum */
230 const uint8_t *payload = buf + 2;
231 int payload_len =
len - 2;
232 int missed_last_packet = 0;
233
234 uint8_t *dest;
235
236 if (*timestamp !=
data->timestamp) {
237 if (
data->frame && (!
data->interlaced ||
data->field)) {
238 /*
239 * if we're here, it means that we missed the cue to return
240 * the previous AVPacket, that cue being the RTP_FLAG_MARKER
241 * in the last packet of either the previous frame (progressive)
242 * or the previous second field (interlace). Let's finalize the
243 * previous frame (or pair of fields) anyway by filling the AVPacket.
244 */
246 missed_last_packet = 1;
248 }
249
252
253 data->timestamp = *timestamp;
254
258 }
259 }
260
261 /*
262 * looks for the 'Continuation bit' in scan lines' headers
263 * to find where data start
264 */
265 do {
266 if (payload_len < 6)
268
269 cont = payload[4] & 0x80;
270 payload += 6;
271 payload_len -= 6;
272 } while (cont);
273
274 /* and now iterate over every scan lines */
275 do {
276 int copy_offset;
277
278 if (payload_len < data->pgroup)
280
288
289 if (!
data->pgroup || length %
data->pgroup)
291
292 if (length > payload_len)
293 length = payload_len;
294
295 if (
data->interlaced)
297
298 /* prevent ill-formed packets to write after buffer's end */
300 if (copy_offset + length >
data->frame_size || !
data->frame)
302
303 dest =
data->frame + copy_offset;
304 memcpy(dest, payload, length);
305
306 payload += length;
307 payload_len -= length;
308 } while (cont);
309
312 } else if (missed_last_packet) {
313 return 0;
314 }
315
317 }
318
326 };