Runt
2025-04-13 8c0f96b20f4cf44d230b373f51261566af02de8e
app/src/main/cpp/native-lib.cpp
@@ -115,7 +115,6 @@
void *task_pushFrames(void *args){
    int64_t time = getCurrentTimestamp();
    while (TRUE){
        YUVData *mainYuvData;
        int result = pushFrames.pop(mainYuvData);
        if(!result){
            continue;
@@ -186,37 +185,32 @@
            if(pushers.size() == 0){
                break;
            }
            if(width != FRAME_WIDTH){
                //缩放至1080
                uint8_t *dstData[3];
                copyYUV(mainYuvData->yuvData,width,height,dstData);
                delete mainYuvData->yuvData[0];
                delete mainYuvData->yuvData[1];
                delete mainYuvData->yuvData[2];
                //LOGI("缩放至1080");
                int64_t t1 = getCurrentTimestamp();
                scaleYUV(mainYuvData->yuvData,width,height,FRAME_WIDTH,FRAME_HEIGHT,dstData);
                scaleYUV(dstData,width,height,FRAME_WIDTH,FRAME_HEIGHT,mainYuvData->yuvData);
                //LOGI("缩放至1080 耗时:%d",getCurrentTimestamp() - t1);
                //加水印
                int64_t t2 = getCurrentTimestamp();
                waterYUV(dstData);
                //LOGI("加水印 耗时:%d",getCurrentTimestamp() - t2);
                //主画面
                int64_t t3 = getCurrentTimestamp();
                videoChannel->pushYUV(dstData);
                //LOGI("pushYUV 编码 耗时:%d", getCurrentTimestamp() - t3);
                delete dstData[0];
                delete dstData[1];
                delete dstData[2];
            }else{
                //加水印
                //LOGI("加水印");
                int64_t t2 = getCurrentTimestamp();
                waterYUV(mainYuvData->yuvData);
                //LOGI("加水印 耗时:%d",getCurrentTimestamp() - t2);
                //主画面
                //LOGI("pushYUV pushYUV %d",pushers.size());
                int64_t t1 = getCurrentTimestamp();
                videoChannel->pushYUV(mainYuvData->yuvData);
                //LOGI("pushYUV 编码 耗时:%d", getCurrentTimestamp() - t1);
            }
            //加水印
            //LOGI("加水印");
            int64_t t2 = getCurrentTimestamp();
            waterYUV(mainYuvData->yuvData);
            //LOGI("加水印 耗时:%d",getCurrentTimestamp() - t2);
            //主画面
            //LOGI("pushYUV pushYUV %d",pushers.size());
            int64_t t1 = getCurrentTimestamp();
            videoChannel->pushYUV(mainYuvData->yuvData);
            //LOGI("pushYUV 编码 耗时:%d", getCurrentTimestamp() - t1);
            //LOGI("pushYUV 耗时:%d", getCurrentTimestamp() - t);
        } while (0);
        releaseYuvFrameData(mainYuvData);
@@ -369,6 +363,9 @@
    if(!nativeMainWindow){
        LOGE("nativeWindow 回收");
    }
    if(!jvmMainCall){
        jvmMainCall = new JavaMainCall(env,clazz);
    }
}
extern "C"
@@ -443,4 +440,64 @@
    yuv[2] = reinterpret_cast<uint8_t *>(data + ySize + uSize); // V 平面
    pushYUV(stream_code,yuv);
    env->ReleaseByteArrayElements(bytes,data,0);
}
extern "C" JNIEXPORT jbyteArray JNICALL
Java_com_runt_live_cpp_LiveMiniView_native_1get_1cut_1frame(JNIEnv *env, jclass clazz, jint index, jint stream_code) {
    uint8_t *yuvData[3];
    if(mainYuvData){
        pthread_mutex_lock(&pushVideoMutex);
        copyYUV(mainYuvData->yuvData,FRAME_WIDTH,FRAME_HEIGHT,yuvData);
        pthread_mutex_unlock(&pushVideoMutex);
    }else{
        copyYUV(blackYUV,FRAME_WIDTH,FRAME_HEIGHT,yuvData);
    }
    waterYUV(index,yuvData);
    //*****裁切画面
    MiniViewData *miniView = getMiniView(stream_code);
    int scaleWidth = (FRAME_WIDTH * miniView->viewRate);
    int scaleHeight = (FRAME_WIDTH / (miniView->width * 1.0 / miniView->height) * miniView->viewRate);
    //涉及到 YUV 4:2:0 格式的图像时,宽度和高度通常需要是 2 的倍数
    if(scaleWidth % 2 == 1){
        scaleWidth+=1;
    }
    if(scaleHeight % 2 == 1){
        scaleHeight+=1;
    }
    if(scaleWidth > FRAME_WIDTH){
        scaleWidth = FRAME_WIDTH;
    }
    if(scaleHeight > FRAME_HEIGHT){
        scaleHeight = FRAME_HEIGHT;
    }
    if(!miniView->scaledYuvFrame){
        miniView->scaledYuvFrame = new YUVData;
    }
    miniView->scaledYuvFrame->width = scaleWidth;
    miniView->scaledYuvFrame->height = scaleHeight;
    miniView->scaledYuvFrame->pYrate = miniView->pYrate;
    miniView->scaledYuvFrame->pXrate = miniView->pXrate;
    uint8_t *dstData[3];
    //位置
    int offsetY = (FRAME_HEIGHT - scaleHeight) * miniView->pYrate;
    int offsetX = (FRAME_WIDTH - scaleWidth) * miniView->pXrate;
    cutYUV(yuvData,FRAME_WIDTH,FRAME_HEIGHT,offsetX,offsetY,dstData,scaleWidth,scaleHeight);
    LOGE("index:%d x:%d y:%d %dx%d view:%dx%d",index,offsetX,offsetY,scaleWidth,scaleHeight,miniView->width,miniView->height);
    copyYUV(dstData,scaleWidth,scaleHeight,miniView->scaledYuvFrame->yuvData);
    addBlackBorder(miniView->scaledYuvFrame->yuvData,scaleWidth,scaleHeight,3);
    //源数据没用了
    delete yuvData[0];
    delete yuvData[1];
    delete yuvData[2];
    //******转为rgba
    int size = scaleWidth * scaleHeight * 4;
    uint8_t *rgba_data = yuvToRGBA(dstData,scaleWidth,scaleHeight);
    //yuv数据没用了
    delete dstData[0];
    delete dstData[1];
    delete dstData[2];
    //转为java字节数组
    jbyteArray java_array = env->NewByteArray(size);
    env->SetByteArrayRegion(java_array, 0, size, (jbyte *)rgba_data);
    delete[] rgba_data;
    return java_array;
}