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 "bsf.h" 20#include "bsf_internal.h" 21#include "cbs_bsf.h" 22 23static int cbs_bsf_update_side_data(AVBSFContext *bsf, AVPacket *pkt) 24{ 25 CBSBSFContext *ctx = bsf->priv_data; 26 CodedBitstreamFragment *frag = &ctx->fragment; 27 uint8_t *side_data; 28 int err; 29 30 if (!av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) 31 return 0; 32 33 err = ff_cbs_read_packet_side_data(ctx->input, frag, pkt); 34 if (err < 0) { 35 av_log(bsf, AV_LOG_ERROR, 36 "Failed to read extradata from packet side data.\n"); 37 return err; 38 } 39 40 err = ctx->type->update_fragment(bsf, NULL, frag); 41 if (err < 0) 42 return err; 43 44 err = ff_cbs_write_fragment_data(ctx->output, frag); 45 if (err < 0) { 46 av_log(bsf, AV_LOG_ERROR, 47 "Failed to write extradata into packet side data.\n"); 48 return err; 49 } 50 51 side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, 52 frag->data_size); 53 if (!side_data) 54 return AVERROR(ENOMEM); 55 memcpy(side_data, frag->data, frag->data_size); 56 57 ff_cbs_fragment_reset(frag); 58 return 0; 59} 60 61int ff_cbs_bsf_generic_filter(AVBSFContext *bsf, AVPacket *pkt) 62{ 63 CBSBSFContext *ctx = bsf->priv_data; 64 CodedBitstreamFragment *frag = &ctx->fragment; 65 int err; 66 67 err = ff_bsf_get_packet_ref(bsf, pkt); 68 if (err < 0) 69 return err; 70 71 err = cbs_bsf_update_side_data(bsf, pkt); 72 if (err < 0) 73 goto fail; 74 75 err = ff_cbs_read_packet(ctx->input, frag, pkt); 76 if (err < 0) { 77 av_log(bsf, AV_LOG_ERROR, "Failed to read %s from packet.\n", 78 ctx->type->fragment_name); 79 goto fail; 80 } 81 82 if (frag->nb_units == 0) { 83 av_log(bsf, AV_LOG_ERROR, "No %s found in packet.\n", 84 ctx->type->unit_name); 85 err = AVERROR_INVALIDDATA; 86 goto fail; 87 } 88 89 err = ctx->type->update_fragment(bsf, pkt, frag); 90 if (err < 0) 91 goto fail; 92 93 err = ff_cbs_write_packet(ctx->output, pkt, frag); 94 if (err < 0) { 95 av_log(bsf, AV_LOG_ERROR, "Failed to write %s into packet.\n", 96 ctx->type->fragment_name); 97 goto fail; 98 } 99 100 err = 0; 101fail: 102 ff_cbs_fragment_reset(frag); 103 104 if (err < 0) 105 av_packet_unref(pkt); 106 107 return err; 108} 109 110int ff_cbs_bsf_generic_init(AVBSFContext *bsf, const CBSBSFType *type) 111{ 112 CBSBSFContext *ctx = bsf->priv_data; 113 CodedBitstreamFragment *frag = &ctx->fragment; 114 int err; 115 116 ctx->type = type; 117 118 err = ff_cbs_init(&ctx->input, type->codec_id, bsf); 119 if (err < 0) 120 return err; 121 122 err = ff_cbs_init(&ctx->output, type->codec_id, bsf); 123 if (err < 0) 124 return err; 125 126 if (bsf->par_in->extradata) { 127 err = ff_cbs_read_extradata(ctx->input, frag, bsf->par_in); 128 if (err < 0) { 129 av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n"); 130 goto fail; 131 } 132 133 err = type->update_fragment(bsf, NULL, frag); 134 if (err < 0) 135 goto fail; 136 137 err = ff_cbs_write_extradata(ctx->output, bsf->par_out, frag); 138 if (err < 0) { 139 av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n"); 140 goto fail; 141 } 142 } 143 144 err = 0; 145fail: 146 ff_cbs_fragment_reset(frag); 147 return err; 148} 149 150void ff_cbs_bsf_generic_close(AVBSFContext *bsf) 151{ 152 CBSBSFContext *ctx = bsf->priv_data; 153 154 ff_cbs_fragment_free(&ctx->fragment); 155 ff_cbs_close(&ctx->input); 156 ff_cbs_close(&ctx->output); 157} 158