1
0
Fork 0
android_external_ffmpeg_codec2/ffmpeg_utils/ffmpeg_hwaccel.c
dvab-sarma 4695642189 minor modifications
minor modifications were added as a part of testing codec2 service on rockchip SoC. These mods are only for testing and wouldn't impact the functionality
2025-11-28 20:03:56 -06:00

110 lines
2.7 KiB
C

#define DEBUG_HWACCEL 0
#define LOG_TAG "HWACCEL"
#include <cutils/log.h>
#include <cutils/properties.h>
#include "ffmpeg_hwaccel.h"
int ffmpeg_hwaccel_init(AVCodecContext *avctx) {
if (!property_get_bool("persist.vendor.ffmpeg_codec2.v4l2.h265", 0))
return 0;
// Find codec information. At this point, AVCodecContext.codec may not be
// set yet, so retrieve our own version using AVCodecContext.codec_id.
const AVCodec* codec = avcodec_find_decoder(avctx->codec_id);
if (!codec) {
ALOGE("ffmpeg_hwaccel_init: codec not found = %d", avctx->codec_id);
return 0;
}
// Find a working HW configuration for this codec.
for (int i = 0;; i++) {
const AVCodecHWConfig* config = avcodec_get_hw_config(codec, i);
if (!config) {
// No more HW configs available.
break;
}
// Try to initialize HW device.
if (av_hwdevice_ctx_create(&avctx->hw_device_ctx, config->device_type, NULL, NULL, 0) < 0) {
// Initialization failed, skip this HW config.
ALOGD_IF(DEBUG_HWACCEL, "ffmpeg_hwaccel_init: failed to initialize HW device %s",
av_hwdevice_get_type_name(config->device_type));
continue;
}
// Use refcounted frames.
av_opt_set_int(avctx, "refcounted_frames", 1, 0);
// Don't use multithreading.
avctx->thread_count = 1;
// HW device created, stop here.
ALOGD("ffmpeg_hwaccel_init: %p [%s], hw device = %s", avctx, codec->name,
av_hwdevice_get_type_name(config->device_type));
break;
}
if (!avctx->hw_device_ctx) {
ALOGD("ffmpeg_hwaccel_init: no HW accel found for codec = %s", codec->name);
}
return 0;
}
void ffmpeg_hwaccel_deinit(AVCodecContext *avctx __unused) {
}
int ffmpeg_hwaccel_get_frame(AVCodecContext *avctx __unused, AVFrame *frame) {
if (!frame->hw_frames_ctx) {
// Frame is not hw-accel
return 0;
}
AVFrame* output;
int err;
output = av_frame_alloc();
if (!output) {
return AVERROR(ENOMEM);
}
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get((int)frame->format);
bool is_10bit = (desc && desc->comp[0].depth > 8);
if(is_10bit){
output->format = AV_PIX_FMT_NV15;
}
else {
output->format = AV_PIX_FMT_NV12;
}
err = av_hwframe_transfer_data(output, frame, 0);
if (err < 0) {
goto fail;
}
err = av_frame_copy_props(output, frame);
if (err < 0) {
goto fail;
}
av_frame_unref(frame);
av_frame_move_ref(frame, output);
av_frame_free(&output);
return 0;
fail:
av_frame_free(&output);
return err;
}