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