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",
|
||||
"libswscale",
|
||||
"libutils",
|
||||
"libyuv",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "C2FFMPEGVideoDecodeComponent.h"
|
||||
#include "ffmpeg_hwaccel.h"
|
||||
|
||||
|
||||
#define DEBUG_FRAMES 0
|
||||
#define DEBUG_WORKQUEUE 0
|
||||
#define DEBUG_EXTRADATA 0
|
||||
|
|
@ -282,6 +283,95 @@ c2_status_t C2FFMPEGVideoDecodeComponent::getOutputBuffer(C2GraphicView* outBuff
|
|||
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) {
|
||||
work->worklets.front()->output.flags =
|
||||
(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;
|
||||
std::vector<std::unique_ptr<C2Param>> configUpdate;
|
||||
|
||||
uint32_t frameSize = mFrame->height * mFrame->width;
|
||||
|
||||
switch (mCtx->codec_id) {
|
||||
case AV_CODEC_ID_HEVC:
|
||||
case AV_CODEC_ID_H264:
|
||||
// Increase output delay step-wise.
|
||||
if (outputDelay >= 18u) {
|
||||
newOutputDelay = 34u;
|
||||
} else if (outputDelay >= 8u) {
|
||||
newOutputDelay = 18u;
|
||||
} else {
|
||||
newOutputDelay = 8u;
|
||||
|
||||
if(frameSize <= RKVDEC_1080P_PIXELS){
|
||||
if (outputDelay >= 8u){
|
||||
newOutputDelay = 16u;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
default:
|
||||
// Other codecs use constant output delay.
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@
|
|||
#include "C2FFMPEGCommon.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 {
|
||||
|
||||
typedef std::pair<uint64_t, uint64_t> PendingWork;
|
||||
|
|
@ -75,7 +81,7 @@ private:
|
|||
bool mCodecAlreadyOpened;
|
||||
bool mExtradataReady;
|
||||
bool mEOSSignalled;
|
||||
std::deque<PendingWork> mPendingWorkQueue;
|
||||
std::deque<PendingWork> mPendingWorkQueue;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
#include <cutils/properties.h>
|
||||
|
||||
#include "ffmpeg_hwaccel.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
if (err < 0) {
|
||||
ALOGE("ffmpeg_hwaccel_get_frame failed to transfer data: %s (%08x)",
|
||||
av_err2str(err), err);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = av_frame_copy_props(output, frame);
|
||||
if (err < 0) {
|
||||
ALOGE("ffmpeg_hwaccel_get_frame failed to copy frame properties: %s (%08x)",
|
||||
av_err2str(err), err);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
#ifndef FFMPEG_HWACCEL_H
|
||||
#define FFMPEG_HWACCEL_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#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 void ffmpeg_hwaccel_deinit(AVCodecContext *avctx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue