Files
2026-08-24 10:03:24 +08:00

482 lines
15 KiB
C

/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in below
* which is part of this source code package.
*
* Description:
*/
// Copyright (C) 2019 Amlogic, Inc. All rights reserved.
//
// All information contained herein is Amlogic confidential.
//
// This software is provided to you pursuant to Software License
// Agreement (SLA) with Amlogic Inc ("Amlogic"). This software may be
// used only in accordance with the terms of this agreement.
//
// Redistribution and use in source and binary forms, with or without
// modification is strictly prohibited without prior written permission
// from Amlogic.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define LOG_TAG "jenc_test"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "jpegenc_api.h"
#include "test_dma_api.h"
//#include <media/stagefright/foundation/ALooper.h>
//using namespace android;
//#include <malloc.h>
#define LOG_LINE() printf("[%s:%d]\n", __FUNCTION__, __LINE__)
static int64_t GetNowUs() {
struct timeval tv;
gettimeofday(&tv, NULL);
return (int64_t)(tv.tv_sec) * 1000000 + (int64_t)(tv.tv_usec);
}
int main(int argc, const char *argv[])
{
int outfd = -1;
FILE *fp = NULL;
int ret = -1;
int width, height ,quality;
jpegenc_frame_fmt_e iformat;
jpegenc_frame_fmt_e oformat;
struct usr_ctx_s ctx;
int shared_fd[3] = {0};
int64_t encoding_time = 0;
int enc_frame = 0;
int framesize = 0;
unsigned char *vaddr = NULL;
unsigned char *input[3] = { NULL };
jpegenc_frame_info_t frame_info;
int datalen = 0;
int num_planes = 1;
int w_stride = 0;
int h_stride = 0;
int w_alignment = 0;
int h_alignment = 0;
int num = 1;
unsigned int output_size = 0;
unsigned char *output_buffer = NULL;
unsigned char *inputBuffer = NULL;
unsigned int ysize;
unsigned int usize;
unsigned int vsize;
unsigned int uvsize;
jpegenc_result_e result = ENC_FAILED;
jpegenc_handle_t handle = 0;
int End_status = 0;
if (argc < 11) {
printf("Amlogic AVC Encode API \n");
printf("usage: output [srcfile] [outfile] [width] [height] [quality] [iformat] [oformat] [w_stride] [h_stride] [memtype]\n");
printf("options :\n");
printf(" srcfile : yuv data url in your root fs \n");
printf(" outfile : stream url in your root fs \n");
printf(" width : width \n");
printf(" height : height \n");
printf(" qulaity : jpeg quality scale \n");
printf(" iformat : 0:422, 1:444, 2:NV21, 3:NV12, 4:420M, 5:444M \n");
printf(" oformat : 0:420, 1:422, 2:444 \n");
printf(" width alignment : width alignment \n");
printf(" height alignment : height alignment \n");
printf(" memory type : memory type for input data, 0:vmalloc, 3:dma\n");
printf(" num \t: encode frame count \n");
printf(" num_planes \t: used for dma buffer case. 2 : nv12/nv21, 3 : yuv420p(yv12/yu12)\n");
return -1;
} else {
printf("%s\n", argv[1]);
printf("%s\n", argv[2]);
}
width = atoi(argv[3]);
if (width < 1) {
printf("Encode Failed! invalid width \n");
return -1;
}
height = atoi(argv[4]);
if (height < 1) {
printf("Encode Failed! invalid height \n");
return -1;
}
quality = atoi(argv[5]);
iformat = (jpegenc_frame_fmt_e)atoi(argv[6]);
oformat = (jpegenc_frame_fmt_e)atoi(argv[7]);
w_alignment = atoi(argv[8]);
h_alignment = atoi(argv[9]);
jpegenc_mem_type_e mem_type = (jpegenc_mem_type_e)atoi(argv[10]);
if (argc > 11)
num = atoi(argv[11]);
if (argc > 12)
num_planes = atoi(argv[12]);
printf("src url: %s \n", argv[1]);
printf("out url: %s \n", argv[2]);
printf("width : %d \n", width);
printf("height : %d \n", height);
printf("quality: %d \n", quality);
printf("iformat: %d \n", iformat);
printf("oformat: %d \n", oformat);
printf("width alignment: %d \n", w_alignment);
printf("height alignment: %d \n", h_alignment);
printf("memory type: %s\n", mem_type == JPEGENC_LOCAL_BUFF ? "VMALLOC" : mem_type == JPEGENC_DMA_BUFF ? "DMA" : "unsupported mem type");
printf("num: %d \n", num);
if (w_alignment > 0)
w_stride = (width % w_alignment) == 0 ? width : (((width / w_alignment)+1)*w_alignment);
else
w_stride = width;
if (h_alignment > 0)
h_stride = (height % h_alignment) == 0 ? height : (((height / h_alignment)+1)*h_alignment);
else
h_stride = height;
printf("align: %d->%d\n", width, w_stride);
printf("align: %d->%d\n", height, h_stride);
if (mem_type != JPEGENC_LOCAL_BUFF && mem_type != JPEGENC_DMA_BUFF) {
printf("Encode Failed! unsupported mem type\n");
return -1;
}
memset(&frame_info, 0, sizeof(frame_info));
framesize = w_stride * h_stride * 3 / 2;
ysize = w_stride * h_stride;
usize = w_stride * h_stride / 4;
vsize = w_stride * h_stride / 4;
uvsize = w_stride * h_stride / 2;
if (iformat == 1 || iformat == 5 || iformat == 6) {
framesize = w_stride * h_stride * 3;
} else if (iformat == 0) {
framesize = w_stride * h_stride * 2;
}
printf("framesize=%d\n", framesize);
if (mem_type == JPEGENC_DMA_BUFF) {
ret = create_ctx(&ctx);
if (ret < 0) {
printf("gdc create fail ret=%d\n", ret);
End_status = -1;
goto exit;
}
if (num_planes == 3)
{
if (iformat != FMT_YUV420)
{
printf("error fmt %d\n", iformat);
End_status = -1;
goto exit;
}
ret = alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, ysize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
ysize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[0];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[0] = ret;
input[0] = vaddr;
ret = alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, usize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
usize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[1];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[1] = ret;
input[1] = vaddr;
ret = alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, vsize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
vsize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[2];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[2] = ret;
input[2] = vaddr;
} else if (num_planes == 2)
{
ret = alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, ysize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
ysize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[0];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[0] = ret;
input[0] = vaddr;
if (iformat != FMT_NV12 && iformat != FMT_NV21)
{
printf("error fmt %d\n", iformat);
End_status = -1;
goto exit;
}
ret = alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, uvsize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
uvsize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[1];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[1] = ret;
input[1] = vaddr;
} else if (num_planes == 1)
{
ret =
alloc_dma_buffer(&ctx, INPUT_BUFF_TYPE, framesize);
if (ret < 0)
{
printf("alloc fail ret=%d, len=%u\n", ret,
framesize);
End_status = -1;
goto exit;
}
vaddr = (unsigned char *) ctx.i_buff[0];
if (!vaddr)
{
printf("mmap failed,Not enough memory\n");
End_status = -1;
goto exit;
}
shared_fd[0] = ret;
input[0] = vaddr;
}
frame_info.plane_num = num_planes;
frame_info.YCbCr[0] = shared_fd[0];
frame_info.YCbCr[1] = shared_fd[1];
frame_info.YCbCr[2] = shared_fd[2];
} else {
inputBuffer = (unsigned char *) malloc(framesize);
if (inputBuffer == NULL) {
printf("Can not allocat inputBuffer\n");
End_status = -1;
goto exit;
}
frame_info.YCbCr[0] = (ulong) (inputBuffer);
frame_info.YCbCr[1] =
(ulong) (inputBuffer + ysize);
frame_info.YCbCr[2] =
(ulong) (inputBuffer + ysize + usize);
}
output_size = 1024 * 1024 * 10;
output_buffer = (unsigned char *)malloc(output_size);
if (!output_buffer) {
printf("alloc buffer for output jpeg failed\n");
End_status = -1;
goto exit;
}
fp = fopen(argv[1], "rb");
if (!fp) {
printf("open input file %s failed: %s\n", argv[1], strerror(errno));
End_status = -1;
goto exit;
}
outfd = open(argv[2], O_CREAT | O_RDWR | O_TRUNC, 0644);
if (outfd < 0)
{
printf("open dist file error!\n");
End_status = -1;
goto exit;
}
frame_info.width = width;
frame_info.height = height;
frame_info.w_stride = w_stride;
frame_info.h_stride = h_stride;
frame_info.quality = quality;
frame_info.iformat = iformat;
frame_info.oformat = oformat;
frame_info.mem_type = mem_type;
handle = jpegenc_init();
if (handle == (long)NULL) {
printf("jpegenc_init failed\n");
End_status = -1;
goto exit;
}
if (mem_type == JPEGENC_DMA_BUFF) { // read data to dma buf vaddr
if (num_planes == 1)
{
if (fread(input[0], 1, framesize, fp) !=
framesize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
} else if (num_planes == 2)
{
if (fread(input[0], 1, ysize, fp) != ysize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
if (fread(input[1], 1, uvsize, fp) != uvsize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
} else if (num_planes == 3)
{
if (fread(input[0], 1, ysize, fp) != ysize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
if (fread(input[1], 1, usize, fp) != usize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
if (fread(input[2], 1, vsize, fp) != vsize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
}
} else {
if (fread(inputBuffer, 1, framesize, fp) != framesize)
{
printf("read input file error!\n");
End_status = -1;
goto exit;
}
}
memset(output_buffer, 0, output_size);
for (int i = 0; i < num; i++) {
int64_t t_1=GetNowUs();
result = jpegenc_encode(handle, frame_info, output_buffer, &datalen);
int64_t t_2=GetNowUs();
fprintf(stderr, "jpegenc_encode time: %lld\n", t_2-t_1);
if (result != ENC_FAILED) {
write(outfd, (unsigned char *)output_buffer, datalen);
enc_frame++;
encoding_time+=t_2-t_1;
} else {
End_status = ENC_FAILED;
goto exit;
}
}
fprintf(stderr, "encode time:%lld, fps:%3.1f\n", encoding_time, enc_frame*1.0/(encoding_time/1000000.0));
exit:
if (handle)
jpegenc_destroy(handle);
if (outfd >= 0)
close(outfd);
if (fp)
fclose(fp);
if (output_buffer != NULL)
free(output_buffer);
if (mem_type == JPEGENC_DMA_BUFF)
{
if (shared_fd[0] >= 0)
close(shared_fd[0]);
if (shared_fd[1] >= 0)
close(shared_fd[1]);
if (shared_fd[2] >= 0)
close(shared_fd[2]);
destroy_ctx(&ctx);
} else {
if (inputBuffer)
free(inputBuffer);
}
if (End_status == 0)
printf("Encode End Succeeded!\n");
else if (End_status == -1)
printf("Encode Failed!\n");
else
printf("Encode End with unknown status:%d\n", End_status);
return 0;
}