Update for v1.0beta3.1

This commit is contained in:
James Deng 2024-04-15 11:42:57 +08:00
parent 3ba6ecc050
commit 3e9bbf514f
32 changed files with 69712 additions and 32 deletions

View file

@ -15,9 +15,7 @@ do_strip=no
# Dracut modules needed
add_dracutmodules+=" \
busybox-init \
busybox \
rescue \
busybox-init
"
# Modules to ignore
@ -26,6 +24,7 @@ bash \
biosdevname \
btrfs \
bluetooth \
busybox \
caps \
cifs \
crypt \

View file

@ -55,6 +55,5 @@ install() {
/etc/group \
/etc/passwd \
/etc/shadow \
/etc/hostname \
/lib/firmware/esos.elf
/etc/hostname
}

View file

@ -43,8 +43,6 @@ ifeq ($(BR2_INIT_BUSYBOX),y)
define HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE
$(INSTALL) -D -m 0755 package/dracut/busybox-init-module-setup.sh \
$(HOST_DIR)/lib/dracut/modules.d/05busybox-init/module-setup.sh
$(INSTALL) -D -m 0755 package/dracut/rescue-module-setup.sh \
$(HOST_DIR)/lib/dracut/modules.d/03rescue/module-setup.sh
endef
HOST_DRACUT_POST_INSTALL_HOOKS += HOST_DRACUT_POST_INSTALL_BUSYBOX_INIT_MODULE
endif

View file

@ -1,19 +0,0 @@
#!/bin/bash
# called by dracut
check() {
# do not add this module by default
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
inst_multiple -o ps grep more cat rm strace free showmount \
ping netstat rpcinfo vi scp ping6 ssh \
fsck fsck.ext2 fsck.ext4 fsck.ext3 fsck.ext4dev fsck.f2fs fsck.vfat e2fsck resize2fs mount
}

View file

