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