从处理后的图像和音频中生成视频

时间:2018-07-11 14:55:30

标签: android opencv android-ffmpeg android-mediacodec

我遵循了这个示例http://nezarobot.blogspot.com/2016/03/android-surfacetexture-camera2-opencv.html,以便在将帧发送到预览之前对其进行处理。

这是通过将ImageSurface发送到完成处理的本机函数来完成的。

我还成功使用openCVVideoWriter将图像流写入了视频。

很不幸,唯一的格式是.avi,我想拥有.mp4。而且,我还希望在创建的视频中有音频。

我有用于处理和写入视频的以下代码:

extern "C"
JNIEXPORT void JNICALL
Java_com_erikbylow_mycamera3_JNIUtils_drawCircle(
        JNIEnv *env, jobject type, jint srcWidth, jint srcHeight, jobject srcBuf, jobject dstSurface,
        jstring path_, jint saveFile) {

    uint8_t *srcLumaPtr = reinterpret_cast<uint8_t *>(env->GetDirectBufferAddress(srcBuf));
    if (srcLumaPtr == nullptr){
        LOGE("blit NULL pointer Error");
    }

    int dstWidth;
    int dstHeight;

    cv::Mat mYuv(srcHeight + srcHeight / 2, srcWidth, CV_8UC1, srcLumaPtr);
    uint8_t*srcChromaUVInterleavedptr = nullptr;

    bool swapDstUV;

    ANativeWindow *win = ANativeWindow_fromSurface(env, dstSurface);
    ANativeWindow_Buffer buf;
    dstWidth = srcHeight;
    dstHeight = srcWidth;
    ANativeWindow_setBuffersGeometry(win, dstWidth, dstHeight, 0);
    if (int32_t err = ANativeWindow_lock(win, &buf, NULL)){
        LOGE("ANativeWindow_lock failed with error code %d\n", err);
        ANativeWindow_release(win);
    }

    uint8_t *dstLumaPtr = reinterpret_cast<uint8_t*>(buf.bits);

    cv::Mat dstRgba(dstHeight, buf.stride, CV_8UC4, dstLumaPtr);
    cv::Mat srcRgba(srcHeight, srcWidth, CV_8UC4);
    cv::Mat flipRgba(dstHeight, dstWidth, CV_8UC4);

    // Convert YUV to RGBA
    cv::cvtColor(mYuv, srcRgba, CV_YUV2RGBA_NV21);

    // Rotate 90 degree
//    cv::transpose(srcRgba, flipRgba);
    cv::flip(srcRgba, flipRgba, 1);
    cv::flip(flipRgba, flipRgba, 0);
//    flipRgba = srcRgba;
//    LaneDetect(flipRgba, str, savefile, outStr);

    // Copy to TextureView surface
    uchar *dbuf;
    uchar *sbuf;
    dbuf = dstRgba.data;
    sbuf = flipRgba.data;

    LOGE("buf.height: %d", buf.height);
    LOGE("buf.width: %d", buf.width);
    LOGE("buf.stride: %d", buf.stride);
    LOGE("flipRgba.cols %d", flipRgba.cols);
    for (int i = 0; i < flipRgba.rows; i++){
        dbuf = dstRgba.data + i * buf.stride*4;
        memcpy(dbuf, sbuf, buf.stride*4); // Is this one row at a time?
        sbuf += flipRgba.cols * 4;
    }
    cv::Point p1(100,100);
    int radius = 10;
    cv::circle(flipRgba, p1, radius, cv::Scalar(255,255,255), CV_FILLED);
    cv::circle(dstRgba, p1, radius, cv::Scalar(255,255,255), CV_FILLED);
    mWriter.write(flipRgba);
    ANativeWindow_unlockAndPost(win);
    ANativeWindow_release(win);
}

最好的方法是什么?要ffmpeg还是Android拥有MediaCodec?我已经将这些帧作为Mat文件使用,因此如果可以继续进行下去,那就太好了。包括音频。

0 个答案:

没有答案