@ -0,0 +1,703 @@
From 573266fb7c6d3747556269aadb66905cab788fcd Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Tue, 12 Mar 2024 08:56:22 +0800
Subject: [PATCH] update version: fix some bugs
---
libavcodec/stcodecdec.c | 477 +++++++++++++++++++++++++++++-----------
1 file changed, 346 insertions(+), 131 deletions(-)
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
index 763e1b2..1d618b9 100755
--- a/libavcodec/stcodecdec.c
+++ b/libavcodec/stcodecdec.c
@@ -39,7 +39,8 @@
#include "libavutil/log.h"
#include "vdec.h"
-#define PACKET_SIZE (2 * 1024 * 1024)
+#define FREESLOTS_THRESHOLD 4
+#define DROPFRAME_NUM_AFTER_FLUSH 1
typedef struct {
MppVdecCtx* pVdecCtx;
@@ -49,6 +50,11 @@ typedef struct {
enum AVPixelFormat ePixFmt;
char eos_reached;
+ char no_pts;
+ char first_packet;
+ int64_t duration;
+ int64_t use_dts;
+ char flushed;
AVBufferRef* frames_ref;
AVBufferRef* device_ref;
@@ -76,17 +82,78 @@ static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
return CODING_VP9;
case AV_CODEC_ID_MJPEG:
return CODING_MJPEG;
+ case AV_CODEC_ID_VC1:
+ return CODING_VC1;
+ case AV_CODEC_ID_MPEG2VIDEO:
+ return CODING_MPEG2;
+ case AV_CODEC_ID_MPEG4:
+ return CODING_MPEG4;
+ case AV_CODEC_ID_AVS:
+ return CODING_AVS;
+ case AV_CODEC_ID_AVS2:
+ return CODING_AVS2;
default:
return CODING_UNKNOWN;
}
}
+static MppProfileType stcodec_get_profiletype(AVCodecContext* avctx) {
+ av_log(avctx, AV_LOG_DEBUG, "profile = %d\n", avctx->profile);
+ if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ switch (avctx->profile) {
+ case FF_PROFILE_MPEG2_422:
+ return PROFILE_MPEG2_422;
+ case FF_PROFILE_MPEG2_HIGH:
+ return PROFILE_MPEG2_HIGH;
+ case FF_PROFILE_MPEG2_SNR_SCALABLE:
+ return PROFILE_MPEG2_SNR_SCALABLE;
+ case FF_PROFILE_MPEG2_MAIN:
+ return PROFILE_MPEG2_MAIN;
+ case FF_PROFILE_MPEG2_SIMPLE:
+ return PROFILE_MPEG2_SIMPLE;
+ default:
+ return PROFILE_UNKNOWN;
+ }
+ } else if (avctx->codec_id == AV_CODEC_ID_VC1) {
+ switch (avctx->profile) {
+ case FF_PROFILE_VC1_SIMPLE:
+ return PROFILE_VC1_SIMPLE;
+ case FF_PROFILE_VC1_MAIN:
+ return PROFILE_VC1_MAIN;
+ case FF_PROFILE_VC1_COMPLEX:
+ return PROFILE_VC1_COMPLEX;
+ case FF_PROFILE_VC1_ADVANCED:
+ return PROFILE_VC1_ADVANCED;
+ default:
+ return PROFILE_UNKNOWN;
+ }
+ } else if (avctx->codec_id == AV_CODEC_ID_MJPEG) {
+ switch (avctx->profile) {
+ case FF_PROFILE_MJPEG_HUFFMAN_BASELINE_DCT:
+ return PROFILE_MJPEG_HUFFMAN_BASELINE_DCT;
+ case FF_PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT:
+ return PROFILE_MJPEG_HUFFMAN_EXTENDED_SEQUENTIAL_DCT;
+ case FF_PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT:
+ return PROFILE_MJPEG_HUFFMAN_PROGRESSIVE_DCT;
+ case FF_PROFILE_MJPEG_HUFFMAN_LOSSLESS:
+ return PROFILE_MJPEG_HUFFMAN_LOSSLESS;
+ case FF_PROFILE_MJPEG_JPEG_LS:
+ return PROFILE_MJPEG_JPEG_LS;
+ default:
+ return PROFILE_UNKNOWN;
+ }
+ } else {
+ return PROFILE_UNKNOWN;
+ }
+}
+
static int get_stride(int width, int align) {
return (width + align - 1) & (~(align - 1));
}
static int stcodec_send_data_to_decoder(AVCodecContext* avctx, uint8_t* buffer,
- int size, int64_t pts) {
+ int size, int64_t pts, int64_t dts,
+ int64_t duration) {
STCODECDecodeContext* st_context = avctx->priv_data;
STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
int ret = 0;
@@ -102,7 +169,14 @@ static int stcodec_send_data_to_decoder(AVCodecContext* avctx, uint8_t* buffer,
PACKET_SetDataPointer(decoder->pPacket, buffer);
PACKET_SetLength(decoder->pPacket, size);
- PACKET_SetPts(decoder->pPacket, pts);
+ if (pts != AV_NOPTS_VALUE) {
+ PACKET_SetPts(decoder->pPacket, pts);
+ } else if (dts != AV_NOPTS_VALUE) {
+ PACKET_SetPts(decoder->pPacket, dts);
+ decoder->use_dts = 1;
+ } else {
+ decoder->no_pts = 1;
+ }
PACKET_SetEos(decoder->pPacket, 0);
av_log(avctx, AV_LOG_DEBUG, "input pts : %ld\n", pts);
}
@@ -135,12 +209,24 @@ static int stcodec_close_decoder(AVCodecContext* avctx) {
static void stcodec_release_stcodec_decoder(void* opaque, uint8_t* data) {
STCODECDecoder* decoder = (STCODECDecoder*)data;
+
+ if (decoder->pPacket) {
+ // PACKET_Free(decoder->pPacket);
+ PACKET_Destory(decoder->pPacket);
+ decoder->pPacket = NULL;
+ }
+
+ if (decoder->pFrame) {
+ FRAME_Destory(decoder->pFrame);
+ decoder->pFrame = NULL;
+ }
+
if (decoder->pVdecCtx) {
- av_log(NULL, AV_LOG_ERROR, "stcodec release decoder\n");
- VDEC_ResetChannel(decoder->pVdecCtx);
+ // VDEC_ResetChannel(decoder->pVdecCtx);
VDEC_DestoryChannel(decoder->pVdecCtx);
decoder->pVdecCtx = NULL;
}
+
av_buffer_unref(&decoder->frames_ref);
av_buffer_unref(&decoder->device_ref);
av_free(decoder);
@@ -151,9 +237,10 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
STCODECDecoder* decoder = NULL;
MppCodingType codectype = CODING_UNKNOWN;
int ret;
-/*
- if (avctx->width > 4096 || avctx->height > 2160 || avctx->width <= 640 ||
- avctx->height <= 480) {
+
+ if ((avctx->width > 4096 || avctx->height > 2304 || avctx->width <= 640 ||
+ avctx->height <= 480) &&
+ (avctx->width != 0 || avctx->height != 0)) {
av_log(avctx, AV_LOG_ERROR,
"STCODEC Decoder do not support the size (%d x %d), too big or too "
"small!\n",
@@ -161,9 +248,9 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
ret = AVERROR_UNKNOWN;
goto fail;
}
-*/
+
avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
- av_log(avctx, AV_LOG_ERROR, "------------------------ Use pixel format %d\n", avctx->pix_fmt);
+ av_log(avctx, AV_LOG_ERROR, "Use pixel format %d\n", avctx->pix_fmt);
// create a decoder and a ref to it
decoder = av_mallocz(sizeof(STCODECDecoder));
@@ -206,6 +293,7 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
// set para
decoder->pVdecCtx->stVdecPara.eCodingType = codectype;
+ decoder->pVdecCtx->stVdecPara.nProfile = stcodec_get_profiletype(avctx);
decoder->pVdecCtx->stVdecPara.bInputBlockModeEnable = MPP_FALSE;
decoder->pVdecCtx->stVdecPara.bOutputBlockModeEnable = MPP_TRUE;
decoder->pVdecCtx->stVdecPara.nWidth = avctx->width;
@@ -213,7 +301,12 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
decoder->pVdecCtx->stVdecPara.nStride = get_stride(avctx->width, 8);
decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = PIXEL_FORMAT_NV12;
decoder->pVdecCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
- decoder->pVdecCtx->stVdecPara.nScale = 1;
+ if (avctx->width >= 3840 || avctx->height >= 2160) {
+ av_log(avctx, AV_LOG_ERROR, "4K video, downscale!\n");
+ decoder->pVdecCtx->stVdecPara.nScale = 2;
+ } else {
+ decoder->pVdecCtx->stVdecPara.nScale = 1;
+ }
decoder->pVdecCtx->stVdecPara.nHorizonScaleDownRatio = 1;
decoder->pVdecCtx->stVdecPara.nVerticalScaleDownRatio = 1;
decoder->pVdecCtx->stVdecPara.nRotateDegree = 0;
@@ -225,37 +318,38 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
if (ret) {
av_log(avctx, AV_LOG_ERROR,
"Failed to initialize STCODEC VDEV (ret = %d).\n", ret);
- VDEC_DestoryChannel(decoder->pVdecCtx);
- av_free(decoder);
+ // VDEC_DestoryChannel(decoder->pVdecCtx);
+ // av_free(decoder);
ret = AVERROR_UNKNOWN;
goto fail;
}
- av_log(avctx, AV_LOG_ERROR, "init 1.\n");
// mpp packet init
decoder->pPacket = PACKET_Create();
if (!decoder->pPacket) {
av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC packet.\n");
- VDEC_DestoryChannel(decoder->pVdecCtx);
- av_free(decoder);
+ // VDEC_DestoryChannel(decoder->pVdecCtx);
+ // av_free(decoder);
ret = AVERROR_UNKNOWN;
goto fail;
}
- PACKET_Alloc(decoder->pPacket, PACKET_SIZE);
- av_log(avctx, AV_LOG_ERROR, "init 2.\n");
// mpp frame init
decoder->pFrame = FRAME_Create();
if (!decoder->pFrame) {
av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC frame.\n");
PACKET_Destory(decoder->pPacket);
- VDEC_DestoryChannel(decoder->pVdecCtx);
- av_free(decoder);
+ // VDEC_DestoryChannel(decoder->pVdecCtx);
+ // av_free(decoder);
ret = AVERROR_UNKNOWN;
goto fail;
}
- av_log(avctx, AV_LOG_ERROR, "init 3.\n");
+ decoder->first_packet = 1;
+ decoder->duration = 0;
+ decoder->use_dts = 0;
+ decoder->flushed = 0;
+
av_log(avctx, AV_LOG_DEBUG, "STCODEC decoder initialized successfully.\n");
decoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM);
@@ -264,37 +358,32 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
ret = AVERROR(ENOMEM);
goto fail;
}
- av_log(avctx, AV_LOG_ERROR, "init 4.\n");
ret = av_hwdevice_ctx_init(decoder->device_ref);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_init\n");
goto fail;
}
- av_log(avctx, AV_LOG_ERROR, "init 5.\n");
-
- decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);
- if (!decoder->frames_ref) {
- av_log(avctx, AV_LOG_ERROR, "Failed to av_hwframe_ctx_alloc\n");
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- av_log(avctx, AV_LOG_ERROR, "init 6.\n");
-
- AVHWFramesContext* hwframes;
- hwframes = (AVHWFramesContext*)decoder->frames_ref->data;
- hwframes->format = AV_PIX_FMT_DRM_PRIME;
- hwframes->sw_format = AV_PIX_FMT_NV12;
- hwframes->width = avctx->width;
- hwframes->height = avctx->height;
- ret = av_hwframe_ctx_init(decoder->frames_ref);
- if (ret < 0) goto fail;
+ /*
+ decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);
+ if (!decoder->frames_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwframe_ctx_alloc\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ AVHWFramesContext* hwframes;
+ hwframes = (AVHWFramesContext*)decoder->frames_ref->data;
+ hwframes->format = AV_PIX_FMT_DRM_PRIME;
+ hwframes->sw_format = AV_PIX_FMT_NV12;
+ hwframes->width = avctx->width;
+ hwframes->height = avctx->height;
+ ret = av_hwframe_ctx_init(decoder->frames_ref);
+ if (ret < 0) goto fail;
+ */
av_log(avctx, AV_LOG_DEBUG, "Initialized successfully.\n");
- av_log(avctx, AV_LOG_ERROR, "init 7.\n");
return 0;
fail:
- av_log(avctx, AV_LOG_ERROR, "init 8.\n");
av_log(avctx, AV_LOG_ERROR,
"Failed to initialize STCODEC decoder, please check!\n");
stcodec_close_decoder(avctx);
@@ -305,23 +394,57 @@ static int stcodec_send_packet(AVCodecContext* avctx, const AVPacket* avpkt) {
STCODECDecodeContext* st_context = avctx->priv_data;
STCODECDecoder* decoder = (STCODECDecoder*)st_context->decoder_ref->data;
int ret;
- av_log(avctx, AV_LOG_DEBUG, "start send packet, pts(%ld)\n", avpkt->pts);
+ av_log(avctx, AV_LOG_DEBUG,
+ "start send packet, pts(%ld) dts(%ld) duration(%ld)\n", avpkt->pts,
+ avpkt->dts, avpkt->duration);
// handle EOF
if (!avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "Get EOS from parser!\n");
decoder->eos_reached = 1;
// write a NULL data to decoder to inform it the EOS.
- ret = stcodec_send_data_to_decoder(avctx, NULL, 0, 0);
+ ret = stcodec_send_data_to_decoder(avctx, NULL, 0, 0, 0, 0);
if (ret)
av_log(avctx, AV_LOG_ERROR, "Failed to send EOS to decoder (ret = %d)\n",
ret);
return ret;
}
+ // on first packet, send extradata
+ if (decoder->first_packet) {
+ if (avctx->extradata_size) {
+ if (avctx->codec_id == AV_CODEC_ID_H264) {
+ ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
+ avctx->extradata_size, avpkt->pts,
+ avpkt->dts, avpkt->duration);
+ } else if (avctx->codec_id == AV_CODEC_ID_HEVC) {
+ ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
+ avctx->extradata_size, avpkt->pts,
+ avpkt->dts, avpkt->duration);
+ } else if (avctx->codec_id == AV_CODEC_ID_MJPEG) {
+ // do nothing.
+ } else if (avctx->codec_id == AV_CODEC_ID_MPEG4 ||
+ avctx->codec_id == AV_CODEC_ID_VC1) {
+ ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
+ avctx->extradata_size, avpkt->pts,
+ avpkt->dts, avpkt->duration);
+ if (ret) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to write extradata to decoder (ret = %d)\n", ret);
+ return ret;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "OK! Write extradata to decoder (size = %d)\n",
+ avctx->extradata_size);
+ }
+ }
+ }
+ decoder->first_packet = 0;
+ }
+
// now send packet
- ret =
- stcodec_send_data_to_decoder(avctx, avpkt->data, avpkt->size, avpkt->pts);
+ ret = stcodec_send_data_to_decoder(avctx, avpkt->data, avpkt->size,
+ avpkt->pts, avpkt->dts, avpkt->duration);
if (ret) {
av_log(avctx, AV_LOG_DEBUG,
"Failed to write data to decoder (code = %d (%s))\n", ret,
@@ -351,6 +474,7 @@ static void stcodec_release_frame(void* opaque, uint8_t* data) {
AV_PIX_FMT_DRM_PRIME) {
av_free(desc);
}
+ FRAME_Destory(framecontext->pFrame);
av_buffer_unref(&framecontext->decoder_ref);
av_buffer_unref(&framecontextref);
}
@@ -373,15 +497,15 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
// we get the available input queue num in decoder
VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
freeslots = decoder->pVdecPara->nInputQueueLeftNum;
- av_log(avctx, AV_LOG_ERROR, "--------- Input queue left %d seat!!\n", freeslots);
+ av_log(avctx, AV_LOG_DEBUG, "Input queue left %d seat!!\n", freeslots);
- if (freeslots > 0) {
+ while (freeslots > 0) {
ret = ff_decode_get_packet(avctx, &pkt);
if (ret < 0 && ret != AVERROR_EOF) {
- av_log(avctx, AV_LOG_ERROR,
+ av_log(avctx, AV_LOG_DEBUG,
"Failed to ff_decode_get_packet (ret = %d (%s))\n", ret,
av_err2str(ret));
- return ret;
+ goto fail;
}
ret = stcodec_send_packet(avctx, &pkt);
@@ -391,114 +515,200 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
av_log(avctx, AV_LOG_ERROR,
"Failed to send packet to decoder (code = %d (%s))\n", ret,
av_err2str(ret));
- return ret;
+ goto fail;
}
- }
- // make sure we keep decoder full
- VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
- freeslots = decoder->pVdecPara->nInputQueueLeftNum;
- av_log(avctx, AV_LOG_ERROR, "========== Input queue left %d seat!!\n", freeslots);
- if (freeslots > 0) return AVERROR(EAGAIN);
+ // make sure we keep decoder full
+ VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
+ freeslots = decoder->pVdecPara->nInputQueueLeftNum;
+ av_log(avctx, AV_LOG_DEBUG, "Input queue left %d seat!!\n", freeslots);
+ }
}
- ret = VDEC_RequestOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ do {
+ ret =
+ VDEC_RequestOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ if (ret == MPP_CODER_NULL_DATA) {
+ av_log(avctx, AV_LOG_ERROR, "null data, return\n");
+ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ }
+ } while (ret == MPP_CODER_NO_DATA || ret == MPP_CODER_NULL_DATA);
av_log(avctx, AV_LOG_DEBUG, "Request frame (ret = %d)\n", ret);
if (ret == MPP_CODER_EOS && mppframe == NULL) {
av_log(avctx, AV_LOG_ERROR, "EOS 1!\n");
- return AVERROR_EOF;
+ ret = AVERROR_EOF;
+ goto fail;
}
if (ret == MPP_CODER_EOS ||
FRAME_GetEos(mppframe) == 1 /* || decoder->eos_reached*/) {
av_log(avctx, AV_LOG_ERROR, "EOS 2!\n");
VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
- return AVERROR_EOF;
+ ret = AVERROR_EOF;
+ goto fail;
}
- if (!ret) {
- av_log(NULL, AV_LOG_DEBUG, "stcodec request a frame\n");
+ if (ret == MPP_ERROR_FRAME) {
+ av_log(avctx, AV_LOG_ERROR, "error frame, need discard\n");
+ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ ret = AVERROR(EAGAIN);
+ goto fail;
+ }
- // setup general frame fields
- frame->format = avctx->pix_fmt;
- frame->width = avctx->width;
- frame->height = avctx->height;
- // frame->pts = FRAME_GetPts(decoder->pFrame);
- frame->interlaced_frame = 0;
- frame->top_field_first = 0;
-
- framecontextref = av_buffer_allocz(sizeof(*framecontext));
- if (!framecontextref) {
- av_log(avctx, AV_LOG_ERROR, "Failed to alloc AvBufferRef\n");
- ret = AVERROR(ENOMEM);
- return ret;
- }
+ if (ret == MPP_RESOLUTION_CHANGED) {
+ av_log(avctx, AV_LOG_ERROR,
+ "resolution changed!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ AVHWFramesContext* hwframes;
- // MPP decoder needs to be closed only when all frames have been released.
- framecontext = (STCODECFrameContext*)framecontextref->data;
- framecontext->decoder_ref = av_buffer_ref(st_context->decoder_ref);
- framecontext->pFrame = mppframe;
+ av_log(avctx, AV_LOG_DEBUG, "Decoder noticed an info change (%dx%d)\n",
+ decoder->pVdecCtx->stVdecPara.nWidth,
+ decoder->pVdecCtx->stVdecPara.nHeight);
- if (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME) {
- desc = av_mallocz(sizeof(AVDRMFrameDescriptor));
- if (!desc) {
- ret = AVERROR(ENOMEM);
- return ret;
- }
+ avctx->width = decoder->pVdecCtx->stVdecPara.nWidth;
+ avctx->height = decoder->pVdecCtx->stVdecPara.nHeight;
- desc->nb_objects = 1;
- desc->objects[0].fd = FRAME_GetFD(mppframe, 0);
- desc->objects[0].size = frame->width * frame->height * 3 / 2;
- av_log(avctx, AV_LOG_DEBUG, "fd=%d size=%ld\n", desc->objects[0].fd,
- desc->objects[0].size);
- desc->nb_layers = 1;
- layer = &desc->layers[0];
- layer->format = DRM_FORMAT_NV12;
- layer->nb_planes = 2;
-
- layer->planes[0].object_index = 0;
- layer->planes[0].offset = 0;
- layer->planes[0].pitch = frame->width;
-
- layer->planes[1].object_index = 0;
- layer->planes[1].offset = frame->width * frame->height;
- layer->planes[1].pitch = frame->width;
-
- frame->data[0] = (uint8_t*)desc;
- frame->buf[0] =
- av_buffer_create((uint8_t*)desc, sizeof(*desc), stcodec_release_frame,
- framecontextref, AV_BUFFER_FLAG_READONLY);
- } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {
- frame->linesize[0] = get_stride(avctx->width, 8);
- frame->linesize[1] = get_stride(avctx->width, 8);
- frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
- frame->data[1] = frame->data[0] + frame->width * frame->height;
- frame->buf[0] = av_buffer_create(
- (uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
- stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
- }
+ av_buffer_unref(&decoder->frames_ref);
- if (!frame->buf[0]) {
+ decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);
+ if (!decoder->frames_ref) {
av_log(avctx, AV_LOG_ERROR,
- "Failed to create AVDRMFrameDescriptor ref\n");
+ "av_hwframe_ctx_alloc failed, please check\n");
ret = AVERROR(ENOMEM);
- return ret;
+ goto fail;
}
- frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
- if (!frame->hw_frames_ctx) {
- av_log(avctx, AV_LOG_ERROR, "Failed to create hw_frames_ctx\n");
- ret = AVERROR(ENOMEM);
- return ret;
+ hwframes = (AVHWFramesContext*)decoder->frames_ref->data;
+ hwframes->format = AV_PIX_FMT_DRM_PRIME;
+ hwframes->sw_format = AV_PIX_FMT_NV12;
+ hwframes->width = avctx->width;
+ hwframes->height = avctx->height;
+ ret = av_hwframe_ctx_init(decoder->frames_ref);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed, please check\n");
+ goto fail;
}
+ // here decoder is fully initialized, we need to feed it again with data
+ ret = AVERROR(EAGAIN);
+ goto fail;
+ }
+
+ if (!ret) {
+ av_log(NULL, AV_LOG_DEBUG, "stcodec request a frame\n");
+ if (!decoder->flushed) {
+ // setup general frame fields
+ frame->format = avctx->pix_fmt;
+ frame->width = avctx->width;
+ frame->height = avctx->height;
+ if (!decoder->no_pts) {
+ if (!decoder->use_dts) {
+ frame->pts = FRAME_GetPts(mppframe);
+ } else {
+ frame->pkt_dts = FRAME_GetPts(mppframe);
+ }
+ } else {
+ }
+ av_log(avctx, AV_LOG_DEBUG, "frame pts:%ld pkt_dts:%ld\n", frame->pts,
+ frame->pkt_dts);
+ frame->interlaced_frame = 0;
+ frame->top_field_first = 0;
+
+ framecontextref = av_buffer_allocz(sizeof(*framecontext));
+ if (!framecontextref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to alloc AvBufferRef\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ // MPP decoder needs to be closed only when all frames have been released.
+ framecontext = (STCODECFrameContext*)framecontextref->data;
+ framecontext->decoder_ref = av_buffer_ref(st_context->decoder_ref);
+ framecontext->pFrame = mppframe;
+
+ if (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME) {
+ desc = av_mallocz(sizeof(AVDRMFrameDescriptor));
+ if (!desc) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ desc->nb_objects = 1;
+ desc->objects[0].fd = FRAME_GetFD(mppframe, 0);
+ desc->objects[0].size = frame->width * frame->height * 3 / 2;
+ av_log(avctx, AV_LOG_DEBUG, "fd=%d size=%ld\n", desc->objects[0].fd,
+ desc->objects[0].size);
+ desc->nb_layers = 1;
+ layer = &desc->layers[0];
+ layer->format = DRM_FORMAT_NV12;
+ layer->nb_planes = 2;
+
+ layer->planes[0].object_index = 0;
+ layer->planes[0].offset = 0;
+ layer->planes[0].pitch = frame->width;
+
+ layer->planes[1].object_index = 0;
+ layer->planes[1].offset = frame->width * frame->height;
+ layer->planes[1].pitch = frame->width;
+
+ frame->data[0] = (uint8_t*)desc;
+ frame->buf[0] = av_buffer_create((uint8_t*)desc, sizeof(*desc),
+ stcodec_release_frame, framecontextref,
+ AV_BUFFER_FLAG_READONLY);
+ } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {
+ frame->linesize[0] = get_stride(avctx->width, 8);
+ frame->linesize[1] = get_stride(avctx->width, 8);
+ frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
+ frame->data[1] = frame->data[0] + frame->width * frame->height;
+ frame->buf[0] = av_buffer_create(
+ (uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
+ stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
+ }
+
+ if (!frame->buf[0]) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to create AVDRMFrameDescriptor ref\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);
+ if (!frame->hw_frames_ctx) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create hw_frames_ctx\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ } else if (decoder->flushed < DROPFRAME_NUM_AFTER_FLUSH) {
+ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ av_log(avctx, AV_LOG_ERROR, "drop some frames after flush, num=%d\n",
+ decoder->flushed);
+ decoder->flushed++;
+ ret = AVERROR(EAGAIN);
+ goto fail;
+ } else if (decoder->flushed == DROPFRAME_NUM_AFTER_FLUSH) {
+ VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
+ ret = AVERROR(EAGAIN);
+ av_log(avctx, AV_LOG_ERROR,
+ "drop some frames after flush finish, num=%d\n", decoder->flushed);
+ decoder->flushed = 0;
+ goto fail;
+ }
} else {
- // return AVERROR_UNKNOWN;
- return AVERROR(EAGAIN);
+ av_log(avctx, AV_LOG_ERROR, "should not be here, ret = %d\n", ret);
+ ret = AVERROR(EAGAIN);
+ goto fail;
}
return 0; // return AVERROR(EAGAIN);
+
+fail:
+ if (mppframe) FRAME_Destory(mppframe);
+ if (framecontext && framecontext->pFrame) FRAME_Destory(framecontext->pFrame);
+ if (framecontext) av_buffer_unref(&framecontext->decoder_ref);
+ if (framecontextref) av_buffer_unref(&framecontextref);
+ if (desc) av_free(desc);
+
+ return ret;
}
static void stcodec_flush(AVCodecContext* avctx) {
@@ -507,13 +717,18 @@ static void stcodec_flush(AVCodecContext* avctx) {
int ret = -1;
av_log(avctx, AV_LOG_ERROR, "Flush.\n");
-/*
- ret = VDEC_ResetChannel(decoder->pVdecCtx);
+
+ ret = VDEC_Flush(decoder->pVdecCtx);
if (ret)
- av_log(avctx, AV_LOG_ERROR, "Failed to reset VDEC Channel (code = %d)\n",
+ av_log(avctx, AV_LOG_ERROR, "Failed to flush VDEC Channel (code = %d)\n",
ret);
-*/
+
decoder->eos_reached = 0;
+ decoder->no_pts = 0;
+ decoder->first_packet = 1;
+ decoder->duration = 0;
+ decoder->use_dts = 0;
+ decoder->flushed = 1;
}
static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
--
2.25.1

View file

@ -0,0 +1,38 @@
From 6eb52b2c24bbc15ea991d40c7c7772f642881ae8 Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Wed, 20 Mar 2024 14:38:47 +0800
Subject: [PATCH] optimize: ffmpeg -c:v h264_stcodec -i xxx.mp4 output.yuv
---
libavcodec/stcodecdec.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
index 1d618b9..cf88096 100755
--- a/libavcodec/stcodecdec.c
+++ b/libavcodec/stcodecdec.c
@@ -532,7 +532,7 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
av_log(avctx, AV_LOG_ERROR, "null data, return\n");
VDEC_ReturnOutputFrame(decoder->pVdecCtx, FRAME_GetBaseData(mppframe));
}
- } while (ret == MPP_CODER_NO_DATA || ret == MPP_CODER_NULL_DATA);
+ } while (ret == MPP_CODER_NULL_DATA);
av_log(avctx, AV_LOG_DEBUG, "Request frame (ret = %d)\n", ret);
if (ret == MPP_CODER_EOS && mppframe == NULL) {
@@ -556,6 +556,12 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
goto fail;
}
+ if (ret == MPP_CODER_NO_DATA) {
+ av_log(avctx, AV_LOG_ERROR, "no data, return\n");
+ ret = AVERROR(EAGAIN);
+ goto fail;
+ }
+
if (ret == MPP_RESOLUTION_CHANGED) {
av_log(avctx, AV_LOG_ERROR,
"resolution changed!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
--
2.25.1

View file

@ -0,0 +1,125 @@
From 217da28a3f91ae8e360d2da836519001488d143b Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Fri, 29 Mar 2024 09:39:01 +0800
Subject: [PATCH] stcodecdec support yuv420p output pixel format
---
libavcodec/stcodecdec.c | 54 ++++++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 20 deletions(-)
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
index cf88096..66b1305 100755
--- a/libavcodec/stcodecdec.c
+++ b/libavcodec/stcodecdec.c
@@ -70,6 +70,19 @@ typedef struct {
AVBufferRef* decoder_ref;
} STCODECFrameContext;
+static MppPixelFormat stcodec_get_pixelformat(AVCodecContext* avctx) {
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_NV12:
+ return PIXEL_FORMAT_NV12;
+ case AV_PIX_FMT_YUV420P:
+ return PIXEL_FORMAT_I420;
+ case AV_PIX_FMT_DRM_PRIME:
+ return PIXEL_FORMAT_NV12;
+ default:
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+}
+
static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
switch (avctx->codec_id) {
case AV_CODEC_ID_H264:
@@ -299,7 +312,7 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
decoder->pVdecCtx->stVdecPara.nWidth = avctx->width;
decoder->pVdecCtx->stVdecPara.nHeight = avctx->height;
decoder->pVdecCtx->stVdecPara.nStride = get_stride(avctx->width, 8);
- decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = PIXEL_FORMAT_NV12;
+ decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = stcodec_get_pixelformat(avctx);
decoder->pVdecCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
if (avctx->width >= 3840 || avctx->height >= 2160) {
av_log(avctx, AV_LOG_ERROR, "4K video, downscale!\n");
@@ -413,18 +426,10 @@ static int stcodec_send_packet(AVCodecContext* avctx, const AVPacket* avpkt) {
// on first packet, send extradata
if (decoder->first_packet) {
if (avctx->extradata_size) {
- if (avctx->codec_id == AV_CODEC_ID_H264) {
- ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
- avctx->extradata_size, avpkt->pts,
- avpkt->dts, avpkt->duration);
- } else if (avctx->codec_id == AV_CODEC_ID_HEVC) {
- ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
- avctx->extradata_size, avpkt->pts,
- avpkt->dts, avpkt->duration);
- } else if (avctx->codec_id == AV_CODEC_ID_MJPEG) {
- // do nothing.
- } else if (avctx->codec_id == AV_CODEC_ID_MPEG4 ||
- avctx->codec_id == AV_CODEC_ID_VC1) {
+ if (avctx->codec_id == AV_CODEC_ID_H264 ||
+ avctx->codec_id == AV_CODEC_ID_HEVC ||
+ avctx->codec_id == AV_CODEC_ID_MPEG4 ||
+ avctx->codec_id == AV_CODEC_ID_VC1) {
ret = stcodec_send_data_to_decoder(avctx, avctx->extradata,
avctx->extradata_size, avpkt->pts,
avpkt->dts, avpkt->duration);
@@ -499,7 +504,7 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
freeslots = decoder->pVdecPara->nInputQueueLeftNum;
av_log(avctx, AV_LOG_DEBUG, "Input queue left %d seat!!\n", freeslots);
- while (freeslots > 0) {
+ if (freeslots > 0) {
ret = ff_decode_get_packet(avctx, &pkt);
if (ret < 0 && ret != AVERROR_EOF) {
av_log(avctx, AV_LOG_DEBUG,
@@ -517,11 +522,6 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
av_err2str(ret));
goto fail;
}
-
- // make sure we keep decoder full
- VDEC_GetParam(decoder->pVdecCtx, &(decoder->pVdecPara));
- freeslots = decoder->pVdecPara->nInputQueueLeftNum;
- av_log(avctx, AV_LOG_DEBUG, "Input queue left %d seat!!\n", freeslots);
}
}
@@ -666,6 +666,17 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
frame->linesize[1] = get_stride(avctx->width, 8);
frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
frame->data[1] = frame->data[0] + frame->width * frame->height;
+ frame->buf[0] = av_buffer_create(
+ (uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
+ stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
+ } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
+ frame->linesize[0] = get_stride(avctx->width, 8);
+ frame->linesize[1] = get_stride(avctx->width, 8) / 2;
+ frame->linesize[2] = get_stride(avctx->width, 8) / 2;
+ frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
+ frame->data[1] = FRAME_GetDataPointer(mppframe, 1);
+ frame->data[2] = FRAME_GetDataPointer(mppframe, 2);
+
frame->buf[0] = av_buffer_create(
(uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
@@ -763,7 +774,7 @@ static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
AV_CODEC_CAP_HARDWARE, \
.pix_fmts = \
(const enum AVPixelFormat[]){AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NV12, \
- AV_PIX_FMT_NONE}, \
+ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE}, \
.hw_configs = stcodec_hw_configs, \
.bsfs = BSFS, \
.wrapper_name = "stcodec", \
@@ -771,4 +782,7 @@ static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
STCODEC_DEC(h264, AV_CODEC_ID_H264, "h264_mp4toannexb")
STCODEC_DEC(hevc, AV_CODEC_ID_HEVC, "hevc_mp4toannexb")
+STCODEC_DEC(vp8, AV_CODEC_ID_VP8, NULL)
+STCODEC_DEC(vp9, AV_CODEC_ID_VP9, NULL)
STCODEC_DEC(mjpeg, AV_CODEC_ID_MJPEG, NULL)
+STCODEC_DEC(mpeg4, AV_CODEC_ID_MPEG4, NULL)
\ No newline at end of file
--
2.25.1

View file

@ -0,0 +1,592 @@
From 7757b33d16cc70e2f5a182cad8f9f9ee375874b2 Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Fri, 29 Mar 2024 10:45:11 +0800
Subject: [PATCH] stcodec support video encode
---
configure | 7 +
libavcodec/Makefile | 7 +
libavcodec/allcodecs.c | 7 +
libavcodec/stcodecenc.c | 417 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 438 insertions(+)
create mode 100755 libavcodec/stcodecenc.c
diff --git a/configure b/configure
index 473d30e..c14c5c1 100755
--- a/configure
+++ b/configure
@@ -3095,6 +3095,7 @@ h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf"
h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
h264_stcodec_decoder_deps="stcodec"
+h264_stcodec_encoder_deps="stcodec"
hevc_amf_encoder_deps="amf"
hevc_cuvid_decoder_deps="cuvid"
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
@@ -3113,12 +3114,15 @@ hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
hevc_stcodec_decoder_deps="stcodec"
+hevc_stcodec_encoder_deps="stcodec"
mjpeg_cuvid_decoder_deps="cuvid"
mjpeg_qsv_decoder_select="qsvdec"
mjpeg_qsv_encoder_deps="libmfx"
mjpeg_qsv_encoder_select="qsvenc"
mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
+mjpeg_stcodec_decoder_deps="stcodec"
+mjpeg_stcodec_encoder_deps="stcodec"
mp3_mf_encoder_deps="mediafoundation"
mpeg1_cuvid_decoder_deps="cuvid"
mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
@@ -3137,6 +3141,7 @@ mpeg4_mmal_decoder_deps="mmal"
mpeg4_omx_encoder_deps="omx"
mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
mpeg4_v4l2m2m_encoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
+mpeg4_stcodec_decoder_deps="stcodec"
msmpeg4_crystalhd_decoder_select="crystalhd"
nvenc_h264_encoder_select="h264_nvenc_encoder"
nvenc_hevc_encoder_select="hevc_nvenc_encoder"
@@ -3153,6 +3158,7 @@ vp8_vaapi_encoder_deps="VAEncPictureParameterBufferVP8"
vp8_vaapi_encoder_select="vaapi_encode"
vp8_v4l2m2m_decoder_deps="v4l2_m2m vp8_v4l2_m2m"
vp8_v4l2m2m_encoder_deps="v4l2_m2m vp8_v4l2_m2m"
+vp8_stcodec_decoder_deps="stcodec"
vp9_cuvid_decoder_deps="cuvid"
vp9_mediacodec_decoder_deps="mediacodec"
vp9_qsv_decoder_select="qsvdec"
@@ -3162,6 +3168,7 @@ vp9_vaapi_encoder_select="vaapi_encode"
vp9_qsv_encoder_deps="libmfx MFX_CODEC_VP9"
vp9_qsv_encoder_select="qsvenc"
vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m"
+vp9_stcodec_decoder_deps="stcodec"
wmv3_crystalhd_decoder_select="crystalhd"
av1_qsv_decoder_select="qsvdec"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index ff56ed6..e8e18f3 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -386,6 +386,7 @@ OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_H264_STCODEC_DECODER) += stcodecdec.o
+OBJS-$(CONFIG_H264_STCODEC_ENCODER) += stcodecenc.o
OBJS-$(CONFIG_HAP_DECODER) += hapdec.o hap.o
OBJS-$(CONFIG_HAP_ENCODER) += hapenc.o hap.o
OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
@@ -407,6 +408,7 @@ OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
OBJS-$(CONFIG_HEVC_STCODEC_DECODER) += stcodecdec.o
+OBJS-$(CONFIG_HEVC_STCODEC_ENCODER) += stcodecenc.o
OBJS-$(CONFIG_HNM4_VIDEO_DECODER) += hnm4video.o
OBJS-$(CONFIG_HQ_HQA_DECODER) += hq_hqa.o hq_hqadata.o hq_hqadsp.o \
canopus.o
@@ -461,6 +463,8 @@ OBJS-$(CONFIG_MJPEGB_DECODER) += mjpegbdec.o
OBJS-$(CONFIG_MJPEG_CUVID_DECODER) += cuviddec.o
OBJS-$(CONFIG_MJPEG_QSV_ENCODER) += qsvenc_jpeg.o
OBJS-$(CONFIG_MJPEG_VAAPI_ENCODER) += vaapi_encode_mjpeg.o
+OBJS-$(CONFIG_MJPEG_STCODEC_DECODER) += stcodecdec.o
+OBJS-$(CONFIG_MJPEG_STCODEC_ENCODER) += stcodecenc.o
OBJS-$(CONFIG_MLP_DECODER) += mlpdec.o mlpdsp.o
OBJS-$(CONFIG_MLP_ENCODER) += mlpenc.o mlp.o
OBJS-$(CONFIG_MMVIDEO_DECODER) += mmvideo.o
@@ -506,6 +510,7 @@ OBJS-$(CONFIG_MPEG4_MEDIACODEC_DECODER) += mediacodecdec.o
OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o
OBJS-$(CONFIG_MPEG4_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_MPEG4_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
+OBJS-$(CONFIG_MPEG4_STCODEC_DECODER) += stcodecdec.o
OBJS-$(CONFIG_MPL2_DECODER) += mpl2dec.o ass.o
OBJS-$(CONFIG_MSA1_DECODER) += mss3.o
OBJS-$(CONFIG_MSCC_DECODER) += mscc.o
@@ -722,6 +727,7 @@ OBJS-$(CONFIG_VP8_RKMPP_DECODER) += rkmppdec.o
OBJS-$(CONFIG_VP8_VAAPI_ENCODER) += vaapi_encode_vp8.o
OBJS-$(CONFIG_VP8_V4L2M2M_DECODER) += v4l2_m2m_dec.o
OBJS-$(CONFIG_VP8_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
+OBJS-$(CONFIG_VP8_STCODEC_DECODER) += stcodecdec.o
OBJS-$(CONFIG_VP9_DECODER) += vp9.o vp9data.o vp9dsp.o vp9lpf.o vp9recon.o \
vp9block.o vp9prob.o vp9mvs.o vp56rac.o \
vp9dsp_8bpp.o vp9dsp_10bpp.o vp9dsp_12bpp.o
@@ -732,6 +738,7 @@ OBJS-$(CONFIG_VP9_VAAPI_ENCODER) += vaapi_encode_vp9.o
OBJS-$(CONFIG_VP9_QSV_ENCODER) += qsvenc_vp9.o
OBJS-$(CONFIG_VPLAYER_DECODER) += textdec.o ass.o
OBJS-$(CONFIG_VP9_V4L2M2M_DECODER) += v4l2_m2m_dec.o
+OBJS-$(CONFIG_VP9_STCODEC_DECODER) += stcodecdec.o
OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o
OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o wavpackdata.o dsd.o
OBJS-$(CONFIG_WAVPACK_ENCODER) += wavpackdata.o wavpackenc.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 9981106..79bf666 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -149,12 +149,14 @@ extern AVCodec ff_h264_mmal_decoder;
extern AVCodec ff_h264_qsv_decoder;
extern AVCodec ff_h264_rkmpp_decoder;
extern AVCodec ff_h264_stcodec_decoder;
+extern AVCodec ff_h264_stcodec_encoder;
extern AVCodec ff_hap_encoder;
extern AVCodec ff_hap_decoder;
extern AVCodec ff_hevc_decoder;
extern AVCodec ff_hevc_qsv_decoder;
extern AVCodec ff_hevc_rkmpp_decoder;
extern AVCodec ff_hevc_stcodec_decoder;
+extern AVCodec ff_hevc_stcodec_encoder;
extern AVCodec ff_hevc_v4l2m2m_decoder;
extern AVCodec ff_hnm4_video_decoder;
extern AVCodec ff_hq_hqa_decoder;
@@ -191,6 +193,8 @@ extern AVCodec ff_mimic_decoder;
extern AVCodec ff_mjpeg_encoder;
extern AVCodec ff_mjpeg_decoder;
extern AVCodec ff_mjpegb_decoder;
+extern AVCodec ff_mjpeg_stcodec_decoder;
+extern AVCodec ff_mjpeg_stcodec_encoder;
extern AVCodec ff_mmvideo_decoder;
extern AVCodec ff_mobiclip_decoder;
extern AVCodec ff_motionpixels_decoder;
@@ -203,6 +207,7 @@ extern AVCodec ff_mpeg4_decoder;
extern AVCodec ff_mpeg4_crystalhd_decoder;
extern AVCodec ff_mpeg4_v4l2m2m_decoder;
extern AVCodec ff_mpeg4_mmal_decoder;
+extern AVCodec ff_mpeg4_stcodec_decoder;
extern AVCodec ff_mpegvideo_decoder;
extern AVCodec ff_mpeg1_v4l2m2m_decoder;
extern AVCodec ff_mpeg2_mmal_decoder;
@@ -361,9 +366,11 @@ extern AVCodec ff_vp7_decoder;
extern AVCodec ff_vp8_decoder;
extern AVCodec ff_vp8_rkmpp_decoder;
extern AVCodec ff_vp8_v4l2m2m_decoder;
+extern AVCodec ff_vp8_stcodec_decoder;
extern AVCodec ff_vp9_decoder;
extern AVCodec ff_vp9_rkmpp_decoder;
extern AVCodec ff_vp9_v4l2m2m_decoder;
+extern AVCodec ff_vp9_stcodec_decoder;
extern AVCodec ff_vqa_decoder;
extern AVCodec ff_webp_decoder;
extern AVCodec ff_wcmv_decoder;
diff --git a/libavcodec/stcodecenc.c b/libavcodec/stcodecenc.c
new file mode 100755
index 0000000..eeaa41a
--- /dev/null
+++ b/libavcodec/stcodecenc.c
@@ -0,0 +1,417 @@
+/*
+ * Spacemit MPP Video Encoder
+ * Copyright 2022-2023 SPACEMIT. All rights reserved.
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <drm_fourcc.h>
+#include <fcntl.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "avcodec.h"
+#include "internal.h"
+#include "encode.h"
+#include "h264_parse.h"
+#include "hevc_parse.h"
+#include "hwconfig.h"
+#include "libavutil/buffer.h"
+#include "libavutil/common.h"
+#include "libavutil/frame.h"
+#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_drm.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "venc.h"
+
+#define PACKET_SIZE (2 * 1024 * 1024)
+
+typedef struct {
+ MppVencCtx* pVencCtx;
+ MppPacket* pPacket;
+ MppFrame* pFrame;
+
+ char first_packet;
+ char eos_reached;
+
+ AVBufferRef* frames_ref;
+ AVBufferRef* device_ref;
+} STCODECEncoder;
+
+typedef struct {
+ AVClass* av_class;
+ AVBufferRef* encoder_ref;
+} STCODECEncodeContext;
+
+typedef struct {
+ MppFrame* pFrame;
+ AVBufferRef* encoder_ref;
+} STCODECFrameContext;
+
+static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_H264:
+ return CODING_H264;
+ case AV_CODEC_ID_HEVC:
+ return CODING_H265;
+ case AV_CODEC_ID_VP8:
+ return CODING_VP8;
+ case AV_CODEC_ID_VP9:
+ return CODING_VP9;
+ case AV_CODEC_ID_MJPEG:
+ return CODING_MJPEG;
+ default:
+ return CODING_UNKNOWN;
+ }
+}
+
+static int get_stride(int width, int align) {
+ return (width + align - 1) & (~(align - 1));
+}
+
+static int stcodec_send_frame(AVCodecContext* avctx, const AVFrame* frame) {
+ STCODECEncodeContext* st_context = avctx->priv_data;
+ STCODECEncoder* encoder = (STCODECEncoder*)st_context->encoder_ref->data;
+ int ret = -1;
+
+ if (frame != NULL) {
+ av_log(avctx, AV_LOG_ERROR, "@@@@@@@@ format:%d fd:%d %p %p\n",
+ frame->format,
+ ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].fd,
+ frame->data[0], frame->data[1]);
+ FRAME_SetEos(encoder->pFrame, 0);
+ if (frame->format == AV_PIX_FMT_NV12) {
+ FRAME_SetDataUsedNum(encoder->pFrame, 2);
+ FRAME_SetDataPointer(encoder->pFrame, 0, frame->data[0]);
+ FRAME_SetDataPointer(encoder->pFrame, 1, frame->data[1]);
+ // FRAME_SetDataPointer(encoder->pFrame, 2, frame->data[2]);
+ } else if (frame->format == AV_PIX_FMT_DRM_PRIME) {
+ void* vaddr =
+ mmap(NULL, ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].fd, 0);
+ FRAME_SetDataUsedNum(encoder->pFrame, 2);
+ FRAME_SetDataPointer(encoder->pFrame, 0, (U8*)vaddr);
+ FRAME_SetDataPointer(encoder->pFrame, 1,
+ ((U8*)vaddr) + frame->width * frame->height);
+ // FRAME_SetDataPointer(encoder->pFrame, 2,
+ // ((U8*)vaddr) + frame->width * frame->height * 5 /
+ // 4);
+ } else {
+ }
+ ret = VENC_Encode(encoder->pVencCtx, FRAME_GetBaseData(encoder->pFrame));
+ } else {
+ FRAME_SetEos(encoder->pFrame, 1);
+ av_log(avctx, AV_LOG_ERROR, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bigbig %d\n",
+ FRAME_GetEos(encoder->pFrame));
+ // FRAME_SetDataUsedNum(encoder->pFrame, 0);
+ ret = VENC_Encode(encoder->pVencCtx, FRAME_GetBaseData(encoder->pFrame));
+ }
+
+ return ret;
+}
+
+static int stcodec_receive_packet(AVCodecContext* avctx, AVPacket* avpkt) {
+ STCODECEncodeContext* st_context = avctx->priv_data;
+ STCODECEncoder* encoder = (STCODECEncoder*)st_context->encoder_ref->data;
+ int ret = -1;
+ AVFrame* frame = av_frame_alloc();
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 0.\n");
+ // if (!frame->buf[0]) {
+ ret = ff_encode_get_frame(avctx, frame);
+
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 0. RET = %d\n",
+ ret);
+ if (ret < 0 && ret != AVERROR_EOF) return ret;
+
+ if (ret == AVERROR_EOF) {
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 get eos\n");
+ frame = NULL;
+ }
+ //}
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 1.\n");
+ ret = stcodec_send_frame(avctx, frame);
+ if (ret != AVERROR(EAGAIN)) av_frame_unref(frame);
+
+ if (ret < 0 && ret != AVERROR(EAGAIN)) return ret;
+
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 2.\n");
+ // return ff_v4l2_context_dequeue_packet(capture, avpkt);
+haha:
+ ret = VENC_RequestOutputStreamBuffer(encoder->pVencCtx,
+ PACKET_GetBaseData(encoder->pPacket));
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 2. ret = %d\n",
+ ret);
+ if (ret == MPP_OK) {
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 3.\n");
+ avpkt->size = PACKET_GetLength(encoder->pPacket);
+ av_log(avctx, AV_LOG_DEBUG, "1111111111111111111111111111111 4. %d=%d %p\n",
+ PACKET_GetLength(encoder->pPacket), avpkt->size,
+ PACKET_GetDataPointer(encoder->pPacket));
+ av_new_packet(avpkt, avpkt->size);
+ memcpy(avpkt->data, PACKET_GetDataPointer(encoder->pPacket), avpkt->size);
+ av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 5.\n");
+ VENC_ReturnOutputStreamBuffer(encoder->pVencCtx,
+ PACKET_GetBaseData(encoder->pPacket));
+ } else if (ret == MPP_CODER_NO_DATA) {
+ av_log(avctx, AV_LOG_ERROR, "get no data.\n");
+ // return AVERROR(EAGAIN);
+ goto haha;
+ } else if (ret == MPP_CODER_EOS) {
+ av_log(avctx, AV_LOG_ERROR, "get EOS.\n");
+ return AVERROR_EOF;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "get ???. %d\n", ret);
+ }
+
+ return 0;
+}
+
+static av_cold int stcodec_close_encoder(AVCodecContext* avctx) {
+ STCODECEncodeContext* st_context = avctx->priv_data;
+ av_log(NULL, AV_LOG_ERROR, "stcodec close encoder\n");
+ av_buffer_unref(&st_context->encoder_ref);
+ return 0;
+}
+
+static void stcodec_release_encoder(void* opaque, uint8_t* data) {
+ STCODECEncoder* encoder = (STCODECEncoder*)data;
+ if (encoder->pVencCtx) {
+ av_log(NULL, AV_LOG_ERROR, "stcodec release encoder\n");
+ VENC_ResetChannel(encoder->pVencCtx);
+ VENC_DestoryChannel(encoder->pVencCtx);
+ encoder->pVencCtx = NULL;
+ }
+ av_buffer_unref(&encoder->frames_ref);
+ av_buffer_unref(&encoder->device_ref);
+ av_free(encoder);
+}
+
+static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
+ STCODECEncodeContext* st_context = avctx->priv_data;
+ STCODECEncoder* encoder = NULL;
+
+ MppCodingType codectype = CODING_UNKNOWN;
+ int ret;
+
+ if (avctx->width > 4096 || avctx->height > 2160 || avctx->width <= 640 ||
+ avctx->height <= 480) {
+ av_log(avctx, AV_LOG_ERROR,
+ "STCODEC-ENC do not support the size, too big or too small!\n");
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ // avctx->pix_fmt = AV_PIX_FMT_DRM_PRIME;
+ // avctx->pix_fmt = AV_PIX_FMT_NV12;
+ // avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
+ av_log(avctx, AV_LOG_ERROR, "======================== Use pixel format %d\n",
+ avctx->pix_fmt);
+
+ // create a encoder and a ref to it
+ encoder = av_mallocz(sizeof(STCODECEncoder));
+ if (!encoder) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to av_mallocz STCODECEncoder encoder\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ st_context->encoder_ref =
+ av_buffer_create((uint8_t*)encoder, sizeof(*encoder),
+ stcodec_release_encoder, NULL, AV_BUFFER_FLAG_READONLY);
+ if (!st_context->encoder_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create ref of STCODECEncoder!\n");
+ av_free(encoder);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "Initializing STCODEC encoder.\n");
+
+ codectype = stcodec_get_codingtype(avctx);
+ if (codectype == CODING_UNKNOWN) {
+ av_log(avctx, AV_LOG_ERROR, "Unknown codec type (%d).\n", avctx->codec_id);
+ av_free(encoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+ /*
+ ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
+ if (ret != MPP_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Codec type (%d) unsupported by MPP\n",
+ avctx->codec_id); ret = AVERROR_UNKNOWN; goto fail;
+ }
+ */
+
+ // Create the MPP context
+ encoder->pVencCtx = VENC_CreateChannel();
+ if (!encoder->pVencCtx) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to create STCODEC VENC channel.\n");
+ av_free(encoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ // set para
+ encoder->pVencCtx->stVencPara.eCodingType = codectype;
+ encoder->pVencCtx->stVencPara.nWidth = avctx->width;
+ encoder->pVencCtx->stVencPara.nHeight = avctx->height;
+ encoder->pVencCtx->stVencPara.nStride = get_stride(avctx->width, 8);
+ encoder->pVencCtx->stVencPara.PixelFormat = PIXEL_FORMAT_NV12;
+ encoder->pVencCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
+ encoder->pVencCtx->stVencPara.nBitrate = 5000000;
+ encoder->pVencCtx->stVencPara.nFrameRate = 30;
+ av_log(avctx, AV_LOG_ERROR, "(widthxheight = %d x %d).\n", avctx->width,
+ avctx->height);
+
+ // venc init
+ ret = VENC_Init(encoder->pVencCtx);
+ if (ret != MPP_OK) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to initialize STCODEC VENC (ret = %d).\n", ret);
+ VENC_DestoryChannel(encoder->pVencCtx);
+ av_free(encoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ // mpp packet init
+ encoder->pPacket = PACKET_Create();
+ if (!encoder->pPacket) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC packet.\n");
+ VENC_DestoryChannel(encoder->pVencCtx);
+ av_free(encoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+ PACKET_Alloc(encoder->pPacket, PACKET_SIZE);
+
+ // mpp frame init
+ encoder->pFrame = FRAME_Create();
+ if (!encoder->pFrame) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to initialize STCODEC frame.\n");
+ PACKET_Destory(encoder->pPacket);
+ VENC_DestoryChannel(encoder->pVencCtx);
+ av_free(encoder);
+ ret = AVERROR_UNKNOWN;
+ goto fail;
+ }
+
+ VENC_SetParam(encoder->pVencCtx, &(encoder->pVencCtx->stVencPara));
+
+ /*
+ // make decode calls blocking with a timeout
+ paramS32 = MPP_POLL_BLOCK;
+ ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK,
+ &paramS32);
+
+ paramS64 = RECEIVE_FRAME_TIMEOUT;
+ ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT,
+ &paramS64);
+
+ ret = mpp_buffer_group_get_internal(&decoder->frame_group,
+ MPP_BUFFER_TYPE_ION);
+ ret = decoder->mpi->control(decoder->ctx, MPP_DEC_SET_EXT_BUF_GROUP,
+ decoder->frame_group);
+
+ ret = mpp_buffer_group_limit_config(decoder->frame_group, 0,
+ FRAMEGROUP_MAX_FRAMES);
+ */
+ // decoder->first_packet = 1;
+
+ av_log(avctx, AV_LOG_DEBUG, "STCODEC encoder initialized successfully.\n");
+ /*
+ encoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM);
+ if (!encoder->device_ref) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_alloc\n");
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ ret = av_hwdevice_ctx_init(encoder->device_ref);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_init\n");
+ goto fail;
+ }
+
+ AVHWFramesContext* hwframes;
+ avctx->width = avctx->width;
+ avctx->height = avctx->height;
+ encoder->frames_ref = av_hwframe_ctx_alloc(encoder->device_ref);
+ if (!encoder->frames_ref) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ hwframes = (AVHWFramesContext*)encoder->frames_ref->data;
+ hwframes->format = AV_PIX_FMT_YUV420P;//AV_PIX_FMT_DRM_PRIME;
+ hwframes->sw_format = AV_PIX_FMT_YUV420P;
+ hwframes->width = avctx->width;
+ hwframes->height = avctx->height;
+ ret = av_hwframe_ctx_init(encoder->frames_ref);
+ if (ret < 0) goto fail;
+ */
+ av_log(avctx, AV_LOG_ERROR, "Initialized successfully.\n");
+ return 0;
+
+fail:
+ av_log(avctx, AV_LOG_ERROR,
+ "Failed to initialize STCODEC encoder, please check!\n");
+ stcodec_close_encoder(avctx);
+ return ret;
+}
+
+static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
+ HW_CONFIG_INTERNAL(DRM_PRIME), NULL};
+
+#define STCODEC_ENC_CLASS(NAME) \
+ static const AVClass stcodec_##NAME##_enc_class = { \
+ .class_name = "stcodec_" #NAME "_enc", \
+ .version = LIBAVUTIL_VERSION_INT, \
+ };
+
+#define STCODEC_ENC(NAME, ID) \
+ STCODEC_ENC_CLASS(NAME) \
+ AVCodec ff_##NAME##_stcodec_encoder = { \
+ .name = #NAME "_stcodec", \
+ .long_name = NULL_IF_CONFIG_SMALL(#NAME " (stcodec encoder)"), \
+ .type = AVMEDIA_TYPE_VIDEO, \
+ .id = ID, \
+ .priv_data_size = sizeof(STCODECEncodeContext), \
+ .priv_class = &stcodec_##NAME##_enc_class, \
+ .init = stcodec_init_encoder, \
+ .receive_packet = stcodec_receive_packet, \
+ .close = stcodec_close_encoder, \
+ .capabilities = AV_CODEC_CAP_HARDWARE | AV_CODEC_CAP_DELAY, \
+ .wrapper_name = "stcodec", \
+ .pix_fmts = \
+ (const enum AVPixelFormat[]){AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NV12, \
+ AV_PIX_FMT_NONE}, \
+ .hw_configs = stcodec_hw_configs, \
+ };
+
+STCODEC_ENC(h264, AV_CODEC_ID_H264)
+STCODEC_ENC(hevc, AV_CODEC_ID_HEVC)
+STCODEC_ENC(mjpeg, AV_CODEC_ID_MJPEG)
--
2.25.1

View file

@ -0,0 +1,327 @@
From 23c0a7e3fb8f22afe6513e5d72c61302f04901ad Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Sun, 7 Apr 2024 15:34:13 +0800
Subject: [PATCH] ffmpeg: optimize stcodecenc logic
---
libavcodec/stcodecenc.c | 221 +++++++++++++++-------------------------
1 file changed, 81 insertions(+), 140 deletions(-)
diff --git a/libavcodec/stcodecenc.c b/libavcodec/stcodecenc.c
index eeaa41a..30025e2 100755
--- a/libavcodec/stcodecenc.c
+++ b/libavcodec/stcodecenc.c
@@ -53,12 +53,6 @@ typedef struct {
MppVencCtx* pVencCtx;
MppPacket* pPacket;
MppFrame* pFrame;
-
- char first_packet;
- char eos_reached;
-
- AVBufferRef* frames_ref;
- AVBufferRef* device_ref;
} STCODECEncoder;
typedef struct {
@@ -66,11 +60,6 @@ typedef struct {
AVBufferRef* encoder_ref;
} STCODECEncodeContext;
-typedef struct {
- MppFrame* pFrame;
- AVBufferRef* encoder_ref;
-} STCODECFrameContext;
-
static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
switch (avctx->codec_id) {
case AV_CODEC_ID_H264:
@@ -92,22 +81,35 @@ static int get_stride(int width, int align) {
return (width + align - 1) & (~(align - 1));
}
-static int stcodec_send_frame(AVCodecContext* avctx, const AVFrame* frame) {
+static int stcodec_receive_packet(AVCodecContext* avctx, AVPacket* avpkt) {
STCODECEncodeContext* st_context = avctx->priv_data;
STCODECEncoder* encoder = (STCODECEncoder*)st_context->encoder_ref->data;
int ret = -1;
+ int index = -1;
+ AVFrame* frame = av_frame_alloc();
+
+ ret = ff_encode_get_frame(avctx, frame);
+ if (ret < 0 && ret != AVERROR_EOF) {
+ av_log(avctx, AV_LOG_DEBUG, "ff_encode_get_frame fail, return\n");
+ return ret;
+ }
+
+ if (ret == AVERROR_EOF) {
+ av_log(avctx, AV_LOG_ERROR, "ff_encode_get_frame get EOS\n");
+ frame = NULL;
+ }
if (frame != NULL) {
- av_log(avctx, AV_LOG_ERROR, "@@@@@@@@ format:%d fd:%d %p %p\n",
- frame->format,
- ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].fd,
- frame->data[0], frame->data[1]);
FRAME_SetEos(encoder->pFrame, 0);
if (frame->format == AV_PIX_FMT_NV12) {
FRAME_SetDataUsedNum(encoder->pFrame, 2);
FRAME_SetDataPointer(encoder->pFrame, 0, frame->data[0]);
FRAME_SetDataPointer(encoder->pFrame, 1, frame->data[1]);
- // FRAME_SetDataPointer(encoder->pFrame, 2, frame->data[2]);
+ } else if (frame->format == AV_PIX_FMT_YUV420P) {
+ FRAME_SetDataUsedNum(encoder->pFrame, 3);
+ FRAME_SetDataPointer(encoder->pFrame, 0, frame->data[0]);
+ FRAME_SetDataPointer(encoder->pFrame, 1, frame->data[1]);
+ FRAME_SetDataPointer(encoder->pFrame, 2, frame->data[3]);
} else if (frame->format == AV_PIX_FMT_DRM_PRIME) {
void* vaddr =
mmap(NULL, ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].size,
@@ -117,74 +119,61 @@ static int stcodec_send_frame(AVCodecContext* avctx, const AVFrame* frame) {
FRAME_SetDataPointer(encoder->pFrame, 0, (U8*)vaddr);
FRAME_SetDataPointer(encoder->pFrame, 1,
((U8*)vaddr) + frame->width * frame->height);
- // FRAME_SetDataPointer(encoder->pFrame, 2,
- // ((U8*)vaddr) + frame->width * frame->height * 5 /
- // 4);
} else {
+ av_log(avctx, AV_LOG_ERROR, "format(%d) not support!", frame->format);
}
- ret = VENC_Encode(encoder->pVencCtx, FRAME_GetBaseData(encoder->pFrame));
- } else {
- FRAME_SetEos(encoder->pFrame, 1);
- av_log(avctx, AV_LOG_ERROR, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bigbig %d\n",
- FRAME_GetEos(encoder->pFrame));
- // FRAME_SetDataUsedNum(encoder->pFrame, 0);
- ret = VENC_Encode(encoder->pVencCtx, FRAME_GetBaseData(encoder->pFrame));
- }
- return ret;
-}
+ ret = VENC_SendInputFrame(encoder->pVencCtx,
+ FRAME_GetBaseData(encoder->pFrame));
+ do {
+ ret = VENC_GetOutputStreamBuffer(encoder->pVencCtx,
+ PACKET_GetBaseData(encoder->pPacket));
+ if (ret == MPP_OK) {
+ avpkt->size = PACKET_GetLength(encoder->pPacket);
+ av_new_packet(avpkt, avpkt->size);
+ memcpy(avpkt->data, PACKET_GetDataPointer(encoder->pPacket),
+ avpkt->size);
+ }
+ } while (ret != MPP_OK);
-static int stcodec_receive_packet(AVCodecContext* avctx, AVPacket* avpkt) {
- STCODECEncodeContext* st_context = avctx->priv_data;
- STCODECEncoder* encoder = (STCODECEncoder*)st_context->encoder_ref->data;
- int ret = -1;
- AVFrame* frame = av_frame_alloc();
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 0.\n");
- // if (!frame->buf[0]) {
- ret = ff_encode_get_frame(avctx, frame);
+ index = -1;
+ do {
+ index = VENC_ReturnInputFrame(encoder->pVencCtx, NULL);
+ if (index >= 0) {
+ av_log(avctx, AV_LOG_DEBUG, "a frame return");
+ }
+ } while (index == -1);
+ } else {
+ FRAME_SetEos(encoder->pFrame, FRAME_EOS_WITHOUT_DATA);
+ ret = VENC_SendInputFrame(encoder->pVencCtx,
+ FRAME_GetBaseData(encoder->pFrame));
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 0. RET = %d\n",
- ret);
- if (ret < 0 && ret != AVERROR_EOF) return ret;
+ do {
+ ret = VENC_GetOutputStreamBuffer(encoder->pVencCtx,
+ PACKET_GetBaseData(encoder->pPacket));
+ if (ret == MPP_OK || ret == MPP_CODER_EOS) {
+ avpkt->size = PACKET_GetLength(encoder->pPacket);
+ av_new_packet(avpkt, avpkt->size);
+ memcpy(avpkt->data, PACKET_GetDataPointer(encoder->pPacket),
+ avpkt->size);
+ }
+ } while (ret != MPP_OK && ret != MPP_CODER_EOS);
- if (ret == AVERROR_EOF) {
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 get eos\n");
- frame = NULL;
+ index = -1;
+ do {
+ index = VENC_ReturnInputFrame(encoder->pVencCtx, NULL);
+ if (index >= 0) {
+ av_log(avctx, AV_LOG_DEBUG, "a frame return");
+ }
+ } while (index != -1);
}
- //}
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 1.\n");
- ret = stcodec_send_frame(avctx, frame);
- if (ret != AVERROR(EAGAIN)) av_frame_unref(frame);
- if (ret < 0 && ret != AVERROR(EAGAIN)) return ret;
+ usleep(1000);
+ if (ret != AVERROR(EAGAIN)) av_frame_unref(frame);
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 2.\n");
- // return ff_v4l2_context_dequeue_packet(capture, avpkt);
-haha:
- ret = VENC_RequestOutputStreamBuffer(encoder->pVencCtx,
- PACKET_GetBaseData(encoder->pPacket));
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 2. ret = %d\n",
- ret);
- if (ret == MPP_OK) {
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 3.\n");
- avpkt->size = PACKET_GetLength(encoder->pPacket);
- av_log(avctx, AV_LOG_DEBUG, "1111111111111111111111111111111 4. %d=%d %p\n",
- PACKET_GetLength(encoder->pPacket), avpkt->size,
- PACKET_GetDataPointer(encoder->pPacket));
- av_new_packet(avpkt, avpkt->size);
- memcpy(avpkt->data, PACKET_GetDataPointer(encoder->pPacket), avpkt->size);
- av_log(avctx, AV_LOG_ERROR, "1111111111111111111111111111111 5.\n");
- VENC_ReturnOutputStreamBuffer(encoder->pVencCtx,
- PACKET_GetBaseData(encoder->pPacket));
- } else if (ret == MPP_CODER_NO_DATA) {
- av_log(avctx, AV_LOG_ERROR, "get no data.\n");
- // return AVERROR(EAGAIN);
- goto haha;
- } else if (ret == MPP_CODER_EOS) {
- av_log(avctx, AV_LOG_ERROR, "get EOS.\n");
+ if (ret == MPP_CODER_EOS) {
+ av_log(avctx, AV_LOG_ERROR, "get final EOS.\n");
return AVERROR_EOF;
- } else {
- av_log(avctx, AV_LOG_ERROR, "get ???. %d\n", ret);
}
return 0;
@@ -199,14 +188,25 @@ static av_cold int stcodec_close_encoder(AVCodecContext* avctx) {
static void stcodec_release_encoder(void* opaque, uint8_t* data) {
STCODECEncoder* encoder = (STCODECEncoder*)data;
+
+ if (encoder->pPacket) {
+ // PACKET_Free(decoder->pPacket);
+ PACKET_Destory(encoder->pPacket);
+ encoder->pPacket = NULL;
+ }
+
+ if (encoder->pFrame) {
+ FRAME_Destory(encoder->pFrame);
+ encoder->pFrame = NULL;
+ }
+
if (encoder->pVencCtx) {
av_log(NULL, AV_LOG_ERROR, "stcodec release encoder\n");
VENC_ResetChannel(encoder->pVencCtx);
VENC_DestoryChannel(encoder->pVencCtx);
encoder->pVencCtx = NULL;
}
- av_buffer_unref(&encoder->frames_ref);
- av_buffer_unref(&encoder->device_ref);
+
av_free(encoder);
}
@@ -217,8 +217,8 @@ static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
MppCodingType codectype = CODING_UNKNOWN;
int ret;
- if (avctx->width > 4096 || avctx->height > 2160 || avctx->width <= 640 ||
- avctx->height <= 480) {
+ if (avctx->width > 4096 || avctx->height > 4096 || avctx->width < 640 ||
+ avctx->height < 360) {
av_log(avctx, AV_LOG_ERROR,
"STCODEC-ENC do not support the size, too big or too small!\n");
ret = AVERROR_UNKNOWN;
@@ -259,13 +259,6 @@ static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
ret = AVERROR_UNKNOWN;
goto fail;
}
- /*
- ret = mpp_check_support_format(MPP_CTX_DEC, codectype);
- if (ret != MPP_OK) {
- av_log(avctx, AV_LOG_ERROR, "Codec type (%d) unsupported by MPP\n",
- avctx->codec_id); ret = AVERROR_UNKNOWN; goto fail;
- }
- */
// Create the MPP context
encoder->pVencCtx = VENC_CreateChannel();
@@ -282,9 +275,9 @@ static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
encoder->pVencCtx->stVencPara.nHeight = avctx->height;
encoder->pVencCtx->stVencPara.nStride = get_stride(avctx->width, 8);
encoder->pVencCtx->stVencPara.PixelFormat = PIXEL_FORMAT_NV12;
+ encoder->pVencCtx->stVencPara.eFrameBufferType =
+ MPP_FRAME_BUFFERTYPE_NORMAL_EXTERNAL;
encoder->pVencCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
- encoder->pVencCtx->stVencPara.nBitrate = 5000000;
- encoder->pVencCtx->stVencPara.nFrameRate = 30;
av_log(avctx, AV_LOG_ERROR, "(widthxheight = %d x %d).\n", avctx->width,
avctx->height);
@@ -321,58 +314,6 @@ static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
goto fail;
}
- VENC_SetParam(encoder->pVencCtx, &(encoder->pVencCtx->stVencPara));
-
- /*
- // make decode calls blocking with a timeout
- paramS32 = MPP_POLL_BLOCK;
- ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK,
- &paramS32);
-
- paramS64 = RECEIVE_FRAME_TIMEOUT;
- ret = decoder->mpi->control(decoder->ctx, MPP_SET_OUTPUT_BLOCK_TIMEOUT,
- &paramS64);
-
- ret = mpp_buffer_group_get_internal(&decoder->frame_group,
- MPP_BUFFER_TYPE_ION);
- ret = decoder->mpi->control(decoder->ctx, MPP_DEC_SET_EXT_BUF_GROUP,
- decoder->frame_group);
-
- ret = mpp_buffer_group_limit_config(decoder->frame_group, 0,
- FRAMEGROUP_MAX_FRAMES);
- */
- // decoder->first_packet = 1;
-
- av_log(avctx, AV_LOG_DEBUG, "STCODEC encoder initialized successfully.\n");
- /*
- encoder->device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DRM);
- if (!encoder->device_ref) {
- av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_alloc\n");
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- ret = av_hwdevice_ctx_init(encoder->device_ref);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Failed to av_hwdevice_ctx_init\n");
- goto fail;
- }
-
- AVHWFramesContext* hwframes;
- avctx->width = avctx->width;
- avctx->height = avctx->height;
- encoder->frames_ref = av_hwframe_ctx_alloc(encoder->device_ref);
- if (!encoder->frames_ref) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- hwframes = (AVHWFramesContext*)encoder->frames_ref->data;
- hwframes->format = AV_PIX_FMT_YUV420P;//AV_PIX_FMT_DRM_PRIME;
- hwframes->sw_format = AV_PIX_FMT_YUV420P;
- hwframes->width = avctx->width;
- hwframes->height = avctx->height;
- ret = av_hwframe_ctx_init(encoder->frames_ref);
- if (ret < 0) goto fail;
- */
av_log(avctx, AV_LOG_ERROR, "Initialized successfully.\n");
return 0;
--
2.25.1

View file

@ -0,0 +1,53 @@
From 4fd5362fcef8f8d7c10dd1624c40d29880a03324 Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Sun, 7 Apr 2024 19:46:55 +0800
Subject: [PATCH] fix bug: video transcoding blur
---
libavcodec/stcodecdec.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
index 66b1305..6acb89f 100755
--- a/libavcodec/stcodecdec.c
+++ b/libavcodec/stcodecdec.c
@@ -251,8 +251,8 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
MppCodingType codectype = CODING_UNKNOWN;
int ret;
- if ((avctx->width > 4096 || avctx->height > 2304 || avctx->width <= 640 ||
- avctx->height <= 480) &&
+ if ((avctx->width > 4096 || avctx->height > 4096 || avctx->width < 640 ||
+ avctx->height < 320) &&
(avctx->width != 0 || avctx->height != 0)) {
av_log(avctx, AV_LOG_ERROR,
"STCODEC Decoder do not support the size (%d x %d), too big or too "
@@ -312,7 +312,15 @@ static int stcodec_init_decoder(AVCodecContext* avctx) {
decoder->pVdecCtx->stVdecPara.nWidth = avctx->width;
decoder->pVdecCtx->stVdecPara.nHeight = avctx->height;
decoder->pVdecCtx->stVdecPara.nStride = get_stride(avctx->width, 8);
- decoder->pVdecCtx->stVdecPara.eOutputPixelFormat = stcodec_get_pixelformat(avctx);
+ decoder->pVdecCtx->stVdecPara.eOutputPixelFormat =
+ stcodec_get_pixelformat(avctx);
+ if (avctx->pix_fmt == AV_PIX_FMT_DRM_PRIME) {
+ decoder->pVdecCtx->stVdecPara.eFrameBufferType =
+ MPP_FRAME_BUFFERTYPE_DMABUF_INTERNAL;
+ } else {
+ decoder->pVdecCtx->stVdecPara.eFrameBufferType =
+ MPP_FRAME_BUFFERTYPE_NORMAL_INTERNAL;
+ }
decoder->pVdecCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
if (avctx->width >= 3840 || avctx->height >= 2160) {
av_log(avctx, AV_LOG_ERROR, "4K video, downscale!\n");
@@ -665,7 +673,7 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
frame->linesize[0] = get_stride(avctx->width, 8);
frame->linesize[1] = get_stride(avctx->width, 8);
frame->data[0] = FRAME_GetDataPointer(mppframe, 0);
- frame->data[1] = frame->data[0] + frame->width * frame->height;
+ frame->data[1] = FRAME_GetDataPointer(mppframe, 1);
frame->buf[0] = av_buffer_create(
(uint8_t*)(frame->data[0]), sizeof(frame->data[0]),
stcodec_release_frame, framecontextref, AV_BUFFER_FLAG_READONLY);
--
2.25.1

View file

@ -0,0 +1,76 @@
From 65302ef6df4dd3a8228e0347163aa6d91e82991c Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Mon, 8 Apr 2024 15:41:53 +0800
Subject: [PATCH] stcodecenc support YUV420P and fix some small bugs
---
libavcodec/stcodecdec.c | 1 +
libavcodec/stcodecenc.c | 19 ++++++++++++++++---
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/libavcodec/stcodecdec.c b/libavcodec/stcodecdec.c
index 6acb89f..0300554 100755
--- a/libavcodec/stcodecdec.c
+++ b/libavcodec/stcodecdec.c
@@ -566,6 +566,7 @@ static int stcodec_receive_frame(AVCodecContext* avctx, AVFrame* frame) {
if (ret == MPP_CODER_NO_DATA) {
av_log(avctx, AV_LOG_ERROR, "no data, return\n");
+ usleep(5000);
ret = AVERROR(EAGAIN);
goto fail;
}
diff --git a/libavcodec/stcodecenc.c b/libavcodec/stcodecenc.c
index 30025e2..c976dec 100755
--- a/libavcodec/stcodecenc.c
+++ b/libavcodec/stcodecenc.c
@@ -60,6 +60,19 @@ typedef struct {
AVBufferRef* encoder_ref;
} STCODECEncodeContext;
+static MppPixelFormat stcodec_get_pixelformat(AVCodecContext* avctx) {
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_NV12:
+ return PIXEL_FORMAT_NV12;
+ case AV_PIX_FMT_YUV420P:
+ return PIXEL_FORMAT_I420;
+ case AV_PIX_FMT_DRM_PRIME:
+ return PIXEL_FORMAT_NV12;
+ default:
+ return PIXEL_FORMAT_UNKNOWN;
+ }
+}
+
static MppCodingType stcodec_get_codingtype(AVCodecContext* avctx) {
switch (avctx->codec_id) {
case AV_CODEC_ID_H264:
@@ -109,7 +122,7 @@ static int stcodec_receive_packet(AVCodecContext* avctx, AVPacket* avpkt) {
FRAME_SetDataUsedNum(encoder->pFrame, 3);
FRAME_SetDataPointer(encoder->pFrame, 0, frame->data[0]);
FRAME_SetDataPointer(encoder->pFrame, 1, frame->data[1]);
- FRAME_SetDataPointer(encoder->pFrame, 2, frame->data[3]);
+ FRAME_SetDataPointer(encoder->pFrame, 2, frame->data[2]);
} else if (frame->format == AV_PIX_FMT_DRM_PRIME) {
void* vaddr =
mmap(NULL, ((AVDRMFrameDescriptor*)(frame->data[0]))->objects[0].size,
@@ -274,7 +287,7 @@ static av_cold int stcodec_init_encoder(AVCodecContext* avctx) {
encoder->pVencCtx->stVencPara.nWidth = avctx->width;
encoder->pVencCtx->stVencPara.nHeight = avctx->height;
encoder->pVencCtx->stVencPara.nStride = get_stride(avctx->width, 8);
- encoder->pVencCtx->stVencPara.PixelFormat = PIXEL_FORMAT_NV12;
+ encoder->pVencCtx->stVencPara.PixelFormat = stcodec_get_pixelformat(avctx);
encoder->pVencCtx->stVencPara.eFrameBufferType =
MPP_FRAME_BUFFERTYPE_NORMAL_EXTERNAL;
encoder->pVencCtx->eCodecType = CODEC_V4L2_LINLONV5V7;
@@ -349,7 +362,7 @@ static const AVCodecHWConfigInternal* const stcodec_hw_configs[] = {
.wrapper_name = "stcodec", \
.pix_fmts = \
(const enum AVPixelFormat[]){AV_PIX_FMT_DRM_PRIME, AV_PIX_FMT_NV12, \
- AV_PIX_FMT_NONE}, \
+ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE}, \
.hw_configs = stcodec_hw_configs, \
};
--
2.25.1

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,406 @@
diff --git a/ext/spacemit/spacemitcodec/gstspacemitdec.c b/ext/spacemit/spacemitcodec/gstspacemitdec.c
index 6a989e0..48b5b7f 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitdec.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitdec.c
@@ -50,6 +50,7 @@ static GstFlowReturn gst_spacemitdec_finish(GstVideoDecoder *decoder);
static GstFlowReturn gst_spacemitdec_handle_frame(GstVideoDecoder *decoder, GstVideoCodecFrame *frame);
static gboolean gst_spacemitdec_decide_allocation(GstVideoDecoder *decoder, GstQuery *query);
static GstStateChangeReturn gst_spacemitdec_dec_change_state (GstElement * element, GstStateChange transition);
+static GstFlowReturn gst_spacemitdec_parse (GstVideoDecoder * bdec, GstVideoCodecFrame * frame, GstAdapter * adapter, gboolean at_eos);
/* pad templates */
static GstStaticPadTemplate gst_spacemitdec_sink_template =
@@ -73,8 +74,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
"parsed = (boolean) true,"
"systemstream = (boolean) false"
";"
- "image/jpeg"
- ";"
+// "image/jpeg"
+// ";"
"video/x-vp8"
";"
"video/x-vp9"
@@ -204,6 +205,7 @@ static void gst_spacemitdec_class_init(GstSpacemitDecClass * klass)
video_decoder_class->finish = GST_DEBUG_FUNCPTR(gst_spacemitdec_finish);
video_decoder_class->handle_frame = GST_DEBUG_FUNCPTR(gst_spacemitdec_handle_frame);
video_decoder_class->decide_allocation = GST_DEBUG_FUNCPTR(gst_spacemitdec_decide_allocation);
+ video_decoder_class->parse = gst_spacemitdec_parse;
// element_class->change_state = GST_DEBUG_FUNCPTR (gst_spacemitdec_dec_change_state);
@@ -359,6 +361,9 @@ static gboolean gst_spacemitdec_start (GstVideoDecoder * decoder)
if (thiz->save_dec)
thiz->fb = fopen("/tmp/spacemitdec_out.yuv", "wb+");
+ thiz->saw_header = FALSE;
+ thiz->parse_entropy_len = 0;
+ thiz->parse_resync = FALSE;
GST_DEBUG_OBJECT (thiz, "finish start ! (%d)", thiz->save_dec);
return TRUE;
@@ -370,6 +375,10 @@ static gboolean gst_spacemitdec_stop(GstVideoDecoder * decoder)
if (thiz->save_dec)
fclose(thiz->fb);
+ thiz->parse_entropy_len = 0;
+ thiz->parse_resync = FALSE;
+ thiz->saw_header = FALSE;
+
if (!(gst_pad_get_task_state ((decoder)->srcpad) == GST_TASK_STARTED)) {
GST_DEBUG_OBJECT (thiz, "ZRong --------------- spacemitdec finish stop");
return TRUE;
@@ -436,7 +445,8 @@ gst_spacemitdec_init_decoder (GstSpacemitDec * thiz)
thiz->ctx->stVdecPara.bInputBlockModeEnable = MPP_TRUE;
thiz->ctx->stVdecPara.bOutputBlockModeEnable = MPP_TRUE;
- GST_DEBUG_OBJECT (thiz, "spacemitdec set eCodecType is %d, downscale:%u", thiz->ctx->eCodecType, thiz->downscale);
+ GST_DEBUG_OBJECT (thiz, "spacemitdec set eCodecType is %d, downscale:%u, eCodingType:%d",
+ thiz->ctx->eCodecType, thiz->downscale, thiz->eCodingType);
ret = VDEC_Init (thiz->ctx);
if (ret) {
@@ -460,6 +470,7 @@ static gboolean gst_spacemitdec_set_format(GstVideoDecoder * decoder, GstVideoCo
GstSpacemitDec *thiz = GST_SPACEMITDEC(decoder);
GstStructure *structure;
gboolean ret = TRUE;
+ gboolean parsed = FALSE;
GST_DEBUG_OBJECT(thiz, "input caps: %" GST_PTR_FORMAT, state->caps);
@@ -473,11 +484,16 @@ static gboolean gst_spacemitdec_set_format(GstVideoDecoder * decoder, GstVideoCo
if (!gst_spacemitdec_init_decoder(thiz))
return FALSE;
- GST_DEBUG_OBJECT (thiz, "@@@ ZRong ------------------------- set_format (%d, %d, %d), (%d, %d, %d)",
+ if (thiz->eCodingType == CODING_MJPEG) {
+ structure = gst_caps_get_structure (state->caps, 0);
+ gst_structure_get_boolean (structure, "parsed", &parsed);
+ gst_video_decoder_set_packetized (thiz, parsed);
+ }
+ GST_DEBUG_OBJECT (thiz, "set format finish (%d, %d, %d), (%d, %d, %d)",
thiz->input_state->info.width, thiz->input_state->info.height, thiz->input_state->info.size,
state->info.width, state->info.height, state->info.size);
- GST_DEBUG_OBJECT (thiz, "ZRong ----------------------- set format finish, %u, %s",
- GST_VIDEO_INFO_FORMAT (&state->info), gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&state->info)));
+ GST_DEBUG_OBJECT (thiz, "set format finish (%u, %s), parsed: %d",
+ GST_VIDEO_INFO_FORMAT (&state->info), gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&state->info)), parsed);
return TRUE;
}
@@ -1130,6 +1146,202 @@ flushing:
}
}
+static inline gboolean
+gst_spacemitdec_parse_tag_has_entropy_segment (guint8 tag)
+{
+ if (tag == 0xda || (tag >= 0xd0 && tag <= 0xd7))
+ return TRUE;
+ return FALSE;
+}
+
+//code from jpegdec
+static GstFlowReturn
+gst_spacemitdec_parse (GstVideoDecoder * bdec, GstVideoCodecFrame * frame,
+ GstAdapter * adapter, gboolean at_eos)
+{
+ guint size;
+ gint toadd = 0;
+ gboolean resync;
+ gint offset = 0, noffset;
+ GstSpacemitDec *thiz = GST_SPACEMITDEC (bdec);
+
+ if (thiz->eCodingType != CODING_MJPEG) {
+ GST_ERROR_OBJECT (thiz, "only support mjpeg for parse, eCodingType:%d", thiz->eCodingType);
+ return GST_FLOW_ERROR;
+ }
+
+ GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
+
+ /* FIXME : The overhead of using scan_uint32 is massive */
+
+ size = gst_adapter_available (adapter);
+ GST_DEBUG_OBJECT (thiz, "Parsing jpeg image data (%u bytes)", size);
+
+ if (at_eos) {
+ GST_DEBUG_OBJECT (thiz, "Flushing all data out");
+ toadd = size;
+
+ /* If we have leftover data, throw it away */
+ if (!thiz->saw_header)
+ goto drop_frame;
+ goto have_full_frame;
+ }
+
+ if (size < 8)
+ goto need_more_data;
+
+ if (!thiz->saw_header) {
+ gint ret;
+ /* we expect at least 4 bytes, first of which start marker */
+ ret =
+ gst_adapter_masked_scan_uint32 (adapter, 0xffff0000, 0xffd80000, 0,
+ size - 4);
+
+ GST_DEBUG_OBJECT (thiz, "ret:%d", ret);
+ if (ret < 0)
+ goto need_more_data;
+
+ if (ret) {
+ gst_adapter_flush (adapter, ret);
+ size -= ret;
+ }
+ thiz->saw_header = TRUE;
+ }
+
+ while (1) {
+ guint frame_len;
+ guint32 value;
+
+ GST_DEBUG_OBJECT (thiz, "offset:%d, size:%d", offset, size);
+
+ noffset =
+ gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
+ offset, size - offset, &value);
+
+ /* lost sync if 0xff marker not where expected */
+ if ((resync = (noffset != offset))) {
+ GST_DEBUG_OBJECT (thiz, "Lost sync at 0x%08x, resyncing", offset + 2);
+ }
+ /* may have marker, but could have been resyncng */
+ resync = resync || thiz->parse_resync;
+ /* Skip over extra 0xff */
+ while ((noffset >= 0) && ((value & 0xff) == 0xff)) {
+ noffset++;
+ noffset =
+ gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00, 0x0000ff00,
+ noffset, size - noffset, &value);
+ }
+ /* enough bytes left for marker? (we need 0xNN after the 0xff) */
+ if (noffset < 0) {
+ GST_DEBUG_OBJECT (thiz, "at end of input and no EOI marker found, need more data");
+ goto need_more_data;
+ }
+
+ /* now lock on the marker we found */
+ offset = noffset;
+ value = value & 0xff;
+ if (value == 0xd9) {
+ GST_DEBUG_OBJECT (thiz, "0x%08x: EOI marker", offset + 2);
+ /* clear parse state */
+ thiz->saw_header = FALSE;
+ thiz->parse_resync = FALSE;
+ toadd = offset + 4;
+ goto have_full_frame;
+ }
+ if (value == 0xd8) {
+ GST_DEBUG_OBJECT (thiz, "0x%08x: SOI marker before EOI marker", offset + 2);
+
+ /* clear parse state */
+ thiz->saw_header = FALSE;
+ thiz->parse_resync = FALSE;
+ toadd = offset;
+ goto have_full_frame;
+ }
+
+
+ if (value >= 0xd0 && value <= 0xd7)
+ frame_len = 0;
+ else {
+ /* peek tag and subsequent length */
+ if (offset + 2 + 4 > size)
+ goto need_more_data;
+ else
+ gst_adapter_masked_scan_uint32_peek (adapter, 0x0, 0x0, offset + 2, 4,
+ &frame_len);
+ frame_len = frame_len & 0xffff;
+ }
+ GST_DEBUG_OBJECT (thiz, "0x%08x: tag %02x, frame_len=%u", offset + 2, value, frame_len);
+ /* the frame length includes the 2 bytes for the length; here we want at
+ * least 2 more bytes at the end for an end marker */
+ if (offset + 2 + 2 + frame_len + 2 > size) {
+ goto need_more_data;
+ }
+
+ if (gst_spacemitdec_parse_tag_has_entropy_segment (value)) {
+ guint eseglen = thiz->parse_entropy_len;
+
+ GST_DEBUG_OBJECT (thiz, "0x%08x: finding entropy segment length (eseglen:%d)",
+ offset + 2, eseglen);
+ if (size < offset + 2 + frame_len + eseglen)
+ goto need_more_data;
+ noffset = offset + 2 + frame_len + thiz->parse_entropy_len;
+ while (1) {
+ GST_DEBUG_OBJECT (thiz, "noffset:%d, size:%d, size - noffset:%d",
+ noffset, size, size - noffset);
+ noffset = gst_adapter_masked_scan_uint32_peek (adapter, 0x0000ff00,
+ 0x0000ff00, noffset, size - noffset, &value);
+ if (noffset < 0) {
+ /* need more data */
+ thiz->parse_entropy_len = size - offset - 4 - frame_len - 2;
+ goto need_more_data;
+ }
+ if ((value & 0xff) != 0x00) {
+ eseglen = noffset - offset - frame_len - 2;
+ break;
+ }
+ noffset++;
+ }
+ thiz->parse_entropy_len = 0;
+ frame_len += eseglen;
+ GST_DEBUG_OBJECT (thiz, "entropy segment length=%u => frame_len=%u", eseglen,
+ frame_len);
+ }
+ if (resync) {
+ /* check if we will still be in sync if we interpret
+ * this as a sync point and skip this frame */
+ noffset = offset + frame_len + 2;
+ noffset = gst_adapter_masked_scan_uint32 (adapter, 0x0000ff00, 0x0000ff00,
+ noffset, 4);
+ if (noffset < 0) {
+ /* ignore and continue resyncing until we hit the end
+ * of our data or find a sync point that looks okay */
+ offset++;
+ continue;
+ }
+ GST_DEBUG_OBJECT (thiz, "found sync at 0x%x", offset + 2);
+ }
+
+ /* Add current data to output buffer */
+ toadd += frame_len + 2;
+ offset += frame_len + 2;
+ }
+
+need_more_data:
+ if (toadd)
+ gst_video_decoder_add_to_frame (bdec, toadd);
+ return GST_VIDEO_DECODER_FLOW_NEED_DATA;
+
+have_full_frame:
+ if (toadd)
+ gst_video_decoder_add_to_frame (bdec, toadd);
+ GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (frame);
+ return gst_video_decoder_have_frame (bdec);
+
+drop_frame:
+ gst_adapter_flush (adapter, size);
+ return GST_FLOW_OK;
+}
+
static GstFlowReturn gst_spacemitdec_finish(GstVideoDecoder * decoder)
{
GstSpacemitDec *thiz = GST_SPACEMITDEC(decoder);
diff --git a/ext/spacemit/spacemitcodec/gstspacemitdec.h b/ext/spacemit/spacemitcodec/gstspacemitdec.h
index 99cfd31..0b0bc22 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitdec.h
+++ b/ext/spacemit/spacemitcodec/gstspacemitdec.h
@@ -69,6 +69,11 @@ struct _GstSpacemitDec
gboolean wait_reschange;
GstBufferPool *pool;
FILE *fb;
+
+ /* parse state */
+ gboolean saw_header;
+ gint parse_entropy_len;
+ gint parse_resync;
};
struct _GstSpacemitDecClass
diff --git a/ext/spacemit/spacemitcodec/gstspacemitenc.c b/ext/spacemit/spacemitcodec/gstspacemitenc.c
index a0c0370..ba9ab6a 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitenc.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitenc.c
@@ -529,8 +529,6 @@ release_all_buffer (gpointer key, gpointer value, gpointer user_data)
GstBuffer *buffer = (GstBuffer *)value;
GstSpacemitEnc *thiz = (GstSpacemitEnc *)user_data;
- g_hash_table_remove(thiz->bufs_hash, key);
-
GST_DEBUG_OBJECT (thiz, "release buffer %p, before release ref: %d", buffer, GST_MINI_OBJECT_REFCOUNT_VALUE(buffer));
gst_buffer_unref (buffer);
}
@@ -553,6 +551,7 @@ static void drain_all_upstream_buffer (GstSpacemitEnc * thiz)
g_hash_table_size(thiz->bufs_hash), try_count);
g_hash_table_foreach (thiz->bufs_hash, release_all_buffer, thiz);
+ g_hash_table_remove_all (thiz->bufs_hash);
}
static gint32 gst_spacemitenc_request_packet (GstSpacemitEnc *thiz)
diff --git a/ext/spacemit/spacemitcodec/gstspacemitplugin.c b/ext/spacemit/spacemitcodec/gstspacemitplugin.c
index d2d5e62..be75339 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitplugin.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitplugin.c
@@ -17,9 +17,9 @@ static gboolean plugin_init(GstPlugin *plugin)
gboolean ret = FALSE;
ret |= gst_spacemitdec_register (plugin, GST_RANK_PRIMARY + 1);
- ret |= gst_spacemitenc_register (plugin, GST_RANK_PRIMARY + 1);
+ ret |= gst_spacemitenc_register (plugin, GST_RANK_PRIMARY - 1);
- return ret;
+ return ret;
}
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
diff --git a/ext/spacemit/spacemitcodec/meson.build b/ext/spacemit/spacemitcodec/meson.build
index c6ed6c3..e7deda1 100755
--- a/ext/spacemit/spacemitcodec/meson.build
+++ b/ext/spacemit/spacemitcodec/meson.build
@@ -6,7 +6,7 @@ spacemitcodec_sources = [
'gstspacemitplugin.c',
]
-spacemitmpp_dep = dependency('spacemit_mpp', version : '>= 0.0.0', required : false)
+spacemitmpp_dep = dependency('spacemit_mpp', version : '>= 0.0.0', required : get_option('spacemitcodec'))
if spacemitmpp_dep.found()
gstspacemitcodec = library('gstspacemitcodec',
diff --git a/ext/spacemit/spacemitsrc/gstspacemitsrc.c b/ext/spacemit/spacemitsrc/gstspacemitsrc.c
index 2384fb9..eafb476 100755
--- a/ext/spacemit/spacemitsrc/gstspacemitsrc.c
+++ b/ext/spacemit/spacemitsrc/gstspacemitsrc.c
@@ -322,6 +322,7 @@ gst_spacemitsrc_set_property (GObject * object, guint property_id,
GstSpacemitSrc *src;
src = GST_SPACEMIT_SRC (object);
+ GST_INFO_OBJECT (src, "in set property :%d", property_id);
switch (property_id) {
case PROP_LOCATION:
@@ -380,6 +381,7 @@ gst_spacemitsrc_get_property (GObject * object, guint property_id,
g_return_if_fail (GST_IS_SPACEMIT_SRC (object));
src = GST_SPACEMIT_SRC (object);
+ GST_INFO_OBJECT (src, "in get property :%d", property_id);
switch (property_id) {
case PROP_LOCATION:
diff --git a/ext/spacemit/spacemitsrc/meson.build b/ext/spacemit/spacemitsrc/meson.build
index bfa0b49..85040a7 100755
--- a/ext/spacemit/spacemitsrc/meson.build
+++ b/ext/spacemit/spacemitsrc/meson.build
@@ -3,7 +3,7 @@ spacemitsrc_sources = [
'gstspmsrcallocator.c',
]
-spacemitcam_dep = dependency('k1x-cam', version : '>= 0.0.0', required : false)
+spacemitcam_dep = dependency('k1x-cam', version : '>= 0.0.0', required : get_option('spacemitsrc'))
gstspacemitsrc = library('gstspacemitsrc',
spacemitsrc_sources,
diff --git a/meson_options.txt b/meson_options.txt
index 3131929..e2e689f 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -184,7 +184,8 @@ option('wpe', type : 'feature', value : 'auto', description : 'WPE Web browser p
option('magicleap', type : 'feature', value : 'auto', description : 'Magic Leap platform support')
option('v4l2codecs', type : 'feature', value : 'auto', description : 'Video4Linux Stateless CODECs support')
option('isac', type : 'feature', value : 'auto', description : 'iSAC plugin')
-option('spacemit', type : 'feature', value : 'auto', description : 'Spacemit encoder/decoder plugin')
+option('spacemitcodec', type : 'feature', value : 'auto', description : 'Spacemit encoder/decoder plugin')
+option('spacemitsrc', type : 'feature', value : 'auto', description : 'Spacemit source plugin')
# HLS plugin options
option('hls', type : 'feature', value : 'auto', description : 'HTTP Live Streaming plugin')

View file

@ -0,0 +1,474 @@
diff --git a/ext/spacemit/spacemitcodec/gstspacemitallocator.c b/ext/spacemit/spacemitcodec/gstspacemitallocator.c
index abb2b84..a677114 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitallocator.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitallocator.c
@@ -112,7 +112,7 @@ static void
gst_spacemit_allocator_finalize (GObject * obj)
{
GstSpaceMitAllocator *alloc = GST_SPACEMIT_ALLOCATOR (obj);
- GST_DEBUG_OBJECT (alloc, "ZRong ------------------- spacemit allocator finalize");
+ GST_DEBUG_OBJECT (alloc, "start allocator finalize, refcount:%d", GST_OBJECT_REFCOUNT_VALUE(alloc));
G_OBJECT_CLASS (parent_class)->finalize (obj);
}
@@ -147,7 +147,7 @@ gst_spacemit_allocator_memory_dispose (GstMemory * base_mem)
/* keep the memory alive */
gst_memory_ref (base_mem);
- GST_DEBUG ("memory dispose success, mem %p fd:(%d, %d), id:%d, base_mem:%p, ref:%d",
+ GST_DEBUG ("memory dispose success, mem %p fd:(%d, %d), id:%d, base_mem:%p, refcount:%d",
mem, mem->fd, fd, mem->mppframe_id, base_mem, base_mem->mini_object.refcount);
mem->acquired = FALSE;
@@ -340,7 +340,7 @@ gst_spacemit_allocator_set_active (GstSpaceMitAllocator * allocator, gboolean ac
if (allocator->active != active)
changed = TRUE;
- GST_DEBUG_OBJECT (allocator, "allocator set active/deactice paras, cur:%d, set:%d", allocator->active, active);
+ GST_DEBUG_OBJECT (allocator, "start allocator set active, cur:%d, set:%d", allocator->active, active);
if (changed) {
if (active) {
@@ -350,7 +350,7 @@ gst_spacemit_allocator_set_active (GstSpaceMitAllocator * allocator, gboolean ac
g_hash_table_foreach (allocator->memories, gst_unref_spacemit_mem, NULL);
g_hash_table_remove_all (allocator->memories);
if (allocator->foreign_allocator) {
- GST_DEBUG_OBJECT (allocator, "ZRong ------------------- allocator unref(%d %d) (%d %d)",
+ GST_DEBUG_OBJECT (allocator, "allocator refcount (%d %d) (%d %d)",
GST_OBJECT_REFCOUNT_VALUE(allocator->foreign_allocator), GST_OBJECT_REFCOUNT(allocator->foreign_allocator),
GST_OBJECT_REFCOUNT_VALUE(allocator), GST_OBJECT_REFCOUNT(allocator));
g_object_unref (allocator->foreign_allocator);
@@ -361,7 +361,7 @@ gst_spacemit_allocator_set_active (GstSpaceMitAllocator * allocator, gboolean ac
allocator->active = active;
g_mutex_unlock (&allocator->lock);
- GST_DEBUG_OBJECT (allocator, "allocator set active/deactice finish");
+ GST_DEBUG_OBJECT (allocator, "finish allocator set active");
return changed;
}
diff --git a/ext/spacemit/spacemitcodec/gstspacemitbufferpool.c b/ext/spacemit/spacemitcodec/gstspacemitbufferpool.c
index cd186ab..771afe2 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitbufferpool.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitbufferpool.c
@@ -41,7 +41,7 @@ static void gst_spacemit_buffer_pool_finalize (GObject * object);
G_DEFINE_TYPE_WITH_CODE (GstSpaceMitBufferPool, gst_spacemit_buffer_pool,
GST_TYPE_BUFFER_POOL,
- GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "SpaceMitbufferpool", 0,
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "spacemitbufferpool", 0,
"spacemit buffer pool"));
static gboolean
@@ -301,11 +301,11 @@ static void
gst_spacemit_buffer_pool_finalize (GObject * object)
{
GstSpaceMitBufferPool *pool = GST_SPACEMIT_BUFFER_POOL (object);
- GST_DEBUG ("ZRong ------------------------af pool finalize.");
+ GST_DEBUG_OBJECT (pool, "start pool finalize.");
if (pool->allocator) {
- GST_DEBUG ("ZRong ------------------- af pool finalize (%d %d)",
- GST_OBJECT_REFCOUNT_VALUE(pool->allocator), GST_OBJECT_REFCOUNT(pool->allocator));
+ GST_DEBUG_OBJECT (pool, "pool allocator refcount: (%d %d)",
+ GST_OBJECT_REFCOUNT_VALUE(pool->allocator), GST_OBJECT_REFCOUNT(pool->allocator));
gst_object_unref (pool->allocator);
}
diff --git a/ext/spacemit/spacemitcodec/gstspacemitdec.c b/ext/spacemit/spacemitcodec/gstspacemitdec.c
index 48b5b7f..8c170e5 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitdec.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitdec.c
@@ -154,26 +154,26 @@ done:
static gboolean gst_spacemitdec_close(GstVideoDecoder * decoder)
{
GstSpacemitDec *thiz = GST_SPACEMITDEC(decoder);
+ GST_DEBUG_OBJECT (decoder, "start close");
if (thiz->input_state)
{
gst_video_codec_state_unref (thiz->input_state);
thiz->input_state = NULL;
}
- GST_DEBUG_OBJECT (decoder, "ZRong --------------- spacemitdec start close");
+
if (thiz->pool) {
+ GST_DEBUG_OBJECT (decoder, "start pool set active: false(%d, %d)",
+ GST_MINI_OBJECT_REFCOUNT_VALUE(thiz->pool),
+ GST_MINI_OBJECT_REFCOUNT_VALUE(GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator));
+
gst_buffer_pool_set_active (thiz->pool, FALSE);
-// gst_spacemit_allocator_wait_inactive (GST_SPACEMIT_BUFFER_POOL_CAST(spacemitdec->pool)->allocator);
+ gst_spacemit_allocator_wait_inactive (GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator);
gst_object_unref (thiz->pool);
thiz->pool = NULL;
}
- GST_DEBUG_OBJECT (decoder, "ZRong --------------- spacemitdec start close222");
-
-// FRAME_Destory(spacemitdec->mppframe);
- PACKET_Destory (thiz->mpppacket);
- VDEC_DestoryChannel (thiz->ctx);
- GST_DEBUG_OBJECT (decoder, "ZRong --------------- spacemitdec finish close");
+ GST_DEBUG_OBJECT (decoder, "finish close");
return TRUE;
}
@@ -263,7 +263,7 @@ gst_spacemitdec_set_property (GObject * object, guint property_id,
{
GstSpacemitDec *thiz = GST_SPACEMITDEC (object);
- GST_DEBUG_OBJECT (thiz, "ZRong ------------------- set_property: %d", property_id);
+ GST_DEBUG_OBJECT (thiz, "set property: %d", property_id);
switch (property_id) {
case PROP_CODE_TYPE:
@@ -293,7 +293,7 @@ gst_spacemitdec_get_property (GObject * object, guint property_id,
{
GstSpacemitDec *thiz = GST_SPACEMITDEC (object);
- GST_DEBUG_OBJECT (thiz, "ZRong ------------------- get_property: %d", property_id);
+ GST_DEBUG_OBJECT (thiz, "get property: %d", property_id);
switch (property_id) {
case PROP_CODE_TYPE:
@@ -372,6 +372,9 @@ static gboolean gst_spacemitdec_start (GstVideoDecoder * decoder)
static gboolean gst_spacemitdec_stop(GstVideoDecoder * decoder)
{
GstSpacemitDec *thiz = GST_SPACEMITDEC(decoder);
+
+ GST_DEBUG_OBJECT (thiz, "start finish stop");
+
if (thiz->save_dec)
fclose(thiz->fb);
@@ -379,13 +382,19 @@ static gboolean gst_spacemitdec_stop(GstVideoDecoder * decoder)
thiz->parse_resync = FALSE;
thiz->saw_header = FALSE;
+ VDEC_DestoryChannel (thiz->ctx);
+ thiz->ctx = NULL;
+
+ PACKET_Destory(thiz->mpppacket);
+ thiz->mpppacket = NULL;
+
if (!(gst_pad_get_task_state ((decoder)->srcpad) == GST_TASK_STARTED)) {
- GST_DEBUG_OBJECT (thiz, "ZRong --------------- spacemitdec finish stop");
+ GST_DEBUG_OBJECT (thiz, "finish stop");
return TRUE;
}
gst_pad_stop_task (decoder->srcpad);
- GST_DEBUG_OBJECT (thiz, "ZRong --------------- spacemitdec finish stop222");
+ GST_DEBUG_OBJECT (thiz, "finish stop222");
return TRUE;
}
@@ -398,6 +407,26 @@ gst_change_mpp_ecoding_type (GstStructure * s)
if (gst_structure_has_name (s, "video/x-h265"))
return CODING_H265;
+ if (gst_structure_has_name (s, "video/mpeg")) {
+ const GValue *value;
+
+ value = gst_structure_get_value (s, "mpegversion");
+ if (!value || !G_VALUE_HOLDS_INT (value)) {
+ GST_ERROR ("Failed to get mpegversion");
+ return CODING_UNKNOWN;
+ }
+ if (g_value_get_int (value) == 4)
+ return CODING_MPEG4;
+ else if (g_value_get_int (value) == 2)
+ return CODING_MPEG2;
+ else if (g_value_get_int (value) == 1) {
+ GST_ERROR ("no support now!!!");
+ return CODING_MPEG1;
+ } else {
+ return CODING_UNKNOWN;
+ }
+ }
+
if (gst_structure_has_name (s, "image/jpeg"))
return CODING_MJPEG;
@@ -442,6 +471,7 @@ gst_spacemitdec_init_decoder (GstSpacemitDec * thiz)
thiz->ctx->stVdecPara.nRotateDegree = 0;
thiz->ctx->stVdecPara.bThumbnailMode = 0;
thiz->ctx->stVdecPara.bIsInterlaced = MPP_FALSE;
+ thiz->ctx->stVdecPara.eFrameBufferType = MPP_FRAME_BUFFERTYPE_DMABUF_INTERNAL;
thiz->ctx->stVdecPara.bInputBlockModeEnable = MPP_TRUE;
thiz->ctx->stVdecPara.bOutputBlockModeEnable = MPP_TRUE;
@@ -511,7 +541,7 @@ gst_spacemitdec_flush (GstVideoDecoder * decoder)
{
GstSpacemitDec *thiz = GST_SPACEMITDEC(decoder);
- GST_DEBUG_OBJECT (thiz, "ZRong -------------------- flushing start, (%d)", thiz->downstream_flow_ret);
+ GST_DEBUG_OBJECT (thiz, "start flush, (%d)", thiz->downstream_flow_ret);
thiz->flushing = TRUE;
@@ -544,7 +574,7 @@ gst_spacemitdec_flush (GstVideoDecoder * decoder)
thiz->flushing = FALSE;
thiz->downstream_flow_ret = GST_FLOW_OK;
- GST_DEBUG_OBJECT (thiz, "ZRong -------------------- flushing stop");
+ GST_DEBUG_OBJECT (thiz, "finish flush");
return TRUE;
}
@@ -715,7 +745,7 @@ static gint32 gst_spacemitdec_request_frame (GstSpacemitDec *thiz)
} while (thiz->req_nonblock);
if (ret == MPP_CODER_EOS)
- FRAME_SetEos (mppframe, TRUE);
+ FRAME_SetEos (mppframe, FRAME_EOS_WITH_DATA);
count = 0;
thiz->mppframe = mppframe;
@@ -788,7 +818,7 @@ gst_spacemitdec_loop (GstVideoDecoder * decoder)
frame, frame->system_frame_number, GST_TIME_ARGS (GST_BUFFER_PTS (frame->input_buffer)),
GST_TIME_ARGS (GST_BUFFER_DTS (frame->input_buffer)), GST_TIME_ARGS (FRAME_GetPts(thiz->mppframe)));
- //frame->pts = FRAME_GetPts(thiz->mppframe);
+ // frame->pts = FRAME_GetPts(thiz->mppframe);
// frame->pts = GST_CLOCK_TIME_NONE;
// frame->dts = FRAME_GetPts(thiz->mppframe);
flow_status = gst_spacemitdec_fill_output_buffer (decoder, &frame->output_buffer);
@@ -832,6 +862,7 @@ done:
flushing:
{
+ thiz->flushing = TRUE;
thiz->downstream_flow_ret = GST_FLOW_FLUSHING;
while (1) {
@@ -884,7 +915,7 @@ gst_spacemitdec_pool_set_active(GstVideoDecoder * decoder)
GstCaps *caps = NULL;
GstVideoInfo vinfo;
- GST_ERROR_OBJECT (thiz, "@@@ ZRong ------------------------- start pool_set_active!");
+ GST_ERROR_OBJECT (thiz, "start spacemitdec pool set active!");
pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (thiz));
if (pool) {
@@ -895,6 +926,7 @@ gst_spacemitdec_pool_set_active(GstVideoDecoder * decoder)
return FALSE;
}
gst_structure_free (config);
+ gst_object_unref (pool);
}
if (caps) {
@@ -934,6 +966,8 @@ gst_spacemitdec_pool_set_active(GstVideoDecoder * decoder)
return FALSE;
}
+ GST_DEBUG_OBJECT (thiz, "finish spacemitdec pool set active, ref count: %d", GST_OBJECT_REFCOUNT_VALUE(thiz->pool));
+
return TRUE;
}
@@ -1078,8 +1112,7 @@ gst_spacemitdec_handle_frame (GstVideoDecoder * decoder,
if (!gst_spacemitdec_set_src_caps (thiz))
goto not_negotiated_err;
- GST_DEBUG_OBJECT (thiz, "start negotiate, %d, %d, %d",
- actual_width, actual_height, thiz->eOutputPixelFormat);
+ GST_DEBUG_OBJECT (thiz, "start negotiate, (%d, %d, %d)", actual_width, actual_height, thiz->eOutputPixelFormat);
if (!gst_video_decoder_negotiate (decoder))
goto not_negotiated_err;
@@ -1088,13 +1121,14 @@ gst_spacemitdec_handle_frame (GstVideoDecoder * decoder,
goto acitve_fail;
}
- if (G_UNLIKELY (!gst_pad_get_task_state ((decoder)->srcpad) == GST_TASK_STARTED)) {
+ if (G_UNLIKELY (!gst_pad_get_task_state ((decoder)->srcpad) == GST_TASK_STARTED) && !thiz->flushing) {
GST_DEBUG_OBJECT (thiz, "start dec thread");
gst_pad_start_task (decoder->srcpad,
(GstTaskFunction) gst_spacemitdec_loop, decoder, NULL);
}
- GST_DEBUG_OBJECT (thiz, "finish dec handle, %d", thiz->downstream_flow_ret);
+ GST_DEBUG_OBJECT (thiz, "finish dec handle, %d, pool refcount:%d",
+ thiz->downstream_flow_ret, GST_OBJECT_REFCOUNT_VALUE(thiz->pool));
ret = thiz->downstream_flow_ret;
out:
@@ -1461,8 +1495,11 @@ static gboolean gst_spacemitdec_decide_allocation(GstVideoDecoder * decoder, Gst
GstCaps *caps = NULL;
GstVideoInfo vinfo;
GstVideoCodecState *output_state;
+ guint num_buffers;
+ GstAllocationParams params;
+ GstAllocator *allocator = NULL;
- GST_DEBUG_OBJECT (thiz, "@@@ ZRong ------------------------- in decide_allocation!");
+ GST_DEBUG_OBJECT (thiz, "start decide_allocation!, query: %" GST_PTR_FORMAT, query);
if (!GST_VIDEO_DECODER_CLASS(gst_spacemitdec_parent_class)->decide_allocation(decoder, query))
return FALSE;
@@ -1471,34 +1508,72 @@ static gboolean gst_spacemitdec_decide_allocation(GstVideoDecoder * decoder, Gst
class ensures that there will always be at least a 0th pool in
the query. */
gst_query_parse_nth_allocation_pool(query, 0, &pool, &size, &min, &max);
- pool_config = gst_buffer_pool_get_config(pool);
- gst_buffer_pool_config_get_params (pool_config, &caps, &size,
- &min, &max);
+ pool_config = gst_buffer_pool_get_config (pool);
+ gst_buffer_pool_config_get_params (pool_config, &caps, &size, &min, &max);
+
+ GST_DEBUG_OBJECT (thiz, "upstream provides the pool is: %" GST_PTR_FORMAT "pool caps: %" GST_PTR_FORMAT, pool, caps);
+
+ gst_object_unref (pool);
- GST_DEBUG_OBJECT (thiz, "get pool caps: %" GST_PTR_FORMAT, caps);
if (_gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
- GST_INFO_OBJECT (thiz, "the spacemit decoder uses DMABuf memory");
+ // GST_INFO_OBJECT (thiz, "the spacemit decoder uses DMABuf memory");
thiz->use_dmabuf = TRUE;
} else {
thiz->use_dmabuf = FALSE;
}
+ i = 0;
+ while (gst_query_get_n_allocation_pools (query) > 0) {
+ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
+ GST_DEBUG_OBJECT (thiz, "%dth pool is %" GST_PTR_FORMAT, i, pool);
+
+ gst_query_remove_nth_allocation_pool (query, 0);
+ if (pool)
+ gst_object_unref (pool);
+ pool = NULL;
+ i++;
+ }
+
+ i = 0;
+ while (gst_query_get_n_allocation_params (query) > 0) {
+ gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
+ GST_DEBUG_OBJECT (thiz, "%dth allocator is %" GST_PTR_FORMAT, i, allocator);
+
+ gst_query_remove_nth_allocation_param (query, 0);
+ if (allocator)
+ gst_object_unref (allocator);
+ allocator = NULL;
+ i++;
+ }
+
/* Decoder always use its own pool. */
if (!thiz->pool) {
output_state = gst_video_decoder_get_output_state (GST_VIDEO_DECODER (thiz));
gst_clear_object (&thiz->pool);
- GST_INFO_OBJECT (thiz, "create new spacemit bufferpool");
- thiz->pool =
- gst_spacemitdec_create_buffer_pool(thiz, &output_state->info, (8 > min) ? 8 : min);
+ num_buffers = (8 > min) ? 8 : min;
+ GST_INFO_OBJECT (thiz, "create new spacemit bufferpool, DMABUF memory: %d, num: %d", thiz->use_dmabuf, num_buffers);
+ thiz->pool = gst_spacemitdec_create_buffer_pool(thiz, &output_state->info, num_buffers);
gst_video_codec_state_unref (output_state);
if (!thiz->pool) {
GST_ERROR_OBJECT (thiz, "failed to create new pool");
goto failed_to_create_pool;
}
+
+ gst_buffer_pool_config_set_params (pool_config, caps, size, num_buffers, num_buffers);
+ gst_buffer_pool_config_set_allocator (pool_config, GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator, &params);
+ gst_query_add_allocation_param (query, GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator, &params);
+ gst_query_add_allocation_pool (query, thiz->pool, size, num_buffers, num_buffers);
+ } else {
+ gst_buffer_pool_config_set_params (pool_config, caps, size, num_buffers, num_buffers);
+ gst_buffer_pool_config_set_allocator (pool_config, GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator, &params);
+ gst_query_add_allocation_param (query, GST_SPACEMIT_BUFFER_POOL_CAST(thiz->pool)->allocator, &params);
+ gst_query_add_allocation_pool (query, thiz->pool, size, num_buffers, num_buffers);
+ // goto no_support;
+ GST_WARNING_OBJECT (thiz, "spacemit pool had setup!");
}
- GST_DEBUG_OBJECT (thiz,
- "upstream provides the pool is: %" GST_PTR_FORMAT, pool);
+
+ GST_DEBUG_OBJECT (thiz, "finish decide_allocation, spacemit pool ref:%d", GST_OBJECT_REFCOUNT_VALUE(thiz->pool));
/* If downstream supports video meta and video alignment,
* we can replace with our own spacemit bufferpool and use it
@@ -1527,22 +1602,16 @@ static gboolean gst_spacemitdec_decide_allocation(GstVideoDecoder * decoder, Gst
goto no_support;
}
#endif
- if (pool)
- gst_object_unref (pool);
return TRUE;
failed_to_create_pool:
GST_ERROR_OBJECT (thiz, "failed to set buffer pool config");
- if (pool)
- gst_object_unref (pool);
return FALSE;
no_support:
GST_ERROR_OBJECT (thiz,
"error! upstream provides the strange pool: %" GST_PTR_FORMAT, pool);
- if (pool)
- gst_object_unref (pool);
return FALSE;
}
@@ -1550,7 +1619,7 @@ static GstStateChangeReturn
gst_spacemitdec_dec_change_state (GstElement * element, GstStateChange transition)
{
GstVideoDecoder *decoder = GST_VIDEO_DECODER (element);
- GST_DEBUG("ZRong ------------------ in change state, %x", transition);
+ GST_DEBUG_OBJECT (decoder, "start change state, %x", transition);
if (transition == GST_STATE_CHANGE_PAUSED_TO_READY) {
GST_VIDEO_DECODER_STREAM_LOCK (decoder);
diff --git a/ext/spacemit/spacemitcodec/gstspacemitenc.c b/ext/spacemit/spacemitcodec/gstspacemitenc.c
index ba9ab6a..2070c8b 100755
--- a/ext/spacemit/spacemitcodec/gstspacemitenc.c
+++ b/ext/spacemit/spacemitcodec/gstspacemitenc.c
@@ -944,7 +944,7 @@ gst_spacemitenc_handle_frame (GstVideoEncoder * encoder,
if (frame) {
thiz->frame_count++;
- FRAME_SetEos(thiz->mppframe, 0);
+ FRAME_SetEos(thiz->mppframe, FRAME_NO_EOS);
gst_video_frame_map (&video_frame, &thiz->input_state->info, frame->input_buffer, GST_MAP_READ);
if (thiz->PixelFormat == PIXEL_FORMAT_I420) {
@@ -981,7 +981,7 @@ gst_spacemitenc_handle_frame (GstVideoEncoder * encoder,
FRAME_SetPts(mppframe, GST_BUFFER_PTS (frame->input_buffer));
} else {
GST_DEBUG_OBJECT (thiz, "null frame enc, need eos");
- FRAME_SetEos(thiz->mppframe, 1);
+ FRAME_SetEos(thiz->mppframe, FRAME_EOS_WITHOUT_DATA);
mppframe = thiz->mppframe;
}
diff --git a/ext/spacemit/spacemitsrc/gstspacemitsrc.c b/ext/spacemit/spacemitsrc/gstspacemitsrc.c
index eafb476..8a973a5 100755
--- a/ext/spacemit/spacemitsrc/gstspacemitsrc.c
+++ b/ext/spacemit/spacemitsrc/gstspacemitsrc.c
@@ -491,7 +491,7 @@ video_frame_release (void *data)
GST_DEBUG_OBJECT (frame->src, "release cpp output buffer %p, the gstbuffer is %p, pushed frame: %u", outputBuf, frame->gstbuf, frame->src->pushed_frame);
g_mutex_unlock(&frame->src->mutex);
- GST_DEBUG_OBJECT (frame->src, "video_frame dur is: %, fd: %d" GST_TIME_FORMAT, GST_TIME_ARGS (GST_CLOCK_DIFF (frame->use_dur, gst_clock_get_time (clock))), outputBuf->m.fd);
+ GST_DEBUG_OBJECT (frame->src, "video_frame dur is: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_CLOCK_DIFF (frame->use_dur, gst_clock_get_time (clock))), ", fd: %d", outputBuf->m.fd);
gst_object_unref (clock);
gst_release_cpp_buffer(outputBuf, frame->index);
diff --git a/gst-libs/gst/wayland/gstwllinuxdmabuf.c b/gst-libs/gst/wayland/gstwllinuxdmabuf.c
index d6ee6ec..c591742 100644
--- a/gst-libs/gst/wayland/gstwllinuxdmabuf.c
+++ b/gst-libs/gst/wayland/gstwllinuxdmabuf.c
@@ -152,7 +152,7 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
/* Wait for the request answer */
wl_display_flush (gst_wl_display_get_display (display));
data.wbuf = (gpointer) 0x1;
- timeout = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
+ timeout = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
while (data.wbuf == (gpointer) 0x1) {
if (!g_cond_wait_until (&data.cond, &data.lock, timeout)) {
GST_ERROR_OBJECT (mem->allocator, "zwp_linux_buffer_params_v1 time out");

View file

@ -733,6 +733,20 @@ config BR2_PACKAGE_GST1_PLUGINS_BAD_ZBAR
depends on BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_0 # zbar -> libv4l
select BR2_PACKAGE_ZBAR
config BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITCODEC
bool "spacemitcodec"
default y
depends on BR2_PACKAGE_MPP
help
spacemitcodec plugin for spacemit decodec and encodec
config BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITSRC
bool "spacemitsrc"
default y
depends on BR2_PACKAGE_K1X_CAM_LIB
help
spacemitsrc plugin only for spacemit K1 cam
comment "zbar plugin needs a toolchain w/ threads, C++ and headers >= 3.0"
depends on BR2_USE_MMU
depends on !BR2_TOOLCHAIN_HAS_THREADS \

View file

@ -73,7 +73,8 @@ GST1_PLUGINS_BAD_CONF_OPTS += \
-Dmagicleap=disabled \
-Disac=disabled \
-Diqa=disabled \
-Dopencv=disabled
-Dopencv=disabled \
-Dtinyalsa=disabled
GST1_PLUGINS_BAD_DEPENDENCIES = gst1-plugins-base gstreamer1
@ -818,6 +819,28 @@ else
GST1_PLUGINS_BAD_CONF_OPTS += -Dzxing=disabled
endif
ifeq ($(BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITCODEC)_$(BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITSRC), y_y)
#$(info "open spacemit codec and src")
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitcodec=enabled
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitsrc=enabled
GST1_PLUGINS_BAD_DEPENDENCIES += mpp
GST1_PLUGINS_BAD_DEPENDENCIES += k1x-cam
else ifeq ($(BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITCODEC),y)
#$(info "only open spacemit codec")
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitcodec=enabled
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitsrc=disabled
GST1_PLUGINS_BAD_DEPENDENCIES += mpp
else ifeq ($(BR2_PACKAGE_GST1_PLUGINS_BAD_PLUGIN_SPACEMITSRC),y)
#$(info "only open spacemit src")
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitcodec=disabled
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitsrc=enabled
GST1_PLUGINS_BAD_DEPENDENCIES += k1x-cam
else
#$(info "none open spacemit codec or src")
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitcodec=disabled
GST1_PLUGINS_BAD_CONF_OPTS += -Dspacemitsrc=disabled
endif
# Add GPL license if GPL licensed plugins enabled.
ifeq ($(GST1_PLUGINS_BAD_HAS_GPL_LICENSE),y)
GST1_PLUGINS_BAD_CONF_OPTS += -Dgpl=enabled

View file

@ -31,8 +31,8 @@ HAVEGED_CONF_OPTS += --disable-threads
endif
define HAVEGED_INSTALL_INIT_SYSV
$(INSTALL) -m 755 -D package/haveged/S21haveged \
$(TARGET_DIR)/etc/init.d/S21haveged
$(INSTALL) -m 755 -D package/haveged/S09haveged \
$(TARGET_DIR)/etc/init.d/S09haveged
endef
define HAVEGED_INSTALL_INIT_SYSTEMD

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,162 @@
From 8b1fed41efd82f4843899b02764612bc22fc0a0b Mon Sep 17 00:00:00 2001
From: "lff@Snode" <junzhao.liang@spacemit.com>
Date: Fri, 12 Apr 2024 14:32:03 +0800
Subject: [PATCH] [fix] thumbnail bug
---
simd/rvv/jquanti-rvv.c | 27 ++++++++++++-------
simd/rvv/jsimd.c | 60 +++++++++++++++++++++---------------------
2 files changed, 48 insertions(+), 39 deletions(-)
diff --git a/simd/rvv/jquanti-rvv.c b/simd/rvv/jquanti-rvv.c
index 69b2c20..66b72e6 100644
--- a/simd/rvv/jquanti-rvv.c
+++ b/simd/rvv/jquanti-rvv.c
@@ -84,7 +84,6 @@ void jsimd_convsamp_rvv(JSAMPARRAY sample_data, JDIMENSION start_col,
void jsimd_quantize_rvv(JCOEFPTR coef_block, DCTELEM *divisors,
DCTELEM *workspace)
{
- int cols_remaining;
size_t vl;
JCOEFPTR out_ptr = coef_block;
DCTELEM *in_ptr = workspace;
@@ -92,12 +91,11 @@ void jsimd_quantize_rvv(JCOEFPTR coef_block, DCTELEM *divisors,
UDCTELEM *recip_ptr = (UDCTELEM *)divisors;
UDCTELEM *corr_ptr = (UDCTELEM *)divisors + DCTSIZE2;
- vbool4_t mask;
- vint16m4_t out, shift;
+ vint16m4_t out, nout, shift, sign;
vuint16m4_t temp, recip, corr, ushift;
vuint32m8_t product;
- for (cols_remaining = DCTSIZE2; cols_remaining > 0; cols_remaining -= vl)
+ for (int cols_remaining = DCTSIZE2; cols_remaining > 0; cols_remaining -= vl)
{
/* Set vl for each iteration. */
vl = __riscv_vsetvl_e16m4(cols_remaining);
@@ -108,19 +106,30 @@ void jsimd_quantize_rvv(JCOEFPTR coef_block, DCTELEM *divisors,
corr = __riscv_vle16_v_u16m4(corr_ptr, vl);
shift = __riscv_vle16_v_i16m4(shift_ptr, vl);
- /* Mask set to 1 where elements are negative. */
- mask = __riscv_vmslt_vx_i16m4_b4(out, 0, vl);
- out = __riscv_vneg_v_i16m4_m(mask, out, vl);
+ /* Extract sign from coefficients. */
+ sign = __riscv_vsra_vx_i16m4(out, 15, vl);
+
+ /* Get absolute value of DCT coefficients. */
+ nout = __riscv_vneg_v_i16m4(out, vl);
+ out = __riscv_vmax_vv_i16m4(out, nout, vl);
temp = __riscv_vreinterpret_v_i16m4_u16m4(out);
+ /* Add correction. */
temp = __riscv_vadd_vv_u16m4(temp, corr, vl);
+
+ /* Multiply DCT coefficients by quantization reciprocals. */
product = __riscv_vwmulu_vv_u32m8(temp, recip, vl);
+
+ /* Narrow back to 16-bit. */
shift = __riscv_vadd_vx_i16m4(shift, sizeof(DCTELEM) * 8, vl);
ushift = __riscv_vreinterpret_v_i16m4_u16m4(shift);
temp = __riscv_vnsrl_wv_u16m4(product, ushift, vl);
+ /* Restore sign to original product. */
out = __riscv_vreinterpret_v_u16m4_i16m4(temp);
- out = __riscv_vneg_v_i16m4_m(mask, out, vl);
+ out = __riscv_vxor_vv_i16m4(out, sign, vl);
+ out = __riscv_vsub_vv_i16m4(out, sign, vl);
+
__riscv_vse16_v_i16m4(out_ptr, out, vl);
in_ptr += vl;
@@ -129,4 +138,4 @@ void jsimd_quantize_rvv(JCOEFPTR coef_block, DCTELEM *divisors,
corr_ptr += vl;
shift_ptr += vl;
}
-}
\ No newline at end of file
+}
diff --git a/simd/rvv/jsimd.c b/simd/rvv/jsimd.c
index 9277e76..1627ab0 100644
--- a/simd/rvv/jsimd.c
+++ b/simd/rvv/jsimd.c
@@ -734,22 +734,22 @@ jsimd_quantize_float(JCOEFPTR coef_block, FAST_FLOAT *divisors,
GLOBAL(int)
jsimd_can_idct_2x2(void)
{
- init_simd();
+ // init_simd();
- /* The code is optimised for these values only */
- if (DCTSIZE != 8)
- return 0;
- if (sizeof(JCOEF) != 2)
- return 0;
- if (BITS_IN_JSAMPLE != 8)
- return 0;
- if (sizeof(JDIMENSION) != 4)
- return 0;
- if (sizeof(ISLOW_MULT_TYPE) != 2)
- return 0;
+ // /* The code is optimised for these values only */
+ // if (DCTSIZE != 8)
+ // return 0;
+ // if (sizeof(JCOEF) != 2)
+ // return 0;
+ // if (BITS_IN_JSAMPLE != 8)
+ // return 0;
+ // if (sizeof(JDIMENSION) != 4)
+ // return 0;
+ // if (sizeof(ISLOW_MULT_TYPE) != 2)
+ // return 0;
- if (simd_support & JSIMD_RVV)
- return 1;
+ // if (simd_support & JSIMD_RVV)
+ // return 1;
return 0;
}
@@ -757,22 +757,22 @@ jsimd_can_idct_2x2(void)
GLOBAL(int)
jsimd_can_idct_4x4(void)
{
- init_simd();
-
- /* The code is optimised for these values only */
- if (DCTSIZE != 8)
- return 0;
- if (sizeof(JCOEF) != 2)
- return 0;
- if (BITS_IN_JSAMPLE != 8)
- return 0;
- if (sizeof(JDIMENSION) != 4)
- return 0;
- if (sizeof(ISLOW_MULT_TYPE) != 2)
- return 0;
-
- if (simd_support & JSIMD_RVV)
- return 1;
+ // init_simd();
+
+ // /* The code is optimised for these values only */
+ // if (DCTSIZE != 8)
+ // return 0;
+ // if (sizeof(JCOEF) != 2)
+ // return 0;
+ // if (BITS_IN_JSAMPLE != 8)
+ // return 0;
+ // if (sizeof(JDIMENSION) != 4)
+ // return 0;
+ // if (sizeof(ISLOW_MULT_TYPE) != 2)
+ // return 0;
+
+ // if (simd_support & JSIMD_RVV)
+ // return 1;
return 0;
}
--
2.25.1

View file

@ -23,10 +23,13 @@ else ifeq ($(BR2_SHARED_STATIC_LIBS),y)
JPEG_TURBO_CONF_OPTS += -DENABLE_STATIC=ON -DENABLE_SHARED=ON
else ifeq ($(BR2_SHARED_LIBS),y)
JPEG_TURBO_CONF_OPTS += -DENABLE_STATIC=OFF -DENABLE_SHARED=ON
endif
endif
ifeq ($(BR2_PACKAGE_JPEG_SIMD_SUPPORT),y)
JPEG_TURBO_CONF_OPTS += -DWITH_SIMD=ON
ifeq ($(BR2_RISCV_64),y)
JPEG_TURBO_CONF_OPTS += -DCMAKE_C_FLAGS="-march=rv64gcv"
endif
# x86 simd support needs nasm
JPEG_TURBO_DEPENDENCIES += $(if $(BR2_X86_CPU_HAS_MMX),host-nasm)
else

View file

@ -6,6 +6,7 @@ config BR2_PACKAGE_JPEG_SIMD_SUPPORT
default y if BR2_POWERPC_CPU_HAS_ALTIVEC && !BR2_powerpc64le
default y if BR2_POWERPC_CPU_HAS_VSX && BR2_powerpc64le
default y if BR2_aarch64 || BR2_aarch64_be
default y if BR2_RISCV_64
config BR2_PACKAGE_JPEG
bool "jpeg support"

View file

@ -0,0 +1,312 @@
From 928cc0e2a0b1bbf48b4f4047708f04c74f1edc1a Mon Sep 17 00:00:00 2001
From: "lff@Snode" <junzhao.liang@spacemit.com>
Date: Mon, 25 Mar 2024 10:57:54 +0800
Subject: [PATCH] RVV optimized chacha20
---
crypto/chacha/chacha_enc.c | 223 ++++++++++++++++++++++++++++++-
crypto/evp/e_chacha20_poly1305.c | 11 +-
include/crypto/chacha.h | 7 +
3 files changed, 239 insertions(+), 2 deletions(-)
diff --git a/crypto/chacha/chacha_enc.c b/crypto/chacha/chacha_enc.c
index 18251ea..0231b8f 100644
--- a/crypto/chacha/chacha_enc.c
+++ b/crypto/chacha/chacha_enc.c
@@ -11,7 +11,7 @@
#include <string.h>
-#include "crypto/chacha.h"
+#include "include/crypto/chacha.h"
#include "crypto/ctype.h"
typedef unsigned int u32;
@@ -128,3 +128,224 @@ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
input[12]++;
}
}
+
+#if defined(__riscv_vector)
+#include <riscv_vector.h>
+#define QUARTERROUND_RVV(n, vl) \
+ { \
+ va = __riscv_vadd_vv_u32m##n(va, vb, vl); \
+ vd = __riscv_vxor_vv_u32m##n(vd, va, vl); \
+ vd_t = __riscv_vsll_vx_u32m##n(vd, 16, vl); \
+ vd = __riscv_vsrl_vx_u32m##n(vd, 16, vl); \
+ vd = __riscv_vor_vv_u32m##n(vd, vd_t, vl); \
+ \
+ vc = __riscv_vadd_vv_u32m##n(vc, vd, vl); \
+ vb = __riscv_vxor_vv_u32m##n(vb, vc, vl); \
+ vb_t = __riscv_vsll_vx_u32m##n(vb, 12, vl); \
+ vb = __riscv_vsrl_vx_u32m##n(vb, 20, vl); \
+ vb = __riscv_vor_vv_u32m##n(vb, vb_t, vl); \
+ \
+ va = __riscv_vadd_vv_u32m##n(va, vb, vl); \
+ vd = __riscv_vxor_vv_u32m##n(vd, va, vl); \
+ vd_t = __riscv_vsll_vx_u32m##n(vd, 8, vl); \
+ vd = __riscv_vsrl_vx_u32m##n(vd, 24, vl); \
+ vd = __riscv_vor_vv_u32m##n(vd, vd_t, vl); \
+ \
+ vc = __riscv_vadd_vv_u32m##n(vc, vd, vl); \
+ vb = __riscv_vxor_vv_u32m##n(vb, vc, vl); \
+ vb_t = __riscv_vsll_vx_u32m##n(vb, 7, vl); \
+ vb = __riscv_vsrl_vx_u32m##n(vb, 25, vl); \
+ vb = __riscv_vor_vv_u32m##n(vb, vb_t, vl); \
+ }
+
+void ChaCha20_ctr32_r(unsigned char *out, const unsigned char *inp,
+ size_t len, size_t blocks, const unsigned int key[8],
+ const unsigned int counter[4])
+{
+ size_t i, vl;
+ u8 outbuf[4*16*8]; // 4Bytes x 16elems x 8blocks
+
+ vuint32m1_t v00, v01, v02, v03, v04, v05, v06, v07, v08, v09, v10, v11, v12, v13, v14, v15;
+ vuint8m8_t vkey, vsrc;
+ vuint32m4_t va, vb, vc, vd, vb_t, vd_t;
+ vuint32m1_t vtmp0, vtmp1, vtmp2, vtmp3;
+
+ /* deal with 8 blocks at a time */
+ vuint32m1_t v12_og = __riscv_vid_v_u32m1(8);
+ v12_og = __riscv_vadd_vx_u32m1(v12_og, counter[0], 8);
+
+ while (len > 0) {
+ /* prepare 16 vectors for each elements */
+ v00 = __riscv_vmv_v_x_u32m1(0x61707865, 8);
+ v01 = __riscv_vmv_v_x_u32m1(0x3320646e, 8);
+ v02 = __riscv_vmv_v_x_u32m1(0x79622d32, 8);
+ v03 = __riscv_vmv_v_x_u32m1(0x6b206574, 8);
+ v04 = __riscv_vmv_v_x_u32m1(key[0], 8);
+ v05 = __riscv_vmv_v_x_u32m1(key[1], 8);
+ v06 = __riscv_vmv_v_x_u32m1(key[2], 8);
+ v07 = __riscv_vmv_v_x_u32m1(key[3], 8);
+ v08 = __riscv_vmv_v_x_u32m1(key[4], 8);
+ v09 = __riscv_vmv_v_x_u32m1(key[5], 8);
+ v10 = __riscv_vmv_v_x_u32m1(key[6], 8);
+ v11 = __riscv_vmv_v_x_u32m1(key[7], 8);
+ v12 = v12_og;
+ v13 = __riscv_vmv_v_x_u32m1(counter[1], 8);
+ v14 = __riscv_vmv_v_x_u32m1(counter[2], 8);
+ v15 = __riscv_vmv_v_x_u32m1(counter[3], 8);
+
+ /* combine and compute 4 vectors simultaneously */
+ va = __riscv_vset_v_u32m1_u32m4(va, 0, v00);
+ va = __riscv_vset_v_u32m1_u32m4(va, 1, v01);
+ va = __riscv_vset_v_u32m1_u32m4(va, 2, v02);
+ va = __riscv_vset_v_u32m1_u32m4(va, 3, v03);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 0, v04);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 1, v05);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 2, v06);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 3, v07);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 0, v08);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 1, v09);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 2, v10);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 3, v11);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 0, v12);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 1, v13);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 2, v14);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 3, v15);
+
+ for (i = 0; i < 10; ++i) {
+ /* fisrt half quarter round */
+ QUARTERROUND_RVV(4, 32);
+
+ /* rerange */
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vb, 0);
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vb, 1);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vb, 2);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vb, 3);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 0, vtmp1);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 1, vtmp2);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 2, vtmp3);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 3, vtmp0);
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vc, 0);
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vc, 1);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vc, 2);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vc, 3);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 0, vtmp2);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 1, vtmp3);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 2, vtmp0);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 3, vtmp1);
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vd, 0);
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vd, 1);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vd, 2);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vd, 3);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 0, vtmp3);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 1, vtmp0);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 2, vtmp1);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 3, vtmp2);
+
+ /* second half quarter round */
+ QUARTERROUND_RVV(4, 32);
+
+ /* recover */
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vb, 0);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vb, 1);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vb, 2);
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vb, 3);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 0, vtmp0);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 1, vtmp1);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 2, vtmp2);
+ vb = __riscv_vset_v_u32m1_u32m4(vb, 3, vtmp3);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vc, 0);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vc, 1);
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vc, 2);
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vc, 3);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 0, vtmp0);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 1, vtmp1);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 2, vtmp2);
+ vc = __riscv_vset_v_u32m1_u32m4(vc, 3, vtmp3);
+ vtmp3 = __riscv_vget_v_u32m4_u32m1(vd, 0);
+ vtmp0 = __riscv_vget_v_u32m4_u32m1(vd, 1);
+ vtmp1 = __riscv_vget_v_u32m4_u32m1(vd, 2);
+ vtmp2 = __riscv_vget_v_u32m4_u32m1(vd, 3);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 0, vtmp0);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 1, vtmp1);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 2, vtmp2);
+ vd = __riscv_vset_v_u32m1_u32m4(vd, 3, vtmp3);
+
+ }
+
+ /* split */
+ v00 = __riscv_vget_v_u32m4_u32m1(va, 0);
+ v01 = __riscv_vget_v_u32m4_u32m1(va, 1);
+ v02 = __riscv_vget_v_u32m4_u32m1(va, 2);
+ v03 = __riscv_vget_v_u32m4_u32m1(va, 3);
+ v04 = __riscv_vget_v_u32m4_u32m1(vb, 0);
+ v05 = __riscv_vget_v_u32m4_u32m1(vb, 1);
+ v06 = __riscv_vget_v_u32m4_u32m1(vb, 2);
+ v07 = __riscv_vget_v_u32m4_u32m1(vb, 3);
+ v08 = __riscv_vget_v_u32m4_u32m1(vc, 0);
+ v09 = __riscv_vget_v_u32m4_u32m1(vc, 1);
+ v10 = __riscv_vget_v_u32m4_u32m1(vc, 2);
+ v11 = __riscv_vget_v_u32m4_u32m1(vc, 3);
+ v12 = __riscv_vget_v_u32m4_u32m1(vd, 0);
+ v13 = __riscv_vget_v_u32m4_u32m1(vd, 1);
+ v14 = __riscv_vget_v_u32m4_u32m1(vd, 2);
+ v15 = __riscv_vget_v_u32m4_u32m1(vd, 3);
+
+ /* x[i] + input[i] */
+ v00 = __riscv_vadd_vx_u32m1(v00, 0x61707865, 8);
+ v01 = __riscv_vadd_vx_u32m1(v01, 0x3320646e, 8);
+ v02 = __riscv_vadd_vx_u32m1(v02, 0x79622d32, 8);
+ v03 = __riscv_vadd_vx_u32m1(v03, 0x6b206574, 8);
+ v04 = __riscv_vadd_vx_u32m1(v04, key[0], 8);
+ v05 = __riscv_vadd_vx_u32m1(v05, key[1], 8);
+ v06 = __riscv_vadd_vx_u32m1(v06, key[2], 8);
+ v07 = __riscv_vadd_vx_u32m1(v07, key[3], 8);
+ v08 = __riscv_vadd_vx_u32m1(v08, key[4], 8);
+ v09 = __riscv_vadd_vx_u32m1(v09, key[5], 8);
+ v10 = __riscv_vadd_vx_u32m1(v10, key[6], 8);
+ v11 = __riscv_vadd_vx_u32m1(v11, key[7], 8);
+ v12 = __riscv_vadd_vv_u32m1(v12, v12_og, 8);
+ v13 = __riscv_vadd_vx_u32m1(v13, counter[1], 8);
+ v14 = __riscv_vadd_vx_u32m1(v14, counter[2], 8);
+ v15 = __riscv_vadd_vx_u32m1(v15, counter[3], 8);
+
+ /* counter++ */
+ v12_og = __riscv_vadd_vx_u32m1(v12_og, 8, 8);
+
+ /* XOR input and store */
+ int blk = blocks > 8 ? 8 : blocks;
+
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 0, 64, v00, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 1, 64, v01, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 2, 64, v02, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 3, 64, v03, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 4, 64, v04, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 5, 64, v05, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 6, 64, v06, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 7, 64, v07, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 8, 64, v08, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 9, 64, v09, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 10, 64, v10, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 11, 64, v11, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 12, 64, v12, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 13, 64, v13, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 14, 64, v14, blk);
+ __riscv_vsse32_v_u32m1((u32 *)outbuf + 15, 64, v15, blk);
+
+ blocks -= blk;
+
+ /* e32m1*16 = e8m8*2 */
+ for (i = 0; (len > 0) && (i < 2); ++i) {
+ vl = __riscv_vsetvl_e8m8(len);
+ vsrc = __riscv_vle8_v_u8m8(inp, vl);
+ vkey = __riscv_vle8_v_u8m8(outbuf + i * 256, vl);
+ vsrc = __riscv_vxor_vv_u8m8(vsrc, vkey, vl);
+
+ __riscv_vse8_v_u8m8(out, vsrc, vl);
+
+ out += vl;
+ inp += vl;
+ len -= vl;
+ }
+ }
+}
+#endif /* __riscv_vector */
\ No newline at end of file
diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c
index bdc406b..feaf7a6 100644
--- a/crypto/evp/e_chacha20_poly1305.c
+++ b/crypto/evp/e_chacha20_poly1305.c
@@ -8,6 +8,7 @@
*/
#include <stdio.h>
+#include <riscv_vector.h>
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_CHACHA
@@ -16,7 +17,7 @@
# include <openssl/objects.h>
# include "evp_local.h"
# include "crypto/evp.h"
-# include "crypto/chacha.h"
+# include "include/crypto/chacha.h"
typedef struct {
union {
@@ -102,11 +103,19 @@ static int chacha_cipher(EVP_CIPHER_CTX * ctx, unsigned char *out,
blocks -= ctr32;
ctr32 = 0;
}
+
+#if defined(__riscv_vector)
+ ChaCha20_ctr32_r(out, inp, len, blocks, key->key.d, key->counter);
+ inp += len;
+ out += len;
+ len -= len;
+#else
blocks *= CHACHA_BLK_SIZE;
ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter);
len -= blocks;
inp += blocks;
out += blocks;
+#endif
key->counter[0] = ctr32;
if (ctr32 == 0) key->counter[1]++;
diff --git a/include/crypto/chacha.h b/include/crypto/chacha.h
index 4029400..7ebf4d8 100644
--- a/include/crypto/chacha.h
+++ b/include/crypto/chacha.h
@@ -26,6 +26,13 @@
void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
size_t len, const unsigned int key[8],
const unsigned int counter[4]);
+
+#if defined(__riscv_vector)
+void ChaCha20_ctr32_r(unsigned char *out, const unsigned char *inp,
+ size_t len, size_t blocks, const unsigned int key[8],
+ const unsigned int counter[4]);
+#endif
+
/*
* You can notice that there is no key setup procedure. Because it's
* as trivial as collecting bytes into 32-bit elements, it's reckoned
--
2.25.1

View file

@ -0,0 +1,27 @@
From f14b1064fcc9ea570726034ac3766d742503c150 Mon Sep 17 00:00:00 2001
From: maguoqun <guoqun.ma@spacemit.com>
Date: Fri, 29 Mar 2024 17:23:27 +0800
Subject: [PATCH] fix x86 host compile err which has no header file
riscv_vector.h
---
crypto/evp/e_chacha20_poly1305.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c
index feaf7a6..e56f232 100644
--- a/crypto/evp/e_chacha20_poly1305.c
+++ b/crypto/evp/e_chacha20_poly1305.c
@@ -8,7 +8,9 @@
*/
#include <stdio.h>
+#if defined(__riscv_vector)
#include <riscv_vector.h>
+#endif
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_CHACHA
--
2.34.1

View file

@ -64,6 +64,10 @@ define HOST_LIBOPENSSL_CONFIGURE_CMDS
zlib-dynamic
endef
ifeq ($(BR2_RISCV_64),y)
LIBOPENSSL_CFLAGS += -march=rv64gcv
endif
define LIBOPENSSL_CONFIGURE_CMDS
cd $(@D); \
$(TARGET_CONFIGURE_ARGS) \

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,11 @@ else
LIBPNG_CONF_OPTS += --disable-arm-neon
endif
ifeq ($(BR2_RISCV_64),y)
LIBPNG_CONF_OPTS += --enable-riscv-vector
LIBPNG_CONF_OPTS += CFLAGS="-march=rv64gcv"
endif
ifeq ($(BR2_X86_CPU_HAS_SSE2),y)
LIBPNG_CONF_OPTS += --enable-intel-sse
else

View file

@ -0,0 +1,27 @@
From fcc00b5cfd9ba11b969c3884024fae6792474cfb Mon Sep 17 00:00:00 2001
From: fuqiang <qiang.fu@spacemit.com>
Date: Mon, 11 Mar 2024 19:44:13 +0800
Subject: [PATCH] fix compile error when open wayland: can not find
wayland-scanner
---
configure | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 108ba53..a42b5ae 100755
--- a/configure
+++ b/configure
@@ -23128,7 +23128,8 @@ printf %s "checking for Wayland support... " >&6; }
if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then
WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
- WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
+ #WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
+ WAYLAND_SCANNER="$srcdir/../../host/bin/wayland-scanner"
if $PKG_CONFIG --exists 'wayland-scanner >= 1.15'
then :
WAYLAND_SCANNER_CODE_MODE=private-code
--
2.25.1

