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
This commit is contained in:
parent
552a391396
commit
4695642189
6 changed files with 168 additions and 15 deletions
12
.vscode/settings.json
vendored
Normal file
12
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"bitset": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"span": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"__locale": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ cc_defaults {
|
||||||
"libswresample",
|
"libswresample",
|
||||||
"libswscale",
|
"libswscale",
|
||||||
"libutils",
|
"libutils",
|
||||||
|
"libyuv",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "C2FFMPEGVideoDecodeComponent.h"
|
#include "C2FFMPEGVideoDecodeComponent.h"
|
||||||
#include "ffmpeg_hwaccel.h"
|
#include "ffmpeg_hwaccel.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG_FRAMES 0
|
#define DEBUG_FRAMES 0
|
||||||
#define DEBUG_WORKQUEUE 0
|
#define DEBUG_WORKQUEUE 0
|
||||||
#define DEBUG_EXTRADATA 0
|
#define DEBUG_EXTRADATA 0
|
||||||
|
|
@ -282,6 +283,95 @@ c2_status_t C2FFMPEGVideoDecodeComponent::getOutputBuffer(C2GraphicView* outBuff
|
||||||
return C2_OK;
|
return C2_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*NOTE - This function was added to test the performance difference between Libyuv vs sws_scale.
|
||||||
|
Since the tests are not completed. Keeping it here.*/
|
||||||
|
// c2_status_t C2FFMPEGVideoDecodeComponent::getOutputBuffer(C2GraphicView* outBuffer) {
|
||||||
|
// // output planes
|
||||||
|
// uint8_t* dst_y = outBuffer->data()[C2PlanarLayout::PLANE_Y];
|
||||||
|
// uint8_t* dst_u = outBuffer->data()[C2PlanarLayout::PLANE_U];
|
||||||
|
// uint8_t* dst_v = outBuffer->data()[C2PlanarLayout::PLANE_V];
|
||||||
|
|
||||||
|
// C2PlanarLayout layout = outBuffer->layout();
|
||||||
|
// int dst_stride_y = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
|
||||||
|
// int dst_stride_u = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
|
||||||
|
// int dst_stride_v = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
|
||||||
|
|
||||||
|
// // validate frame pointer
|
||||||
|
// if (!mFrame) {
|
||||||
|
// ALOGE("getOutputBuffer: invalid frame");
|
||||||
|
// return C2_BAD_STATE;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const int width = mFrame->width;
|
||||||
|
// const int height = mFrame->height;
|
||||||
|
|
||||||
|
|
||||||
|
// if (mFrame->format == AV_PIX_FMT_NV12) {
|
||||||
|
// //ALOGE("getOutputBuffer: libyuv: initiated");
|
||||||
|
// const uint8_t* src_y = mFrame->data[0];
|
||||||
|
// const uint8_t* src_uv = mFrame->data[1];
|
||||||
|
// int src_stride_y = mFrame->linesize[0];
|
||||||
|
// int src_stride_uv = mFrame->linesize[1];
|
||||||
|
|
||||||
|
// if (src_y && src_uv) {
|
||||||
|
// // Use libyuv for fast NV12->I420 conversion (hardware decoded only)
|
||||||
|
// // NV12ToI420 handles interleaved UV conversion efficiently
|
||||||
|
// int ret = libyuv::NV12ToI420(
|
||||||
|
// src_y, src_stride_y,
|
||||||
|
// src_uv, src_stride_uv,
|
||||||
|
// dst_y, dst_stride_y,
|
||||||
|
// dst_u, dst_stride_u,
|
||||||
|
// dst_v, dst_stride_v,
|
||||||
|
// width, height);
|
||||||
|
|
||||||
|
// if (ret == 0) {
|
||||||
|
// //ALOGE("getOutputBuffer: libyuv: NV12->I420 (hw decode) conversion successful");
|
||||||
|
// return C2_OK;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //ALOGE("getOutputBuffer: libyuv: NV12->I420 conversion failed with ret: %d", ret);
|
||||||
|
// } else {
|
||||||
|
// //ALOGE("getOutputBuffer: libyuv: invalid source buffers for NV12");
|
||||||
|
// }
|
||||||
|
// // Fall through to sws fallback only if NV12 conversion failed
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Fallback: use sws_scale for software decoded formats (YUV422, YUV420P) or if NV12 conversion failed
|
||||||
|
// // Fallback: use sws_scale for other formats or if libyuv fails
|
||||||
|
// uint8_t* data[4];
|
||||||
|
// int linesize[4];
|
||||||
|
// data[0] = outBuffer->data()[C2PlanarLayout::PLANE_Y];
|
||||||
|
// data[1] = outBuffer->data()[C2PlanarLayout::PLANE_U];
|
||||||
|
// data[2] = outBuffer->data()[C2PlanarLayout::PLANE_V];
|
||||||
|
// //data[3] = NULL;
|
||||||
|
// linesize[0] = layout.planes[C2PlanarLayout::PLANE_Y].rowInc;
|
||||||
|
// linesize[1] = layout.planes[C2PlanarLayout::PLANE_U].rowInc;
|
||||||
|
// linesize[2] = layout.planes[C2PlanarLayout::PLANE_V].rowInc;
|
||||||
|
// //linesize[3] = 0;
|
||||||
|
|
||||||
|
// struct SwsContext* currentImgConvertCtx = mImgConvertCtx;
|
||||||
|
// mImgConvertCtx = sws_getCachedContext(
|
||||||
|
// currentImgConvertCtx,
|
||||||
|
// width, height, (AVPixelFormat)mFrame->format,
|
||||||
|
// width, height, AV_PIX_FMT_YUV420P,
|
||||||
|
// SWS_BICUBIC, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
// if (mImgConvertCtx && mImgConvertCtx != currentImgConvertCtx) {
|
||||||
|
// ALOGD("getOutputBuffer: created video converter - %s => %s",
|
||||||
|
// av_get_pix_fmt_name((AVPixelFormat)mFrame->format),
|
||||||
|
// av_get_pix_fmt_name(AV_PIX_FMT_YUV420P));
|
||||||
|
// } else if (!mImgConvertCtx) {
|
||||||
|
// ALOGE("getOutputBuffer: cannot initialize the conversion context");
|
||||||
|
// return C2_NO_MEMORY;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sws_scale(mImgConvertCtx, mFrame->data, mFrame->linesize,
|
||||||
|
// 0, height, data, linesize);
|
||||||
|
|
||||||
|
// ALOGD("getOutputBuffer: sws_scale conversion complete");
|
||||||
|
// return C2_OK;
|
||||||
|
// }
|
||||||
|
|
||||||
static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
|
static void fillEmptyWork(const std::unique_ptr<C2Work>& work) {
|
||||||
work->worklets.front()->output.flags =
|
work->worklets.front()->output.flags =
|
||||||
(C2FrameData::flags_t)(work->input.flags & C2FrameData::FLAG_END_OF_STREAM);
|
(C2FrameData::flags_t)(work->input.flags & C2FrameData::FLAG_END_OF_STREAM);
|
||||||
|
|
@ -306,17 +396,38 @@ void C2FFMPEGVideoDecodeComponent::pushPendingWork(const std::unique_ptr<C2Work>
|
||||||
uint32_t newOutputDelay = outputDelay;
|
uint32_t newOutputDelay = outputDelay;
|
||||||
std::vector<std::unique_ptr<C2Param>> configUpdate;
|
std::vector<std::unique_ptr<C2Param>> configUpdate;
|
||||||
|
|
||||||
|
uint32_t frameSize = mFrame->height * mFrame->width;
|
||||||
|
|
||||||
switch (mCtx->codec_id) {
|
switch (mCtx->codec_id) {
|
||||||
case AV_CODEC_ID_HEVC:
|
case AV_CODEC_ID_HEVC:
|
||||||
case AV_CODEC_ID_H264:
|
case AV_CODEC_ID_H264:
|
||||||
// Increase output delay step-wise.
|
|
||||||
if (outputDelay >= 18u) {
|
if(frameSize <= RKVDEC_1080P_PIXELS){
|
||||||
newOutputDelay = 34u;
|
if (outputDelay >= 8u){
|
||||||
} else if (outputDelay >= 8u) {
|
newOutputDelay = 16u;
|
||||||
newOutputDelay = 18u;
|
}
|
||||||
} else {
|
else {
|
||||||
newOutputDelay = 8u;
|
newOutputDelay = 8u;
|
||||||
|
}
|
||||||
|
} else if (frameSize <= RKVDEC_4K_PIXELS){
|
||||||
|
if(outputDelay >= 16u){
|
||||||
|
newOutputDelay = 32u;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newOutputDelay = 16u;
|
||||||
|
}
|
||||||
|
} else if (frameSize <= RKVDEC_8K_PIXELS){
|
||||||
|
if (outputDelay >= 32u){
|
||||||
|
newOutputDelay = 64u;
|
||||||
|
} else if (outputDelay >= 16u) {
|
||||||
|
newOutputDelay = 32u;
|
||||||
|
} else {
|
||||||
|
newOutputDelay = 16u;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// Other codecs use constant output delay.
|
// Other codecs use constant output delay.
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,12 @@
|
||||||
#include "C2FFMPEGCommon.h"
|
#include "C2FFMPEGCommon.h"
|
||||||
#include "C2FFMPEGVideoDecodeInterface.h"
|
#include "C2FFMPEGVideoDecodeInterface.h"
|
||||||
|
|
||||||
|
#include "libyuv/convert.h"
|
||||||
|
|
||||||
|
#define RKVDEC_1080P_PIXELS (1920 * 1080)
|
||||||
|
#define RKVDEC_4K_PIXELS (4096 * 2304)
|
||||||
|
#define RKVDEC_8K_PIXELS (7680 * 4320)
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
typedef std::pair<uint64_t, uint64_t> PendingWork;
|
typedef std::pair<uint64_t, uint64_t> PendingWork;
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@
|
||||||
#include <cutils/properties.h>
|
#include <cutils/properties.h>
|
||||||
|
|
||||||
#include "ffmpeg_hwaccel.h"
|
#include "ffmpeg_hwaccel.h"
|
||||||
#include "libavutil/opt.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ffmpeg_hwaccel_init(AVCodecContext *avctx) {
|
int ffmpeg_hwaccel_init(AVCodecContext *avctx) {
|
||||||
if (avctx->codec_id != AV_CODEC_ID_HEVC || !property_get_bool("persist.vendor.ffmpeg_codec2.v4l2.h265", 0))
|
if (!property_get_bool("persist.vendor.ffmpeg_codec2.v4l2.h265", 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Find codec information. At this point, AVCodecContext.codec may not be
|
// Find codec information. At this point, AVCodecContext.codec may not be
|
||||||
|
|
@ -69,19 +71,30 @@ int ffmpeg_hwaccel_get_frame(AVCodecContext *avctx __unused, AVFrame *frame) {
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
output->format = AV_PIX_FMT_NV12;
|
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);
|
err = av_hwframe_transfer_data(output, frame, 0);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ALOGE("ffmpeg_hwaccel_get_frame failed to transfer data: %s (%08x)",
|
|
||||||
av_err2str(err), err);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = av_frame_copy_props(output, frame);
|
err = av_frame_copy_props(output, frame);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ALOGE("ffmpeg_hwaccel_get_frame failed to copy frame properties: %s (%08x)",
|
|
||||||
av_err2str(err), err);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,21 @@
|
||||||
#ifndef FFMPEG_HWACCEL_H
|
#ifndef FFMPEG_HWACCEL_H
|
||||||
#define FFMPEG_HWACCEL_H
|
#define FFMPEG_HWACCEL_H
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libavcodec/avcodec.h"
|
#include "libavcodec/avcodec.h"
|
||||||
|
#include "libavformat/avformat.h"
|
||||||
|
#include "libswscale/swscale.h"
|
||||||
|
#include "libswresample/swresample.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
|
#include "libavutil/pixdesc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern int ffmpeg_hwaccel_init(AVCodecContext *avctx);
|
extern int ffmpeg_hwaccel_init(AVCodecContext *avctx);
|
||||||
extern void ffmpeg_hwaccel_deinit(AVCodecContext *avctx);
|
extern void ffmpeg_hwaccel_deinit(AVCodecContext *avctx);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue