]> git.sesse.net Git - ffmpeg/blob - libavformat/rtpdec_vp9.c
Merge commit '0af3b65880573aa9b3375362eaab4f84140c7dde'
[ffmpeg] / libavformat / rtpdec_vp9.c
1 /*
2  * RTP parser for VP9 payload format (draft version 0) - experimental
3  * Copyright (c) 2015 Thomas Volkert <thomas@homer-conferencing.com>
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
23 #include "libavcodec/bytestream.h"
24
25 #include "avio_internal.h"
26 #include "rtpdec_formats.h"
27
28 #define RTP_VP9_DESC_REQUIRED_SIZE 1
29
30 struct PayloadContext {
31     AVIOContext *buf;
32     uint32_t     timestamp;
33 };
34
35 static av_cold int vp9_init(AVFormatContext *ctx, int st_index,
36                              PayloadContext *data)
37 {
38     av_dlog(ctx, "vp9_init() for stream %d\n", st_index);
39     av_log(ctx, AV_LOG_WARNING,
40            "RTP/VP9 support is still experimental\n");
41
42     if (st_index < 0)
43         return 0;
44
45     ctx->streams[st_index]->need_parsing = AVSTREAM_PARSE_FULL;
46
47     return 0;
48 }
49
50 static int vp9_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_vp9_ctx,
51                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,
52                              const uint8_t *buf, int len, uint16_t seq,
53                              int flags)
54 {
55     int has_pic_id, has_layer_idc, has_ref_idc, has_ss_data, has_su_data;
56     av_unused int pic_id = 0, non_key_frame = 0;
57     av_unused int layer_temporal = -1, layer_spatial = -1, layer_quality = -1;
58     int ref_fields = 0, has_ref_field_ext_pic_id = 0;
59     int first_fragment, last_fragment;
60     int res = 0;
61
62     /* drop data of previous packets in case of non-continuous (lossy) packet stream */
63     if (rtp_vp9_ctx->buf && rtp_vp9_ctx->timestamp != *timestamp) {
64         ffio_free_dyn_buf(&rtp_vp9_ctx->buf);
65     }
66
67     /* sanity check for size of input packet: 1 byte payload at least */
68     if (len < RTP_VP9_DESC_REQUIRED_SIZE + 1) {
69         av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet, got %d bytes\n", len);
70         return AVERROR_INVALIDDATA;
71     }
72
73     /*
74       decode the required VP9 payload descriptor according to section 4.2 of the spec.:
75
76             0 1 2 3 4 5 6 7
77            +-+-+-+-+-+-+-+-+
78            |I|L|F|B|E|V|U|-| (REQUIRED)
79            +-+-+-+-+-+-+-+-+
80
81            I: PictureID present
82            L: Layer indices present
83            F: Reference indices present
84            B: Start of VP9 frame
85            E: End of picture
86            V: Scalability Structure (SS) present
87            U: Scalability Structure Update (SU) present
88     */
89     has_pic_id     = buf[0] & 0x80;
90     has_layer_idc  = buf[0] & 0x40;
91     has_ref_idc    = buf[0] & 0x20;
92     first_fragment = buf[0] & 0x10;
93     last_fragment  = buf[0] & 0x08;
94     has_ss_data    = buf[0] & 0x04;
95     has_su_data    = buf[0] & 0x02;
96
97     /* sanity check for markers: B should always be equal to the RTP M marker */
98     if (last_fragment >> 2 != flags & RTP_FLAG_MARKER) {
99         av_log(ctx, AV_LOG_ERROR, "Invalid combination of B and M marker\n");
100         return AVERROR_INVALIDDATA;
101     }
102
103     /* pass the extensions field */
104     buf += RTP_VP9_DESC_REQUIRED_SIZE;
105     len -= RTP_VP9_DESC_REQUIRED_SIZE;
106
107     /*
108       decode the 1-byte/2-byte picture ID:
109
110             0 1 2 3 4 5 6 7
111            +-+-+-+-+-+-+-+-+
112    I:      |M|PICTURE ID   | (RECOMMENDED)
113            +-+-+-+-+-+-+-+-+
114    M:      | EXTENDED PID  | (RECOMMENDED)
115            +-+-+-+-+-+-+-+-+
116
117            M: The most significant bit of the first octet is an extension flag.
118            PictureID:  8 or 16 bits including the M bit.
119      */
120     if (has_pic_id) {
121         if (len < 1) {
122             av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
123             return AVERROR_INVALIDDATA;
124         }
125
126         /* check for 1-byte or 2-byte picture index */
127         if (buf[0] & 0x80) {
128             if (len < 2) {
129                 av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
130                 return AVERROR_INVALIDDATA;
131             }
132             pic_id = AV_RB16(buf) & 0x7fff;
133             buf += 2;
134             len -= 2;
135         } else {
136             pic_id = buf[0] & 0x7f;
137             buf++;
138             len--;
139         }
140     }
141
142     /*
143       decode layer indices
144
145             0 1 2 3 4 5 6 7
146            +-+-+-+-+-+-+-+-+
147    L:      | T | S | Q | R | (CONDITIONALLY RECOMMENDED)
148            +-+-+-+-+-+-+-+-+
149
150            T, S and Q are 2-bit indices for temporal, spatial, and quality layers.
151            If "F" is set in the initial octet, R is 2 bits representing the number
152            of reference fields this frame refers to.
153      */
154     if (has_layer_idc) {
155         if (len < 1) {
156             av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet");
157             return AVERROR_INVALIDDATA;
158         }
159         layer_temporal = buf[0] & 0xC0;
160         layer_spatial  = buf[0] & 0x30;
161         layer_quality  = buf[0] & 0x0C;
162         if (has_ref_idc) {
163             ref_fields = buf[0] & 0x03;
164             if (ref_fields)
165                 non_key_frame = 1;
166         }
167         buf++;
168         len--;
169     }
170
171     /*
172       decode the reference fields
173
174             0 1 2 3 4 5 6 7
175            +-+-+-+-+-+-+-+-+              -\
176    F:      | PID |X| RS| RQ| (OPTIONAL)    .
177            +-+-+-+-+-+-+-+-+               . - R times
178    X:      | EXTENDED PID  | (OPTIONAL)    .
179            +-+-+-+-+-+-+-+-+              -/
180
181            PID:  The relative Picture ID referred to by this frame.
182            RS and RQ:  The spatial and quality layer IDs.
183            X: 1 if this layer index has an extended relative Picture ID.
184      */
185     if (has_ref_idc) {
186         while (ref_fields) {
187             if (len < 1) {
188                 av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
189                 return AVERROR_INVALIDDATA;
190             }
191
192             has_ref_field_ext_pic_id = buf[0] & 0x10;
193
194             /* pass ref. field */
195             if (has_ref_field_ext_pic_id) {
196                 if (len < 2) {
197                     av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
198                     return AVERROR_INVALIDDATA;
199                 }
200
201                 /* ignore ref. data */
202
203                 buf += 2;
204                 len -= 2;
205             } else {
206
207                 /* ignore ref. data */
208
209                 buf++;
210                 len--;
211             }
212             ref_fields--;
213         }
214     }
215
216     /*
217       decode the scalability structure (SS)
218
219             0 1 2 3 4 5 6 7
220            +-+-+-+-+-+-+-+-+
221       V:   | PATTERN LENGTH|
222            +-+-+-+-+-+-+-+-+                           -\
223            | T | S | Q | R | (OPTIONAL)                 .
224            +-+-+-+-+-+-+-+-+              -\            .
225            | PID |X| RS| RQ| (OPTIONAL)    .            . - PAT. LEN. times
226            +-+-+-+-+-+-+-+-+               . - R times  .
227       X:   | EXTENDED PID  | (OPTIONAL)    .            .
228            +-+-+-+-+-+-+-+-+              -/           -/
229
230            PID:  The relative Picture ID referred to by this frame.
231            RS and RQ:  The spatial and quality layer IDs.
232            X: 1 if this layer index has an extended relative Picture ID.
233      */
234     if (has_ss_data) {
235         avpriv_report_missing_feature(ctx, "VP9 scalability structure data\n");
236         return AVERROR_PATCHWELCOME;
237     }
238
239     /*
240       decode the scalability update structure (SU)
241
242         spec. is tbd
243      */
244     if (has_su_data) {
245         avpriv_report_missing_feature(ctx, "VP9 scalability update structure data\n");
246         return AVERROR_PATCHWELCOME;
247     }
248
249     /*
250       decode the VP9 payload header
251
252         spec. is tbd
253      */
254     //XXX: implement when specified
255
256     /* sanity check: 1 byte payload as minimum */
257     if (len < 1) {
258         av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n");
259         return AVERROR_INVALIDDATA;
260     }
261
262     /* start frame buffering with new dynamic buffer */
263     if (!rtp_vp9_ctx->buf) {
264         /* sanity check: a new frame should have started */
265         if (first_fragment) {
266             res = avio_open_dyn_buf(&rtp_vp9_ctx->buf);
267             if (res < 0)
268                 return res;
269             /* update the timestamp in the frame packet with the one from the RTP packet */
270             rtp_vp9_ctx->timestamp = *timestamp;
271         } else {
272             /* frame not started yet, need more packets */
273             return AVERROR(EAGAIN);
274         }
275     }
276
277     /* write the fragment to the dyn. buffer */
278     avio_write(rtp_vp9_ctx->buf, buf, len);
279
280     /* do we need more fragments? */
281     if (!last_fragment)
282         return AVERROR(EAGAIN);
283
284     /* close frame buffering and create resulting A/V packet */
285     res = ff_rtp_finalize_packet(pkt, &rtp_vp9_ctx->buf, st->index);
286     if (res < 0)
287         return res;
288
289     return 0;
290 }
291
292 RTPDynamicProtocolHandler ff_vp9_dynamic_handler = {
293     .enc_name         = "VP9",
294     .codec_type       = AVMEDIA_TYPE_VIDEO,
295     .codec_id         = AV_CODEC_ID_VP9,
296     .init             = vp9_init,
297     .priv_data_size   = sizeof(PayloadContext),
298     .parse_packet     = vp9_handle_packet
299 };