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/bsf/h264_redundant_pps.c | |
parent | e0da916b8f5b079a4865eef7f64863f50785463d (diff) | |
download | ffmpeg-887a7817b6671cd5dce9ba9bf97b88afdbbe7137.tar.gz |
lavc: move bitstream filters into bsf/ subdir
Diffstat (limited to 'libavcodec/bsf/h264_redundant_pps.c')
-rw-r--r-- | libavcodec/bsf/h264_redundant_pps.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/libavcodec/bsf/h264_redundant_pps.c b/libavcodec/bsf/h264_redundant_pps.c new file mode 100644 index 0000000000..df9a88a705 --- /dev/null +++ b/libavcodec/bsf/h264_redundant_pps.c @@ -0,0 +1,126 @@ +/* + * 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 <inttypes.h> + +#include "libavutil/log.h" + +#include "bsf.h" +#include "bsf_internal.h" +#include "cbs.h" +#include "cbs_bsf.h" +#include "cbs_h264.h" +#include "codec_id.h" +#include "h264.h" +#include "packet.h" + +#define NEW_GLOBAL_PIC_INIT_QP 26 + +typedef struct H264RedundantPPSContext { + CBSBSFContext common; +} H264RedundantPPSContext; + + +static int h264_redundant_pps_fixup_pps(H264RedundantPPSContext *ctx, + CodedBitstreamUnit *unit) +{ + H264RawPPS *pps; + int err; + + // The changes we are about to perform affect the parsing process, + // so we must make sure that the PPS is writable, otherwise the + // parsing of future slices will be incorrect and even raise errors. + err = ff_cbs_make_unit_writable(ctx->common.input, unit); + if (err < 0) + return err; + pps = unit->content; + + // Overwrite pic_init_qp with the global value. + pps->pic_init_qp_minus26 = NEW_GLOBAL_PIC_INIT_QP - 26; + + // Some PPSs have this set, so it must be set in all of them. + // (Slices which do not use such a PPS on input will still have + // *_weight_l*flag as zero and therefore write equivalently.) + pps->weighted_pred_flag = 1; + + return 0; +} + +static int h264_redundant_pps_fixup_slice(H264RedundantPPSContext *ctx, + H264RawSliceHeader *slice) +{ + const CodedBitstreamH264Context *const in = ctx->common.input->priv_data; + const H264RawPPS *const pps = in->pps[slice->pic_parameter_set_id]; + + // We modified the PPS's qp value, now offset this by applying + // the negative offset to the slices. + slice->slice_qp_delta += pps->pic_init_qp_minus26 + - (NEW_GLOBAL_PIC_INIT_QP - 26); + + return 0; +} + +static int h264_redundant_pps_update_fragment(AVBSFContext *bsf, + AVPacket *pkt, + CodedBitstreamFragment *au) +{ + H264RedundantPPSContext *ctx = bsf->priv_data; + int err, i; + + for (i = 0; i < au->nb_units; i++) { + CodedBitstreamUnit *nal = &au->units[i]; + + if (nal->type == H264_NAL_PPS) { + err = h264_redundant_pps_fixup_pps(ctx, nal); + if (err < 0) + return err; + } + if (nal->type == H264_NAL_SLICE || + nal->type == H264_NAL_IDR_SLICE) { + H264RawSlice *slice = nal->content; + h264_redundant_pps_fixup_slice(ctx, &slice->header); + } + } + + return 0; +} + +static const CBSBSFType h264_redundant_pps_type = { + .codec_id = AV_CODEC_ID_H264, + .fragment_name = "access unit", + .unit_name = "NAL unit", + .update_fragment = &h264_redundant_pps_update_fragment, +}; + +static int h264_redundant_pps_init(AVBSFContext *bsf) +{ + return ff_cbs_bsf_generic_init(bsf, &h264_redundant_pps_type); +} + +static const enum AVCodecID h264_redundant_pps_codec_ids[] = { + AV_CODEC_ID_H264, AV_CODEC_ID_NONE, +}; + +const FFBitStreamFilter ff_h264_redundant_pps_bsf = { + .p.name = "h264_redundant_pps", + .p.codec_ids = h264_redundant_pps_codec_ids, + .priv_data_size = sizeof(H264RedundantPPSContext), + .init = &h264_redundant_pps_init, + .close = &ff_cbs_bsf_generic_close, + .filter = &ff_cbs_bsf_generic_filter, +}; |