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
110 lines
2.7 KiB
C
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;
|
|
}
|