diff options
Diffstat (limited to 'src/codec/ffmpeg')
| -rw-r--r-- | src/codec/ffmpeg/decoder.c | 34 | ||||
| -rw-r--r-- | src/codec/ffmpeg/demuxer.c | 13 | ||||
| -rw-r--r-- | src/codec/ffmpeg/resampler.c | 3 |
3 files changed, 26 insertions, 24 deletions
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c index 47bab44..6eff28b 100644 --- a/src/codec/ffmpeg/decoder.c +++ b/src/codec/ffmpeg/decoder.c @@ -60,6 +60,7 @@ static s32 get_buffer2(AVCodecContext *context, AVFrame *pic, s32 flags) return ret; } +// This is currently untested. static s32 init_hwframe_context(struct camu_ff_decoder *av, AVCodecContext *context, AVBufferRef *hw_device_context) { AVBufferRef *hw_frames_ref; @@ -83,9 +84,11 @@ static s32 init_hwframe_context(struct camu_ff_decoder *av, AVCodecContext *cont return ret; } + context->hw_frames_ctx = hw_frames_ref; + /* context->hw_frames_ctx = av_buffer_ref(hw_frames_ref); - av_buffer_unref(&hw_frames_ref); + */ return ret; } @@ -128,8 +131,6 @@ out: static s32 init_hwdevice_context(struct camu_ff_decoder *av, AVCodecContext *context) { - av->hw_context = NULL; - s32 ret = av_hwdevice_ctx_create(&av->hw_context, av->hw_device_type, NULL, NULL, 0); if (ret < 0) { log_error("Failed to create specified HW device."); @@ -208,12 +209,14 @@ static void close_internal(struct camu_ff_decoder *av) { if (av->codec_context) avcodec_free_context(&av->codec_context); #ifdef CAMU_FF_DECODER_HWACCEL - if (av->errored_hw_context) avcodec_free_context(&av->errored_hw_context); + if (av->hw_context) av_buffer_unref(&av->hw_context); al_array_free(av->supported_hw_codecs); al_array_free(av->supported_hw_devices); + if (av->errored_hw_context) avcodec_free_context(&av->errored_hw_context); #endif } +// If decoder_init() fails, we should still expect decoder_free() to by called which will run close_internal(). static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *renderer, struct camu_codec_stream *stream, void (*callback)(void *, struct camu_codec_frame *), void *userdata) { @@ -221,16 +224,17 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend av->codec_context = NULL; #ifdef CAMU_FF_DECODER_HWACCEL - av->errored_hw_context = NULL; + av->hw_context = NULL; al_array_init(av->supported_hw_codecs); al_array_init(av->supported_hw_devices); + av->errored_hw_context = NULL; #endif AVCodecParameters *codecpar = stream->av.stream->codecpar; const AVCodec *codec = avcodec_find_decoder(codecpar->codec_id); if (!codec) { log_error("Failed to find decoder."); - goto err; + return false; } bool is_video = codecpar->codec_type == AVMEDIA_TYPE_VIDEO && stream->duration > 0; @@ -253,6 +257,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend const AVCodec *hw_codec; al_array_foreach(av->supported_hw_codecs, i, hw_codec) { if (hw_codec->id == codecpar->codec_id) { + // @TODO: hw_codec's without a hwdevice (v4l2m2m, cuvid, amf). size_t length = al_strlen(hw_codec->wrapper_name); av->hw_device_type = hw_device_supported_by_name(av, hw_codec->wrapper_name, length); if (get_hwdevice_config(av, hw_codec, av->hw_device_type)) { @@ -270,7 +275,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend #endif if (!alloc_codec_context_internal(av, codec, codecpar)) { - goto err; + return false; } #ifdef CAMU_FF_DECODER_HWACCEL @@ -295,9 +300,10 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend if (av->hw_device_type == AV_HWDEVICE_TYPE_NONE) { #endif // FF_THREAD_FRAME or FF_THREAD_SLICE. - // Both modes can get choked on certain videos, sometimes SLICE can squeeze - // out a little more performance but a higher thread_count with FRAME seems - // like the safest default. + // Both modes can get choked on certain videos, higher thread_count with + // FRAME seems like the safest default. + // @TODO: Check ffmpeg source, SLICE + FRAME? + // - https://ffmpeg.org/ffmpeg-codecs.html#Codec-Options av->codec_context->thread_type = FF_THREAD_FRAME; av->codec_context->thread_count = av->thread_count; log_info("Using %i threads for decoder.", av->thread_count); @@ -310,7 +316,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend //av->codec_context->flags2 |= AV_CODEC_FLAG2_FAST; if (!open_avcodec_internal(av, codec)) { - goto err; + return false; } log_info("Codec: %s (%s) %lldkbps.", codec->name, @@ -321,15 +327,12 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend av->userdata = userdata; return true; -err: - close_internal(av); - return false; } static s32 send_packet(struct camu_ff_decoder *av, AVPacket *pkt) { s32 ret = avcodec_send_packet(av->codec_context, pkt); - if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { + if (ret < 0 && !(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)) { log_error("Error sending packet to the decoder (%s).", av_err2str(ret)); } return ret; @@ -361,6 +364,7 @@ static s32 receive_frames(struct camu_ff_decoder *av) al_free(frame); // Checking for EAGAIN should prevent an infinite loop. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) break; + log_error("Error receiving packet from the decoder (%s).", av_err2str(ret)); continue; } if (avframe->best_effort_timestamp == AV_NOPTS_VALUE) { diff --git a/src/codec/ffmpeg/demuxer.c b/src/codec/ffmpeg/demuxer.c index a8f1df7..e5aa2f6 100644 --- a/src/codec/ffmpeg/demuxer.c +++ b/src/codec/ffmpeg/demuxer.c @@ -31,7 +31,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl av->format_context = avformat_alloc_context(); if (!av->format_context) { log_error("Failed to create format context."); - goto err; + return false; } // This is meant to be the "block size" so, if I understand correctly, that would mean @@ -40,7 +40,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl av->io_context = avio_alloc_context(buf, al_page_size, 0, handle, camu_avio_read, NULL, camu_avio_seek); if (!av->io_context) { log_error("Failed to create custom io context."); - goto err; + return false; } if (!cch_handle_can_seek(handle)) { @@ -67,7 +67,7 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl if (ret < 0) { log_error("Failed to open input (%s).", av_err2str(ret)); av_dict_free(&opts); - goto err; + return false; } av_dict_free(&opts); @@ -75,12 +75,12 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl ret = avformat_find_stream_info(av->format_context, NULL); if (ret < 0) { log_error("Failed to find stream info (%s).", av_err2str(ret)); - goto err; + return false; } if (!av->format_context->nb_streams) { log_error("No streams found."); - goto err; + return false; } s64 default_duration = (av->format_context->duration < 0) ? 0 : av->format_context->duration; @@ -143,9 +143,6 @@ static bool ff_demuxer_init(struct camu_demuxer *demux, struct cch_handle *handl av->eof = false; return true; -err: - close_internal(av); - return false; } static bool subscribed_to_index(struct camu_demuxer *demux, s32 index) diff --git a/src/codec/ffmpeg/resampler.c b/src/codec/ffmpeg/resampler.c index b141681..fa868c8 100644 --- a/src/codec/ffmpeg/resampler.c +++ b/src/codec/ffmpeg/resampler.c @@ -8,8 +8,9 @@ static bool ff_resampler_init(struct camu_resampler *resamp, struct camu_resampler_format *fmt) { struct camu_ff_resampler *av = (struct camu_ff_resampler *)resamp; - al_assert(fmt->resampler_needed); + av->resample_context = NULL; + al_assert(fmt->resampler_needed); camu_audio_format_copy(&av->fmt, &fmt->req); SwrContext *swr = swr_alloc(); |