1 /*
2 * Vp9 invisible (alt-ref) frame to superframe merge bitstream filter
3 * Copyright (c) 2016 Ronald S. Bultje <rsbultje@gmail.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
23
27
33
35 unsigned *_max, unsigned *_sum)
36 {
37 int n;
38 unsigned max = 0, sum = 0;
39
40 for (n = 0; n < n_in; n++) {
41 unsigned sz = in[n]->
size;
42
45 sum += sz;
46 }
47
49 *_sum = sum;
50 }
51
53 {
54 unsigned max, sum, mag, marker, n, sz;
55 uint8_t *ptr;
56 int res;
57
60 marker = 0xC0 + (mag << 3) + (n_in - 1);
61 sz = sum + 2 + (mag + 1) * n_in;
63 if (res < 0)
64 return res;
66 for (n = 0; n < n_in; n++) {
67 memcpy(ptr, in[n]->
data, in[n]->
size);
69 }
70
71 #define wloop(mag, wr) \
72 do { \
73 for (n = 0; n < n_in; n++) { \
74 wr; \
75 ptr += mag + 1; \
76 } \
77 } while (0)
78
79 // write superframe with marker 110[mag:2][nframes:3]
80 *ptr++ = marker;
81 switch (mag) {
82 case 0:
84 break;
85 case 1:
87 break;
88 case 2:
90 break;
91 case 3:
93 break;
94 }
95 *ptr++ = marker;
97
98 return 0;
99 }
100
102 {
105 int res, invisible,
profile, marker, uses_superframe_syntax = 0, n;
106
108 if (res < 0)
109 return res;
110
112 /* In case the cache is empty we can pass side-data-only packets
113 * through unchanged. Otherwise, such a packet makes no sense. */
115 return 0;
117 goto done;
118 }
119
121 if ((marker & 0xe0) == 0xc0) {
122 int nbytes = 1 + ((marker >> 3) & 0x3);
123 int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes;
124
126 }
127
129 goto done;
130
135
137 invisible = 0;
138 } else {
141 }
142
143 if (uses_superframe_syntax &&
s->n_cache > 0) {
145 "Mixing of superframe syntax and naked VP9 frames not supported\n");
147 goto done;
148 }
else if ((!invisible || uses_superframe_syntax) && !
s->n_cache) {
149 // passthrough
150 return 0;
153 "Too many invisible frames\n");
155 goto done;
156 }
157
159
160 if (invisible) {
162 }
164
165 // build superframe
167 goto done;
168
170 if (res < 0)
171 goto done;
172
173 for (n = 0; n <
s->n_cache; n++)
176
177 done:
178 if (res < 0)
180 return res;
181 }
182
184 {
186 int n;
187
188 // alloc cache packets
193 }
194
195 return 0;
196 }
197
199 {
201 int n;
202
203 // unref cached data
204 for (n = 0; n <
s->n_cache; n++)
207 }
208
210 {
212 int n;
213
214 // free cached data
217 }
218
221 };
222
224 .
p.
name =
"vp9_superframe",
231 };