diff options
author | Anton Khirnov <anton@khirnov.net> | 2024-01-26 11:36:02 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2024-01-29 18:40:14 +0100 |
commit | 887a7817b6671cd5dce9ba9bf97b88afdbbe7137 (patch) | |
tree | a59813cb3c9622e92932f5117278277c40e9bc53 /libavcodec/vp9_raw_reorder_bsf.c | |
parent | e0da916b8f5b079a4865eef7f64863f50785463d (diff) | |
download | ffmpeg-887a7817b6671cd5dce9ba9bf97b88afdbbe7137.tar.gz |
lavc: move bitstream filters into bsf/ subdir
Diffstat (limited to 'libavcodec/vp9_raw_reorder_bsf.c')
-rw-r--r-- | libavcodec/vp9_raw_reorder_bsf.c | 414 |
1 files changed, 0 insertions, 414 deletions
diff --git a/libavcodec/vp9_raw_reorder_bsf.c b/libavcodec/vp9_raw_reorder_bsf.c deleted file mode 100644 index d36093316c..0000000000 --- a/libavcodec/vp9_raw_reorder_bsf.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/avassert.h" -#include "libavutil/intmath.h" -#include "libavutil/log.h" -#include "libavutil/mem.h" - -#include "bsf.h" -#include "bsf_internal.h" -#include "get_bits.h" -#include "put_bits.h" - -#define FRAME_SLOTS 8 - -typedef struct VP9RawReorderFrame { - AVPacket *packet; - int needs_output; - int needs_display; - - int64_t pts; - int64_t sequence; - unsigned int slots; - - unsigned int profile; - - unsigned int show_existing_frame; - unsigned int frame_to_show; - - unsigned int frame_type; - unsigned int show_frame; - unsigned int refresh_frame_flags; -} VP9RawReorderFrame; - -typedef struct VP9RawReorderContext { - int64_t sequence; - VP9RawReorderFrame *slot[FRAME_SLOTS]; - VP9RawReorderFrame *next_frame; -} VP9RawReorderContext; - -static void vp9_raw_reorder_frame_free(VP9RawReorderFrame **frame) -{ - if (*frame) - av_packet_free(&(*frame)->packet); - av_freep(frame); -} - -static void vp9_raw_reorder_clear_slot(VP9RawReorderContext *ctx, int s) -{ - if (ctx->slot[s]) { - ctx->slot[s]->slots &= ~(1 << s); - if (ctx->slot[s]->slots == 0) - vp9_raw_reorder_frame_free(&ctx->slot[s]); - else - ctx->slot[s] = NULL; - } -} - -static int vp9_raw_reorder_frame_parse(AVBSFContext *bsf, VP9RawReorderFrame *frame) -{ - GetBitContext bc; - int err; - - unsigned int frame_marker; - unsigned int profile_low_bit, profile_high_bit, reserved_zero; - unsigned int error_resilient_mode; - unsigned int frame_sync_code; - - err = init_get_bits(&bc, frame->packet->data, 8 * frame->packet->size); - if (err) - return err; - - frame_marker = get_bits(&bc, 2); - if (frame_marker != 2) { - av_log(bsf, AV_LOG_ERROR, "Invalid frame marker: %u.\n", - frame_marker); - return AVERROR_INVALIDDATA; - } - - profile_low_bit = get_bits1(&bc); - profile_high_bit = get_bits1(&bc); - frame->profile = (profile_high_bit << 1) | profile_low_bit; - if (frame->profile == 3) { - reserved_zero = get_bits1(&bc); - if (reserved_zero != 0) { - av_log(bsf, AV_LOG_ERROR, "Profile reserved_zero bit set: " - "unsupported profile or invalid bitstream.\n"); - return AVERROR_INVALIDDATA; - } - } - - frame->show_existing_frame = get_bits1(&bc); - if (frame->show_existing_frame) { - frame->frame_to_show = get_bits(&bc, 3); - return 0; - } - - frame->frame_type = get_bits1(&bc); - frame->show_frame = get_bits1(&bc); - error_resilient_mode = get_bits1(&bc); - - if (frame->frame_type == 0) { - frame_sync_code = get_bits(&bc, 24); - if (frame_sync_code != 0x498342) { - av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: %06x.\n", - frame_sync_code); - return AVERROR_INVALIDDATA; - } - frame->refresh_frame_flags = 0xff; - } else { - unsigned int intra_only; - - if (frame->show_frame == 0) - intra_only = get_bits1(&bc); - else - intra_only = 0; - if (error_resilient_mode == 0) { - // reset_frame_context - skip_bits(&bc, 2); - } - if (intra_only) { - frame_sync_code = get_bits(&bc, 24); - if (frame_sync_code != 0x498342) { - av_log(bsf, AV_LOG_ERROR, "Invalid frame sync code: " - "%06x.\n", frame_sync_code); - return AVERROR_INVALIDDATA; - } - if (frame->profile > 0) { - unsigned int color_space; - if (frame->profile >= 2) { - // ten_or_twelve_bit - skip_bits(&bc, 1); - } - color_space = get_bits(&bc, 3); - if (color_space != 7 /* CS_RGB */) { - // color_range - skip_bits(&bc, 1); - if (frame->profile == 1 || frame->profile == 3) { - // subsampling - skip_bits(&bc, 3); - } - } else { - if (frame->profile == 1 || frame->profile == 3) - skip_bits(&bc, 1); - } - } - frame->refresh_frame_flags = get_bits(&bc, 8); - } else { - frame->refresh_frame_flags = get_bits(&bc, 8); - } - } - - return 0; -} - -static int vp9_raw_reorder_make_output(AVBSFContext *bsf, - AVPacket *out, - VP9RawReorderFrame *last_frame) -{ - VP9RawReorderContext *ctx = bsf->priv_data; - VP9RawReorderFrame *next_output = last_frame, - *next_display = last_frame, *frame; - int s, err; - - for (s = 0; s < FRAME_SLOTS; s++) { - frame = ctx->slot[s]; - if (!frame) - continue; - if (frame->needs_output && (!next_output || - frame->sequence < next_output->sequence)) - next_output = frame; - if (frame->needs_display && (!next_display || - frame->pts < next_display->pts)) - next_display = frame; - } - - if (!next_output && !next_display) - return AVERROR_EOF; - - if (!next_display || (next_output && - next_output->sequence < next_display->sequence)) - frame = next_output; - else - frame = next_display; - - if (frame->needs_output && frame->needs_display && - next_output == next_display) { - av_log(bsf, AV_LOG_DEBUG, "Output and display frame " - "%"PRId64" (%"PRId64") in order.\n", - frame->sequence, frame->pts); - - av_packet_move_ref(out, frame->packet); - - frame->needs_output = frame->needs_display = 0; - } else if (frame->needs_output) { - if (frame->needs_display) { - av_log(bsf, AV_LOG_DEBUG, "Output frame %"PRId64" " - "(%"PRId64") for later display.\n", - frame->sequence, frame->pts); - } else { - av_log(bsf, AV_LOG_DEBUG, "Output unshown frame " - "%"PRId64" (%"PRId64") to keep order.\n", - frame->sequence, frame->pts); - } - - av_packet_move_ref(out, frame->packet); - out->pts = out->dts; - - frame->needs_output = 0; - } else { - PutBitContext pb; - - av_assert0(!frame->needs_output && frame->needs_display); - - if (frame->slots == 0) { - av_log(bsf, AV_LOG_ERROR, "Attempting to display frame " - "which is no longer available?\n"); - frame->needs_display = 0; - return AVERROR_INVALIDDATA; - } - - s = ff_ctz(frame->slots); - av_assert0(s < FRAME_SLOTS); - - av_log(bsf, AV_LOG_DEBUG, "Display frame %"PRId64" " - "(%"PRId64") from slot %d.\n", - frame->sequence, frame->pts, s); - - err = av_new_packet(out, 2); - if (err < 0) - return err; - - init_put_bits(&pb, out->data, 2); - - // frame_marker - put_bits(&pb, 2, 2); - // profile_low_bit - put_bits(&pb, 1, frame->profile & 1); - // profile_high_bit - put_bits(&pb, 1, (frame->profile >> 1) & 1); - if (frame->profile == 3) { - // reserved_zero - put_bits(&pb, 1, 0); - } - // show_existing_frame - put_bits(&pb, 1, 1); - // frame_to_show_map_idx - put_bits(&pb, 3, s); - - while (put_bits_count(&pb) < 16) - put_bits(&pb, 1, 0); - - flush_put_bits(&pb); - out->pts = out->dts = frame->pts; - - frame->needs_display = 0; - } - - return 0; -} - -static int vp9_raw_reorder_filter(AVBSFContext *bsf, AVPacket *out) -{ - VP9RawReorderContext *ctx = bsf->priv_data; - VP9RawReorderFrame *frame; - AVPacket *in; - int err, s; - - if (ctx->next_frame) { - frame = ctx->next_frame; - - } else { - err = ff_bsf_get_packet(bsf, &in); - if (err < 0) { - if (err == AVERROR_EOF) - return vp9_raw_reorder_make_output(bsf, out, NULL); - return err; - } - - if (!in->size) { - av_packet_free(&in); - return AVERROR_INVALIDDATA; - } - - if ((in->data[in->size - 1] & 0xe0) == 0xc0) { - av_log(bsf, AV_LOG_ERROR, "Input in superframes is not " - "supported.\n"); - av_packet_free(&in); - return AVERROR(ENOSYS); - } - - frame = av_mallocz(sizeof(*frame)); - if (!frame) { - av_packet_free(&in); - return AVERROR(ENOMEM); - } - - frame->packet = in; - frame->pts = in->pts; - frame->sequence = ++ctx->sequence; - err = vp9_raw_reorder_frame_parse(bsf, frame); - if (err) { - av_log(bsf, AV_LOG_ERROR, "Failed to parse input " - "frame: %d.\n", err); - goto fail; - } - - frame->needs_output = 1; - frame->needs_display = frame->pts != AV_NOPTS_VALUE; - - if (frame->show_existing_frame) - av_log(bsf, AV_LOG_DEBUG, "Show frame %"PRId64" " - "(%"PRId64"): show %u.\n", frame->sequence, - frame->pts, frame->frame_to_show); - else - av_log(bsf, AV_LOG_DEBUG, "New frame %"PRId64" " - "(%"PRId64"): type %u show %u refresh %02x.\n", - frame->sequence, frame->pts, frame->frame_type, - frame->show_frame, frame->refresh_frame_flags); - - ctx->next_frame = frame; - } - - for (s = 0; s < FRAME_SLOTS; s++) { - if (!(frame->refresh_frame_flags & (1 << s))) - continue; - if (ctx->slot[s] && ctx->slot[s]->needs_display && - ctx->slot[s]->slots == (1 << s)) { - // We are overwriting this slot, which is last reference - // to the frame previously present in it. In order to be - // a valid stream, that frame must already have been - // displayed before the pts of the current frame. - err = vp9_raw_reorder_make_output(bsf, out, ctx->slot[s]); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to create " - "output overwriting slot %d: %d.\n", - s, err); - // Clear the slot anyway, so we don't end up - // in an infinite loop. - vp9_raw_reorder_clear_slot(ctx, s); - return AVERROR_INVALIDDATA; - } - return 0; - } - vp9_raw_reorder_clear_slot(ctx, s); - } - - for (s = 0; s < FRAME_SLOTS; s++) { - if (!(frame->refresh_frame_flags & (1 << s))) - continue; - ctx->slot[s] = frame; - } - frame->slots = frame->refresh_frame_flags; - - if (!frame->refresh_frame_flags) { - err = vp9_raw_reorder_make_output(bsf, out, frame); - if (err < 0) { - av_log(bsf, AV_LOG_ERROR, "Failed to create output " - "for transient frame.\n"); - ctx->next_frame = NULL; - return AVERROR_INVALIDDATA; - } - if (!frame->needs_display) { - vp9_raw_reorder_frame_free(&frame); - ctx->next_frame = NULL; - } - return 0; - } - - ctx->next_frame = NULL; - return AVERROR(EAGAIN); - -fail: - vp9_raw_reorder_frame_free(&frame); - return err; -} - -static av_cold void vp9_raw_reorder_flush_close(AVBSFContext *bsf) -{ - VP9RawReorderContext *ctx = bsf->priv_data; - - for (int s = 0; s < FRAME_SLOTS; s++) - vp9_raw_reorder_clear_slot(ctx, s); - vp9_raw_reorder_frame_free(&ctx->next_frame); - ctx->sequence = 0; -} - -static const enum AVCodecID vp9_raw_reorder_codec_ids[] = { - AV_CODEC_ID_VP9, AV_CODEC_ID_NONE, -}; - -const FFBitStreamFilter ff_vp9_raw_reorder_bsf = { - .p.name = "vp9_raw_reorder", - .p.codec_ids = vp9_raw_reorder_codec_ids, - .priv_data_size = sizeof(VP9RawReorderContext), - .filter = &vp9_raw_reorder_filter, - .flush = &vp9_raw_reorder_flush_close, - .close = &vp9_raw_reorder_flush_close, -}; |