| | |
| | | void *task_pushFrames(void *args){ |
| | | int64_t time = getCurrentTimestamp(); |
| | | while (TRUE){ |
| | | YUVData *mainYuvData; |
| | | int result = pushFrames.pop(mainYuvData); |
| | | if(!result){ |
| | | continue; |
| | |
| | | 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); |
| | |
| | | if(!nativeMainWindow){ |
| | | LOGE("nativeWindow 回收"); |
| | | } |
| | | if(!jvmMainCall){ |
| | | jvmMainCall = new JavaMainCall(env,clazz); |
| | | } |
| | | |
| | | } |
| | | extern "C" |
| | |
| | | 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; |
| | | } |