2 * This file is part of Libav.
4 * Libav 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.
9 * Libav 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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "libavutil/log.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
28 struct AVBSFInternal
{
33 void av_bsf_free(AVBSFContext
**pctx
)
41 if (ctx
->filter
->close
)
42 ctx
->filter
->close(ctx
);
43 if (ctx
->filter
->priv_class
&& ctx
->priv_data
)
44 av_opt_free(ctx
->priv_data
);
48 av_packet_free(&ctx
->internal
->buffer_pkt
);
49 av_freep(&ctx
->internal
);
50 av_freep(&ctx
->priv_data
);
52 avcodec_parameters_free(&ctx
->par_in
);
53 avcodec_parameters_free(&ctx
->par_out
);
58 static void *bsf_child_next(void *obj
, void *prev
)
60 AVBSFContext
*ctx
= obj
;
61 if (!prev
&& ctx
->filter
->priv_class
)
62 return ctx
->priv_data
;
66 static const AVClass bsf_class
= {
67 .class_name
= "AVBSFContext",
68 .item_name
= av_default_item_name
,
69 .version
= LIBAVUTIL_VERSION_INT
,
70 .child_next
= bsf_child_next
,
71 .child_class_next
= ff_bsf_child_class_next
,
74 const AVClass
*av_bsf_get_class(void)
79 int av_bsf_alloc(const AVBitStreamFilter
*filter
, AVBSFContext
**pctx
)
84 ctx
= av_mallocz(sizeof(*ctx
));
86 return AVERROR(ENOMEM
);
88 ctx
->av_class
= &bsf_class
;
91 ctx
->par_in
= avcodec_parameters_alloc();
92 ctx
->par_out
= avcodec_parameters_alloc();
93 if (!ctx
->par_in
|| !ctx
->par_out
) {
94 ret
= AVERROR(ENOMEM
);
98 ctx
->internal
= av_mallocz(sizeof(*ctx
->internal
));
100 ret
= AVERROR(ENOMEM
);
104 ctx
->internal
->buffer_pkt
= av_packet_alloc();
105 if (!ctx
->internal
->buffer_pkt
) {
106 ret
= AVERROR(ENOMEM
);
110 av_opt_set_defaults(ctx
);
112 /* allocate priv data and init private options */
113 if (filter
->priv_data_size
) {
114 ctx
->priv_data
= av_mallocz(filter
->priv_data_size
);
115 if (!ctx
->priv_data
) {
116 ret
= AVERROR(ENOMEM
);
119 if (filter
->priv_class
) {
120 *(const AVClass
**)ctx
->priv_data
= filter
->priv_class
;
121 av_opt_set_defaults(ctx
->priv_data
);
132 int av_bsf_init(AVBSFContext
*ctx
)
136 /* check that the codec is supported */
137 if (ctx
->filter
->codec_ids
) {
138 for (i
= 0; ctx
->filter
->codec_ids
[i
] != AV_CODEC_ID_NONE
; i
++)
139 if (ctx
->par_in
->codec_id
== ctx
->filter
->codec_ids
[i
])
141 if (ctx
->filter
->codec_ids
[i
] == AV_CODEC_ID_NONE
) {
142 const AVCodecDescriptor
*desc
= avcodec_descriptor_get(ctx
->par_in
->codec_id
);
143 av_log(ctx
, AV_LOG_ERROR
, "Codec '%s' (%d) is not supported by the "
144 "bitstream filter '%s'. Supported codecs are: ",
145 desc
? desc
->name
: "unknown", ctx
->par_in
->codec_id
, ctx
->filter
->name
);
146 for (i
= 0; ctx
->filter
->codec_ids
[i
] != AV_CODEC_ID_NONE
; i
++) {
147 desc
= avcodec_descriptor_get(ctx
->filter
->codec_ids
[i
]);
148 av_log(ctx
, AV_LOG_ERROR
, "%s (%d) ",
149 desc
? desc
->name
: "unknown", ctx
->filter
->codec_ids
[i
]);
151 av_log(ctx
, AV_LOG_ERROR
, "\n");
152 return AVERROR(EINVAL
);
156 /* initialize output parameters to be the same as input
157 * init below might overwrite that */
158 ret
= avcodec_parameters_copy(ctx
->par_out
, ctx
->par_in
);
162 ctx
->time_base_out
= ctx
->time_base_in
;
164 if (ctx
->filter
->init
) {
165 ret
= ctx
->filter
->init(ctx
);
173 void av_bsf_flush(AVBSFContext
*ctx
)
175 ctx
->internal
->eof
= 0;
177 av_packet_unref(ctx
->internal
->buffer_pkt
);
179 if (ctx
->filter
->flush
)
180 ctx
->filter
->flush(ctx
);
183 int av_bsf_send_packet(AVBSFContext
*ctx
, AVPacket
*pkt
)
185 if (!pkt
|| !pkt
->data
) {
186 ctx
->internal
->eof
= 1;
190 if (ctx
->internal
->eof
) {
191 av_log(ctx
, AV_LOG_ERROR
, "A non-NULL packet sent after an EOF.\n");
192 return AVERROR(EINVAL
);
195 if (ctx
->internal
->buffer_pkt
->data
||
196 ctx
->internal
->buffer_pkt
->side_data_elems
)
197 return AVERROR(EAGAIN
);
199 av_packet_move_ref(ctx
->internal
->buffer_pkt
, pkt
);
204 int av_bsf_receive_packet(AVBSFContext
*ctx
, AVPacket
*pkt
)
206 return ctx
->filter
->filter(ctx
, pkt
);
209 int ff_bsf_get_packet(AVBSFContext
*ctx
, AVPacket
**pkt
)
211 AVBSFInternal
*in
= ctx
->internal
;
217 if (!ctx
->internal
->buffer_pkt
->data
&&
218 !ctx
->internal
->buffer_pkt
->side_data_elems
)
219 return AVERROR(EAGAIN
);
221 tmp_pkt
= av_packet_alloc();
223 return AVERROR(ENOMEM
);
225 *pkt
= ctx
->internal
->buffer_pkt
;
226 ctx
->internal
->buffer_pkt
= tmp_pkt
;
231 int ff_bsf_get_packet_ref(AVBSFContext
*ctx
, AVPacket
*pkt
)
233 AVBSFInternal
*in
= ctx
->internal
;
238 if (!ctx
->internal
->buffer_pkt
->data
&&
239 !ctx
->internal
->buffer_pkt
->side_data_elems
)
240 return AVERROR(EAGAIN
);
242 av_packet_move_ref(pkt
, ctx
->internal
->buffer_pkt
);