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