View file

@ -23,7 +23,6 @@ SDL2_CONF_OPTS += \
--disable-video-vivante \
--disable-video-cocoa \
--disable-video-metal \
--disable-video-wayland \
--disable-video-dummy \
--disable-video-offscreen \
--disable-video-vulkan \
@ -37,7 +36,8 @@ SDL2_CONF_OPTS += \
--disable-hidapi-joystick \
--disable-hidapi-libusb \
--disable-joystick-virtual \
--disable-render-d3d
--disable-render-d3d \
--disable-oss
# We are using autotools build system for sdl2, so the sdl2-config.cmake
# include path are not resolved like for sdl2-config script.
@ -181,4 +181,7 @@ else
SDL2_CONF_OPTS += --disable-video-kmsdrm
endif
SDL2_DEPENDENCIES += wayland libxkbcommon
SDL2_CONF_OPTS += --enable-video-wayland
$(eval $(autotools-package))

File diff suppressed because it is too large Load diff

View file

@ -23,6 +23,10 @@ ifeq ($(BR2_arm),y)
ZLIB_NG_CONF_OPTS += -DWITH_ACLE=1
endif
ifeq ($(BR2_RISCV_64),y)
ZLIB_NG_CONF_OPTS += -DCMAKE_C_FLAGS="-march=rv64gcv"
endif
ifeq ($(BR2_ARM_CPU_HAS_NEON)$(BR2_aarch64),y)
ZLIB_NG_CONF_OPTS += -DWITH_NEON=ON
else