#include "decoder.h" #include int decoder_init (struct Decoder *decoder, const AVCodecParameters *codecpar, AVDictionary **opts) { int err; AVCodecContext *avctx; const AVCodec *codec; if ((codec = avcodec_find_decoder(codecpar->codec_id)) == NULL) return AVERROR_DECODER_NOT_FOUND; /* NOTE: parameter 'codec' might be redundant here due to the next, more * featuref-full call to avcodec_parameters_to_context. */ if ((avctx = avcodec_alloc_context3(codec)) == NULL) return AVERROR(ENOMEM); /* NOTE: After reading libavcodec's code, this * error code *could* misrepresent the actual * error, but ffmpeg won't tell us what it is * anyway so oh well. */ if ((err = avcodec_parameters_to_context(avctx, codecpar)) < 0) goto error; if ((err = avcodec_open2(avctx, codec, opts)) < 0) goto error; /* Free previous context (no-op if avctx == NULL) and swap it with the new * one. This allows the previous one to be left untouched in case of error, * which is generally a nice thing to do in your code. */ avcodec_free_context(&decoder->avctx); decoder->avctx = avctx; return 0; error: avcodec_free_context(&avctx); return err; } int decoder_init_for_stream (struct Decoder *decoder, const AVStream *stream, AVDictionary **opts) { return decoder_init(decoder, stream->codecpar, opts); } int decoder_send (struct Decoder *decoder, const AVPacket *pkt) { return avcodec_send_packet(decoder->avctx, pkt); } int decoder_convert (struct Decoder *decoder, AVFrame *out) { return avcodec_receive_frame(decoder->avctx, out); } void decoder_free (struct Decoder *decoder) { if (decoder == NULL) return; avcodec_free_context(&decoder->avctx); }