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