FFmpeg
Loading...
Searching...
No Matches
rtpdec_rfc4175.c
Go to the documentation of this file.
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
24#include "avio_internal.h"
25#include "rtpdec_formats.h"
26#include "libavutil/avassert.h"
27#include "libavutil/avstring.h"
28#include "libavutil/imgutils.h"
29#include "libavutil/mem.h"
30#include "libavutil/pixdesc.h"
32
33struct PayloadContext {
34 char *sampling;
36 int depth;
37 int width;
38 int height;
40 int field;
41
42 uint8_t *frame;
43 unsigned int frame_size;
44 unsigned int pgroup; /* size of the pixel group in bytes */
45 unsigned int xinc;
46
47 uint32_t timestamp;
48};
49
51{
53 int tag;
55
56 if (!strncmp(data->sampling, "YCbCr-4:2:2", 11)) {
57 tag = MKTAG('U', 'Y', 'V', 'Y');
58 data->xinc = 2;
59
60 if (data->depth == 8) {
61 data->pgroup = 4;
64 } else if (data->depth == 10) {
65 data->pgroup = 5;
68 } else {
70 }
71 } else if (!strncmp(data->sampling, "YCbCr-4:2:0", 11)) {
72 tag = MKTAG('I', '4', '2', '0');
73 data->xinc = 4;
74
75 if (data->depth == 8) {
76 data->pgroup = 6;
79 } else {
81 }
82 } else if (!strncmp(data->sampling, "RGB", 3)) {
83 tag = MKTAG('R', 'G', 'B', 24);
84 if (data->depth == 8) {
85 data->xinc = 1;
86 data->pgroup = 3;
89 } else {
91 }
92 } else if (!strncmp(data->sampling, "BGR", 3)) {
93 tag = MKTAG('B', 'G', 'R', 24);
94 if (data->depth == 8) {
95 data->xinc = 1;
96 data->pgroup = 3;
99 } else {
100 return AVERROR_INVALIDDATA;
101 }
102 } else {
103 return AVERROR_INVALIDDATA;
104 }
105
107 stream->codecpar->format = pixfmt;
108 stream->codecpar->codec_tag = tag;
110 data->frame_size = data->width * data->height * data->pgroup / data->xinc;
111
112 if (data->interlaced)
114 else
116
117 if (data->framerate.den > 0) {
118 stream->avg_frame_rate = data->framerate;
119 stream->codecpar->bit_rate = data->frame_size * av_q2d(data->framerate) * 8;
120 }
121
122 return 0;
123}
124
126 PayloadContext *data, const char *attr,
127 const char *value)
128{
129 if (!strncmp(attr, "width", 5))
130 data->width = atoi(value);
131 else if (!strncmp(attr, "height", 6))
132 data->height = atoi(value);
133 else if (data->sampling == NULL && !strncmp(attr, "sampling", 8))
134 data->sampling = av_strdup(value);
135 else if (!strncmp(attr, "depth", 5))
136 data->depth = atoi(value);
137 else if (!strncmp(attr, "interlace", 9))
138 data->interlaced = 1;
139 else if (!strncmp(attr, "exactframerate", 14)) {
140 if (av_parse_video_rate(&data->framerate, value) < 0)
141 return AVERROR(EINVAL);
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
176static int rfc4175_parse_sdp_line(AVFormatContext *s, int st_index,
177 PayloadContext *data_arg, const char *line)
178{
179 const char *p;
180
181 if (st_index < 0)
182 return 0;
183
184 av_assert0(!data_arg->sampling);
185
186 if (av_strstart(line, "fmtp:", &p)) {
187 AVStream *stream = s->streams[st_index];
188 PayloadContext data0 = *data_arg, *data = &data0;
189 int ret = ff_parse_fmtp(s, stream, data, p, rfc4175_parse_fmtp);
190
191 if (!data->sampling || !data->depth || !data->width || !data->height)
192 ret = AVERROR(EINVAL);
193
194 if (ret < 0)
195 goto fail;
196
197 ret = av_image_check_size(data->width, data->height, 0, s);
198 if (ret < 0)
199 goto fail;
200
201 stream->codecpar->width = data->width;
202 stream->codecpar->height = data->height;
203
204 ret = rfc4175_parse_format(stream, data);
205 av_freep(&data->sampling);
206 if (ret >= 0)
207 *data_arg = *data;
208fail:
209 av_freep(&data->sampling);
210 return ret;
211 }
212
213 return 0;
214}
215
217 int stream_index)
218{
219 int ret = 0;
220
221 pkt->stream_index = stream_index;
222 if (!data->interlaced || data->field) {
223 ret = av_packet_from_data(pkt, data->frame, data->frame_size);
224 if (ret < 0) {
225 av_freep(&data->frame);
226 }
227 data->frame = NULL;
228 }
229
230 data->field = 0;
231
232 return ret;
233}
234
236 AVStream *st, AVPacket *pkt, uint32_t *timestamp,
237 const uint8_t * buf, int len,
238 uint16_t seq, int flags)
239{
240 int length, line, offset, cont, field;
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 */
257 av_log(ctx, AV_LOG_ERROR, "Missed previous RTP Marker\n");
258 missed_last_packet = 1;
260 }
261
262 if (!data->frame)
263 data->frame = av_malloc(data->frame_size);
264
265 data->timestamp = *timestamp;
266
267 if (!data->frame) {
268 av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
269 return AVERROR(ENOMEM);
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)
279 return AVERROR_INVALIDDATA;
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)
291 return AVERROR_INVALIDDATA;
292
293 length = (headers[0] << 8) | headers[1];
294 field = (headers[2] & 0x80) >> 7;
295 line = ((headers[2] & 0x7f) << 8) | headers[3];
296 offset = ((headers[4] & 0x7f) << 8) | headers[5];
297 cont = headers[4] & 0x80;
298 headers += 6;
299 data->field = field;
300
301 if (!data->pgroup || length % data->pgroup)
302 return AVERROR_INVALIDDATA;
303
304 if (length > payload_len)
305 length = payload_len;
306
307 if (data->interlaced)
308 line = 2 * line + field;
309
310 if (line >= data->height)
311 return AVERROR_INVALIDDATA;
312
313 /* prevent ill-formed packets to write after buffer's end */
314 copy_offset = (line * data->width + offset) * data->pgroup / data->xinc;
315 if (copy_offset + length > data->frame_size || !data->frame)
316 return AVERROR_INVALIDDATA;
317
318 dest = data->frame + copy_offset;
319 memcpy(dest, payload, length);
320
321 payload += length;
322 payload_len -= length;
323 } while (cont);
324
325 if ((flags & RTP_FLAG_MARKER)) {
327 } else if (missed_last_packet) {
328 return 0;
329 }
330
331 return AVERROR(EAGAIN);
332}
333
335 .enc_name = "raw",
336 .codec_type = AVMEDIA_TYPE_VIDEO,
337 .codec_id = AV_CODEC_ID_NONE,
338 .priv_data_size = sizeof(PayloadContext),
339 .parse_sdp_a_line = rfc4175_parse_sdp_line,
341};
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
@ AV_FIELD_TT
Top coded_first, top displayed first.
Definition defs.h:214
@ AV_FIELD_PROGRESSIVE
Definition defs.h:213
static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index, int flush)
Parse a packet, add all split parts to parse_queue.
Definition demux.c:1178
static AVPacket * pkt
double value
Definition eval.c:102
#define fail
Definition test.h:479
@ AV_CODEC_ID_RAWVIDEO
Definition codec_id.h:63
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_BITPACKED
Definition codec_id.h:276
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
Initialize a reference-counted packet from av_malloc()ed data.
Definition packet.c:172
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition rational.h:104
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition imgutils.c:318
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
misc image utilities
enum AVPixelFormat pixfmt
Definition kmsgrab.c:367
unsigned offset
Definition libaomenc.c:763
const char * desc
Definition libsvtav1.c:83
#define MKTAG(a, b, c, d)
Definition macros.h:55
Memory handling functions.
uint32_t tag
Definition movenc.c:2073
const char data[16]
Definition mxf.c:149
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
Definition parseutils.c:181
misc parsing utilities
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition pixdesc.c:3412
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AVCOL_RANGE_JPEG
Full range content.
Definition pixfmt.h:783
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition pixfmt.h:88
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition pixfmt.h:76
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition pixfmt.h:649
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition pixfmt.h:644
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition pixfmt.h:653
@ AVCOL_TRC_SMPTEST428_1
Definition pixfmt.h:692
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition pixfmt.h:689
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition pixfmt.h:681
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition pixfmt.h:693
@ AVCOL_TRC_UNSPECIFIED
Definition pixfmt.h:675
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition pixfmt.h:674
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition pixfmt.h:708
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition pixfmt.h:712
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition pixfmt.h:717
int ff_parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *p, int(*parse_fmtp)(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *attr, const char *value))
Definition rtpdec.c:945
#define RTP_FLAG_MARKER
RTP marker bit was set for this packet.
Definition rtpdec.h:94
const RTPDynamicProtocolHandler ff_rfc4175_rtp_handler
static int rfc4175_parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *attr, const char *value)
static int rfc4175_finalize_packet(PayloadContext *data, AVPacket *pkt, int stream_index)
static int rfc4175_parse_sdp_line(AVFormatContext *s, int st_index, PayloadContext *data_arg, const char *line)
static int rfc4175_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags)
static int rfc4175_parse_format(AVStream *stream, PayloadContext *data)
enum AVColorSpace color_space
Definition codec_par.h:192
enum AVFieldOrder field_order
The order of the fields in interlaced video.
Definition codec_par.h:182
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition codec_par.h:113
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
enum AVColorPrimaries color_primaries
Definition codec_par.h:190
enum AVColorTransferCharacteristic color_trc
Definition codec_par.h:191
enum AVColorRange color_range
Additional colorspace characteristics.
Definition codec_par.h:189
Format I/O context.
Definition avformat.h:1333
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
Rational number (pair of numerator and denominator).
Definition rational.h:58
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int index
stream index in AVFormatContext
Definition avformat.h:772
AVRational avg_frame_rate
Average framerate.
Definition avformat.h:855
RTP/AV1 specific private data.
Definition rdt.c:85
AVIOContext * frame
current frame buffer
Definition rtpdec_jpeg.c:35
uint32_t timestamp
last received timestamp for frame
Definition rtpdec_ac3.c:31
unsigned int xinc
unsigned int frame_size
AVRational framerate
unsigned int pgroup
#define av_freep(p)
#define av_log(a,...)
static AVFormatContext * ctx
Definition movenc.c:49
int len