1
0
Fork 0

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:
dvab-sarma 2025-11-28 20:03:56 -06:00
parent 552a391396
commit 4695642189
6 changed files with 168 additions and 15 deletions

12
.vscode/settings.json vendored Normal file
View 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"
}
}

View file

@ -28,6 +28,7 @@ cc_defaults {
"libswresample", "libswresample",
"libswscale", "libswscale",
"libutils", "libutils",
"libyuv",
], ],
} }

View file

@ -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.

View file

@ -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;

View file

@ -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);
} }
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; 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;
} }

View file

@ -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);