1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#include "libavutil/avassert.h"
20#include "libavutil/intmath.h"
21#include "libavutil/log.h"
22#include "libavutil/mem.h"
23
24#include "bsf.h"
25#include "bsf_internal.h"
26#include "get_bits.h"
27#include "put_bits.h"
28
29#define FRAME_SLOTS 8
30
31typedef struct VP9RawReorderFrame {
32    AVPacket    *packet;
33    int          needs_output;
34    int          needs_display;
35
36    int64_t      pts;
37    int64_t      sequence;
38    unsigned int slots;
39
40    unsigned int profile;
41
42    unsigned int show_existing_frame;
43    unsigned int frame_to_show;
44
45    unsigned int frame_type;
46    unsigned int show_frame;
47    unsigned int refresh_frame_flags;
48} VP9RawReorderFrame;
49
50typedef struct VP9RawReorderContext {
51    int64_t sequence;
52    VP9RawReorderFrame *slot[FRAME_SLOTS];
53    VP9RawReorderFrame *next_frame;
54} VP9RawReorderContext;
55
56static void vp9_raw_reorder_frame_free(VP9RawReorderFrame **frame)
57{
58    if (*frame)
59        av_packet_free(&(*frame)->packet);
60    av_freep(frame);
61}
62
63static void vp9_raw_reorder_clear_slot(VP9RawReorderContext *ctx, int s)
64{
65    if (ctx->slot[s]) {
66        ctx->slot[s]->slots &= ~(1 << s);
67        if (ctx->slot[s]->slots == 0)
68            vp9_raw_reorder_frame_free(&ctx->slot[s]);
69        else
70            ctx->slot[s] = NULL;
71    }
72}
73
74static int vp9_raw_reorder_frame_parse(AVBSFContext *bsf, VP9RawReorderFrame *frame)
75{
76    GetBitContext bc;
77    int err;
78
79    unsigned int frame_marker;
80    unsigned int profile_low_bit, profile_high_bit, reserved_zero;
81    unsigned int error_resilient_mode;
82    unsigned int frame_sync_code;
83
84    err = init_get_bits(&bc, frame->packet->data, 8 * frame->packet->size);
85    if (err)
86        return err;
87
88    frame_marker = get_bits(&bc, 2);
89    if (frame_marker != 2) {
90        av_log(bsf, AV_LOG_ERROR, "Invalid frame marker: %u.\n",
91               frame_marker);
92        return AVERROR_INVALIDDATA;
93    }
94
95    profile_low_bit  = get_bits1(&bc);
96    profile_high_bit = get_bits1(&bc);
97    frame->profile = (profile_high_bit << 1) | profile_low_bit;
98    if (frame->profile == 3) {
99        reserved_zero = get_bits1(&bc);
100        if (reserved_zero != 0) {
101            av_log(bsf, AV_LOG_ERROR, "Profile reserved_zero bit set: "
102                   "unsupported profile or invalid bitstream.\n");
103            return AVERROR_INVALIDDATA;
104        }
105    }
106
107    frame->show_existing_frame = get_bits1(&bc);
108    if (frame->show_existing_frame) {
109        frame->frame_to_show = get_bits(&bc, 3);
110        return 0;
111    }
112
113    frame->frame_type = get_bits1(&bc);
114    frame->show_frame = get_bits1(&bc);
115    error_resilient_mode = get_bits1(&bc);
116
117    if (frame->frame_type == 0) {
118        frame_sync_code = get_bits(&bc, 24);
119        if (frame_sync_code != 0x498342) {
120            av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: %06x.\n",
121                   frame_sync_code);
122            return AVERROR_INVALIDDATA;
123        }
124        frame->refresh_frame_flags = 0xff;
125    } else {
126        unsigned int intra_only;
127
128        if (frame->show_frame == 0)
129            intra_only = get_bits1(&bc);
130        else
131            intra_only = 0;
132        if (error_resilient_mode == 0) {
133            // reset_frame_context
134            skip_bits(&bc, 2);
135        }
136        if (intra_only) {
137            frame_sync_code = get_bits(&bc, 24);
138            if (frame_sync_code != 0x498342) {
139                av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: "
140                       "%06x.\n", frame_sync_code);
141                return AVERROR_INVALIDDATA;
142            }
143            if (frame->profile > 0) {
144                unsigned int color_space;
145                if (frame->profile >= 2) {
146                    // ten_or_twelve_bit
147                    skip_bits(&bc, 1);
148                }
149                color_space = get_bits(&bc, 3);
150                if (color_space != 7 /* CS_RGB */) {
151                    // color_range
152                    skip_bits(&bc, 1);
153                    if (frame->profile == 1 || frame->profile == 3) {
154                        // subsampling
155                        skip_bits(&bc, 3);
156                    }
157                } else {
158                    if (frame->profile == 1 || frame->profile == 3)
159                        skip_bits(&bc, 1);
160                }
161            }
162            frame->refresh_frame_flags = get_bits(&bc, 8);
163        } else {
164            frame->refresh_frame_flags = get_bits(&bc, 8);
165        }
166    }
167
168    return 0;
169}
170
171static int vp9_raw_reorder_make_output(AVBSFContext *bsf,
172                                   AVPacket *out,
173                                   VP9RawReorderFrame *last_frame)
174{
175    VP9RawReorderContext *ctx = bsf->priv_data;
176    VP9RawReorderFrame *next_output = last_frame,
177                      *next_display = last_frame, *frame;
178    int s, err;
179
180    for (s = 0; s < FRAME_SLOTS; s++) {
181        frame = ctx->slot[s];
182        if (!frame)
183            continue;
184        if (frame->needs_output && (!next_output ||
185            frame->sequence < next_output->sequence))
186            next_output = frame;
187        if (frame->needs_display && (!next_display ||
188            frame->pts < next_display->pts))
189            next_display = frame;
190    }
191
192    if (!next_output && !next_display)
193        return AVERROR_EOF;
194
195    if (!next_display || (next_output &&
196        next_output->sequence < next_display->sequence))
197        frame = next_output;
198    else
199        frame = next_display;
200
201    if (frame->needs_output && frame->needs_display &&
202        next_output == next_display) {
203        av_log(bsf, AV_LOG_DEBUG, "Output and display frame "
204               "%"PRId64" (%"PRId64") in order.\n",
205               frame->sequence, frame->pts);
206
207        av_packet_move_ref(out, frame->packet);
208
209        frame->needs_output = frame->needs_display = 0;
210    } else if (frame->needs_output) {
211        if (frame->needs_display) {
212            av_log(bsf, AV_LOG_DEBUG, "Output frame %"PRId64" "
213                   "(%"PRId64") for later display.\n",
214                   frame->sequence, frame->pts);
215        } else {
216            av_log(bsf, AV_LOG_DEBUG, "Output unshown frame "
217                   "%"PRId64" (%"PRId64") to keep order.\n",
218                   frame->sequence, frame->pts);
219        }
220
221        av_packet_move_ref(out, frame->packet);
222        out->pts = out->dts;
223
224        frame->needs_output = 0;
225    } else {
226        PutBitContext pb;
227
228        av_assert0(!frame->needs_output && frame->needs_display);
229
230        if (frame->slots == 0) {
231            av_log(bsf, AV_LOG_ERROR, "Attempting to display frame "
232                   "which is no longer available?\n");
233            frame->needs_display = 0;
234            return AVERROR_INVALIDDATA;
235        }
236
237        s = ff_ctz(frame->slots);
238        av_assert0(s < FRAME_SLOTS);
239
240        av_log(bsf, AV_LOG_DEBUG, "Display frame %"PRId64" "
241               "(%"PRId64") from slot %d.\n",
242               frame->sequence, frame->pts, s);
243
244        err = av_new_packet(out, 2);
245        if (err < 0)
246            return err;
247
248        init_put_bits(&pb, out->data, 2);
249
250        // frame_marker
251        put_bits(&pb, 2, 2);
252        // profile_low_bit
253        put_bits(&pb, 1, frame->profile & 1);
254        // profile_high_bit
255        put_bits(&pb, 1, (frame->profile >> 1) & 1);
256        if (frame->profile == 3) {
257            // reserved_zero
258            put_bits(&pb, 1, 0);
259        }
260        // show_existing_frame
261        put_bits(&pb, 1, 1);
262        // frame_to_show_map_idx
263        put_bits(&pb, 3, s);
264
265        while (put_bits_count(&pb) < 16)
266            put_bits(&pb, 1, 0);
267
268        flush_put_bits(&pb);
269        out->pts = out->dts = frame->pts;
270
271        frame->needs_display = 0;
272    }
273
274    return 0;
275}
276
277static int vp9_raw_reorder_filter(AVBSFContext *bsf, AVPacket *out)
278{
279    VP9RawReorderContext *ctx = bsf->priv_data;
280    VP9RawReorderFrame *frame;
281    AVPacket *in;
282    int err, s;
283
284    if (ctx->next_frame) {
285        frame = ctx->next_frame;
286
287    } else {
288        err = ff_bsf_get_packet(bsf, &in);
289        if (err < 0) {
290            if (err == AVERROR_EOF)
291                return vp9_raw_reorder_make_output(bsf, out, NULL);
292            return err;
293        }
294
295        if (!in->size) {
296            av_packet_free(&in);
297            return AVERROR_INVALIDDATA;
298        }
299
300        if ((in->data[in->size - 1] & 0xe0) == 0xc0) {
301            av_log(bsf, AV_LOG_ERROR, "Input in superframes is not "
302                   "supported.\n");
303            av_packet_free(&in);
304            return AVERROR(ENOSYS);
305        }
306
307        frame = av_mallocz(sizeof(*frame));
308        if (!frame) {
309            av_packet_free(&in);
310            return AVERROR(ENOMEM);
311        }
312
313        frame->packet   = in;
314        frame->pts      = in->pts;
315        frame->sequence = ++ctx->sequence;
316        err = vp9_raw_reorder_frame_parse(bsf, frame);
317        if (err) {
318            av_log(bsf, AV_LOG_ERROR, "Failed to parse input "
319                   "frame: %d.\n", err);
320            goto fail;
321        }
322
323        frame->needs_output  = 1;
324        frame->needs_display = frame->pts != AV_NOPTS_VALUE;
325
326        if (frame->show_existing_frame)
327            av_log(bsf, AV_LOG_DEBUG, "Show frame %"PRId64" "
328                   "(%"PRId64"): show %u.\n", frame->sequence,
329                   frame->pts, frame->frame_to_show);
330        else
331            av_log(bsf, AV_LOG_DEBUG, "New frame %"PRId64" "
332                   "(%"PRId64"): type %u show %u refresh %02x.\n",
333                   frame->sequence, frame->pts, frame->frame_type,
334                   frame->show_frame, frame->refresh_frame_flags);
335
336        ctx->next_frame = frame;
337    }
338
339    for (s = 0; s < FRAME_SLOTS; s++) {
340        if (!(frame->refresh_frame_flags & (1 << s)))
341            continue;
342        if (ctx->slot[s] && ctx->slot[s]->needs_display &&
343            ctx->slot[s]->slots == (1 << s)) {
344            // We are overwriting this slot, which is last reference
345            // to the frame previously present in it.  In order to be
346            // a valid stream, that frame must already have been
347            // displayed before the pts of the current frame.
348            err = vp9_raw_reorder_make_output(bsf, out, ctx->slot[s]);
349            if (err < 0) {
350                av_log(bsf, AV_LOG_ERROR, "Failed to create "
351                       "output overwriting slot %d: %d.\n",
352                       s, err);
353                // Clear the slot anyway, so we don't end up
354                // in an infinite loop.
355                vp9_raw_reorder_clear_slot(ctx, s);
356                return AVERROR_INVALIDDATA;
357            }
358            return 0;
359        }
360        vp9_raw_reorder_clear_slot(ctx, s);
361    }
362
363    for (s = 0; s < FRAME_SLOTS; s++) {
364        if (!(frame->refresh_frame_flags & (1 << s)))
365            continue;
366        ctx->slot[s] = frame;
367    }
368    frame->slots = frame->refresh_frame_flags;
369
370    if (!frame->refresh_frame_flags) {
371        err = vp9_raw_reorder_make_output(bsf, out, frame);
372        if (err < 0) {
373            av_log(bsf, AV_LOG_ERROR, "Failed to create output "
374                   "for transient frame.\n");
375            ctx->next_frame = NULL;
376            return AVERROR_INVALIDDATA;
377        }
378        if (!frame->needs_display) {
379            vp9_raw_reorder_frame_free(&frame);
380            ctx->next_frame = NULL;
381        }
382        return 0;
383    }
384
385    ctx->next_frame = NULL;
386    return AVERROR(EAGAIN);
387
388fail:
389    vp9_raw_reorder_frame_free(&frame);
390    return err;
391}
392
393static av_cold void vp9_raw_reorder_flush_close(AVBSFContext *bsf)
394{
395    VP9RawReorderContext *ctx = bsf->priv_data;
396
397    for (int s = 0; s < FRAME_SLOTS; s++)
398        vp9_raw_reorder_clear_slot(ctx, s);
399    vp9_raw_reorder_frame_free(&ctx->next_frame);
400    ctx->sequence = 0;
401}
402
403static const enum AVCodecID vp9_raw_reorder_codec_ids[] = {
404    AV_CODEC_ID_VP9, AV_CODEC_ID_NONE,
405};
406
407const FFBitStreamFilter ff_vp9_raw_reorder_bsf = {
408    .p.name         = "vp9_raw_reorder",
409    .p.codec_ids    = vp9_raw_reorder_codec_ids,
410    .priv_data_size = sizeof(VP9RawReorderContext),
411    .filter         = &vp9_raw_reorder_filter,
412    .flush          = &vp9_raw_reorder_flush_close,
413    .close          = &vp9_raw_reorder_flush_close,
414};
415