标签: grafika

使用Grafika CameraCapture代码拉伸Android相机预览

我正在寻找帮助解决我使用Grafika的CameraCaptureActivity代码所面临的问题.我想构建一个可以记录相机并显示预览的应用程序,所以这个样本和代码看起来就像我想要的那样,到目前为止它很棒,这个问题appart.

我的问题是,当相机预览尺寸与GLSurfaceView我用于显示预览的确切尺寸不匹配时,它会显示拉伸预览.

以下是它的外观:

预览拉伸

你可以看到它是水平拉伸的,因为音符表是一个完美的正方形.

用于在三星Galaxy S4这种精确为例,相机预览大小1280x720(从使用预览可用大小提取Camera2API),并且GLSurfaceView1920x1080覆盖整个屏幕.

什么时候出现?

当SurfaceView与Camera输出相比进行放大时,即使我始终确保比率保持正确(1920x1080= 1.5*1280x720),也会出现此问题.

你用的是什么代码?

我使用Grafika的代码,包括:

有些日志?

这是SurfaceFlinger转储的样子:

Hardware Composer state (version 01030000):
  mDebugForceFakeVSync=0
  Display[0] configurations (* current):
    * 0: 1080x1920, xdpi=442.450989, ydpi=439.351013, secure=1 refresh=16666667
  numHwLayers=3, flags=00000000
    type   |  handle  | hint | flag | tr | blnd |  format     |     source crop(l,t,r,b)       |           frame        |      dirtyRect         |  name 
------------+----------+----------+----------+----+-------+----------+-----------------------------------+---------------------------+-------------------
       HWC | b3b12ba0 …
Run Code Online (Sandbox Code Playgroud)

android opengl-es glsurfaceview android-camera grafika

13
推荐指数
1
解决办法
1276
查看次数

在使用MediaCodec进行Grafika的"连续捕获"活动编码之前裁剪视频

我正在学习Grafika的"连续捕获"活动,它是关于使用MediaCodec录制视频.

活动源代码位于https://github.com/google/grafika/blob/master/src/com/android/grafika/ContinuousCaptureActivity.java

该程序使用SurfaceTexture obj从相机接收数据并使用此SurfaceTexture obj创建2个EGLSurface obj,一个EGLSurface obj将数据提供给MediaCodec,另一个将数据提供给SurfaceView以进行相机预览.MediaCodec将数据编码为h264数据,MediaMuxer obj将h264数据写入mp4文件.

但是有一个问题,相机支持的预览尺寸是空间(宽度>高度),如1920*1080,1440*1080,720*480等.通常,我们在录制视频时以纵向方式拍摄手机,因此我们应该使用API​​:Camera.setDisplayOrientation(90)将图片旋转为肖像,然后录制肖像视频.

但我想用手中的手机肖像录制风景视频,我必须从相机中裁剪每一帧.我的方法是切断每帧图片的底部和顶部并保留图片的中间部分,然后左图片将是一个景观图片.

但我不熟悉opengl,我不知道如何裁剪SurfaceTexture数据.任何擅长opengl的人都能给我一些帮助吗?

video android opengl-es crop grafika

9
推荐指数
1
解决办法
4488
查看次数

带声音的Android视频循环缓冲区

我正在使用Google的开源示例:Grafika.我正在使用它的ContinuousCaptureActivity.java此活动中演示了CircularBuffer的实现,但生成的视频文件中没有包含音频.

我想在此活动中添加音频录制功能,并将录制的音频以相同的CircularBuffered时尚添加到视频中.

为实现这一目标,我探索了MediaCodec库,该库已在4.3+版本中推出.我还使用MediaMuxer捕获视频和音频流,并将它们混合到一个视频中.

但是,我不确定如何在ContinuousCaptureActivity.java课堂上实现录音功能.任何帮助都非常感谢.

audio video android mediacodec grafika

8
推荐指数
0
解决办法
1022
查看次数

setPreviewTexture在MTK设备中失败

最近我正在通过grafika(感谢fadden)学习安卓摄像头和OpenglES.它在大多数设备上都很好,但我遇到了一些设备中的错误,特别是MTK设备(如MT6580,MT8163 ......).

例如,当"CameraCaptureActivity"在MTK中运行时.我收到此错误:

java.lang.NullPointerException:尝试在空对象引用上调用虚方法'void android.hardware.Camera.setPreviewTexture(android.graphics.SurfaceTexture)'

所以我将"handleSetSurfaceTexture"函数更改为:

 private void handleSetSurfaceTexture(SurfaceTexture st) {
    if(mCamera == null)
    {
        Log.e(TAG, "mCamera return null");
        return;
    }
    st.setOnFrameAvailableListener(this);
    try {
        mCamera.setPreviewTexture(st);

    } catch (Exception ioe) {
        Log.e(TAG, "camera failed handleSetSurfaceTexture");
        throw new RuntimeException(ioe);
    }
    mCamera.startPreview();
}
Run Code Online (Sandbox Code Playgroud)

然后错误更改为:

java.lang.RuntimeException:java.io.IOException:setPreviewTexture在jp.co.cyberagent.android.gpuimage.grafika.CameraCaptureActivity.handleSetSurfaceTexture(CameraCaptureActivity.java:1150)失败

我读了许多其他相机应用程序源代码,我想可能在MTK设备中有Camera和SurfaceRender的同步问题.所以我改变了这样的代码:

private void waitUntilSetup()
{
    long l = System.currentTimeMillis();
    while ((getMaxTextureSize() == 0) && (System.currentTimeMillis() - l < 3000L))
    {
        SystemClock.sleep(100L);
    }

    Log.e(TAG,"getMaxTextureSize() = " + getMaxTextureSize());
}

private int getMaxTextureSize() {
    int[] maxTextureSize = new int[1];
    GLES20.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, …
Run Code Online (Sandbox Code Playgroud)

android glsurfaceview android-camera grafika

6
推荐指数
1
解决办法
3199
查看次数

录制时如何将音频添加到视频[ContinuousCaptureActivity] [Grafika]

我使用ContinuousCaptureActivity.java实现视频录制.它的工作完美.

现在我想在此视频中添加音频.

我知道使用MediaMuxer可以在视频中添加音频.

但问题是我不知道如何使用MediaMuxer.

此外,如果您有任何其他解决方案,MediaMuxer然后与我分享任何链接或文档.

我也有演示AudioVideoRecordingSample.但我不明白如何将其与我的代码合并.

如果有人知道,请向我解释.

提前致谢.

android mediacodec grafika

6
推荐指数
1
解决办法
273
查看次数

SurfaceTexture.getTimestamp() 在播放过程中返回 0

最近我在 Android 5.0.2 (API 21) 上遇到了一个奇怪的问题。我的应用程序使用 SurfaceTexture 来显示视频。播放机制主要基于google/grafika 的 CameraCaptureAvtivity,但视频源是解码 .mp4 电影文件而不是相机。该应用程序运行良好,直到我在带有 Android 5.0.2 的 Galaxy S6 上运行它(在那之前我成功使用了 4.4.2 和 4.4.4 的设备)。问题是,每次我尝试从 SurfaceTexture 接收时间戳时getTimestamp(),该方法都会返回 0,但播放没问题。在时间戳正确之前我提到的其他设备上。
有人可以告诉我这是否可能是Android错误?有什么办法可以解决吗?

java android grafika android-mediacodec

5
推荐指数
0
解决办法
852
查看次数

Android精确搜索视频

我正在努力使用MediaExtractor进行精确搜索seekTo().虽然我可以毫无问题地寻求同步帧,但我想寻求具体的时间.这个问题让我想到了如何做到这一点,但我不确定它们是否有效.基本上,我必须寻找最接近的前一个同步帧,然后寻求advance()提取器,直到达到目标时间.该过程中的每个帧将被馈送到解码器,即第一个I帧和其余的P帧.这是相关的代码段(基于google/grafika的MoviePlayer):

extractor.seekTo((long) seekTarget[threadNr], MediaExtractor.SEEK_TO_PREVIOUS_SYNC);

...

while (extractor.getSampleTime() < (long) seekTarget[threadNr]) {
    Log.d(TAG, "Thread " + threadNr + " advanced to timestamp " + extractor.getSampleTime());

    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
    if (inputBufIndex >= 0) {
        ByteBuffer inBufer = decoderInputBuffers[inputBufIndex];
        int chunkSize = extractor.readSampleData(inBufer, 0);

        if (chunkSize < 0) {
            // End of stream -- send empty frame with EOS flag set.
            decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L,
                    MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            inputDone = true;
            if (VERBOSE) Log.d(TAG, "sent input …
Run Code Online (Sandbox Code Playgroud)

android seek mediacodec mediaextractor grafika

5
推荐指数
1
解决办法
1359
查看次数

使用Matrix的rotateM()从SurfaceTexture旋转矩阵但损坏视频输出

我设法用opengl es播放视频,我使用了grafika的ContinuousCaptureActivity方式,我的数据源是MediaPlayer而不是Camera,这没什么区别.MediaPlayer连续生成视频帧,我在onFrameAvailable回调中绘制每个帧到屏幕.代码如下,效果很好:

    mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers();
Run Code Online (Sandbox Code Playgroud)

现在我想旋转270度的视频帧,所以我改变了代码:

        GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    Matrix.rotateM(mTmpMatrix, 0, 270, 1f, 0, 0);
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers();
Run Code Online (Sandbox Code Playgroud)

但结果很奇怪,请看下面的图片: 在此输入图像描述

但我可以使用以下代码成功翻转视频帧:

        mVideoTexture.updateTexImage();
    mVideoTexture.getTransformMatrix(mTmpMatrix);
    mDisplaySurface.makeCurrent();
    int viewWidth = getWidth();
    int viewHeight = getHeight();
    GLES20.glViewport(0, 0, viewWidth, viewHeight);
    mTmpMatrix[5] = -1 * mTmpMatrix[5];
    mTmpMatrix[13] = 1.0f - mTmpMatrix[13];
    mFullFrameBlit.drawFrame(mTextureId, mTmpMatrix);
    mDisplaySurface.swapBuffers(); …
Run Code Online (Sandbox Code Playgroud)

android opengl-es rotation matrix grafika

5
推荐指数
1
解决办法
2502
查看次数

glMapBufferRange()很慢,Android上的映射数据的memcpy()也很慢

我设法编写了一个视频录制演示,类似于grafika 的ContinuousCaptureActivity(ContinuousCaptureActivity.java的源代码).

不同之处在于grafika使用了硬件编码,但我使用了软件编码.对于软件编码,我使用PBO从GPU获取每个视频帧非常快并将图像数据复制到ffmpeg,然后执行h264编码.

对于大多数设备来说,性能是可以接受的,glMapBufferRange()花了不到5ms而memcpy()花了不到10ms.

但是华为mate7手机的性能很低.glMapBufferRange()需要15~30ms,memcpy()需要25~35ms.

我在mate7上测试了正常的memcpy(),复制普通内存时速度要快得多.

真的很奇怪,谁可以给我一些帮助?

设备信息:

chipset of the phone: HiSilicon Kirin 925
cpu of the phone: Quad-core 1.8 GHz Cortex-A15 & quad-core 1.3 GHz Cortex-A7
Run Code Online (Sandbox Code Playgroud)

详见:huawei mate 7

pbo代码如下:

    final int buffer_num = 1;
final int pbo_id[] = new int[buffer_num];
private void getPixelFromPBO(int width, int height, boolean isDefaultFb) {
    try {
        long start = System.currentTimeMillis();

        final int pbo_size = width * height * 4;

        if (mFrameNum == 0) { …
Run Code Online (Sandbox Code Playgroud)

performance opengl-es memcpy pbo grafika

5
推荐指数
0
解决办法
921
查看次数

OMX.qcom编码器随机崩溃

该应用程序基于Grafika的相机捕获活动(https://github.com/google/grafika/tree/master/src/com/android/grafika)。用户点击按钮以录制视频。Nexus 5x随机崩溃。下面发布了2条日志,分别说明何时可以正常工作以及什么时候不工作。请告诉我造成此崩溃的原因是什么,以及是否需要我发布代码的任何部分。

工作方式:

11-21 15:55:22.301 26556-27085/com.testvideo I/OMXClient: MuxOMX ctor
11-21 15:55:22.505 26556-27085/com.testvideo E/ACodec: [OMX.qcom.video.encoder.avc] storeMetaDataInBuffers (output) failed w/ err -1010
11-21 15:55:22.505 26556-27085/com.testvideo W/ACodec: do not know color format 0x7fa30c04 = 2141391876
11-21 15:55:22.506 26556-27085/com.testvideo W/ACodec: do not know color format 0x7f000789 = 2130708361
11-21 15:55:22.518 26556-27085/com.testvideo I/ACodec: setupAVCEncoderParameters with [profile: Baseline] [level: Level31]
11-21 15:55:22.520 26556-27085/com.testvideo I/ACodec: [OMX.qcom.video.encoder.avc] cannot encode color aspects. Ignoring.
11-21 15:55:22.520 26556-27085/com.testvideo I/ACodec: [OMX.qcom.video.encoder.avc] cannot encode HDR static metadata. Ignoring.
11-21 15:55:22.520 26556-27085/com.testvideo …
Run Code Online (Sandbox Code Playgroud)

android video-encoding mediacodec grafika

5
推荐指数
1
解决办法
950
查看次数

在 Android 中创建位图之前从 Bytebuffer 翻转 openGL 纹理

我正在使用依赖于 Google 的 Grafika 存储库的实时流 API。我使用 Grafika EGLSurfaceBase 的 saveFrame 方法来允许用户在流式传输时捕获视频的静态图像。

https://github.com/google/grafika/blob/master/src/com/android/grafika/gles/EglSurfaceBase.java

实际捕获有效,但显然在某些相机方向上图像会翻转。

我发现了很多与从 OpenGL 纹理获取的倒置位图相关的问题 - 但大多数似乎是指绘制的图像并依赖于:

a) 在 OpenG 中翻转纹理。但就我而言,我正在使用实时流 API,因此翻转纹理来捕获图像实际上可能也会翻转视频流上的图像捕获。

或者

b) 在基于资源生成位图后翻转位图。就我而言,我没有资源,我正在从字节缓冲区创建位图,并且不想复制它来翻转它。

这是 API 具有的基本 EGLSurfaceBase 方法 - 我将把相机方向传递给它,但我的问题是:

        String filename = file.toString();

    int width = getWidth();
    int height = getHeight();
    ByteBuffer buf = ByteBuffer.allocateDirect(width * height * 4);
    buf.order(ByteOrder.LITTLE_ENDIAN);
    GLES20.glReadPixels(0, 0, width, height,
            GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
    GlUtil.checkGlError("glReadPixels");
    buf.rewind();

    BufferedOutputStream bos = null;
    try {
        bos = new BufferedOutputStream(new FileOutputStream(filename));
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); …
Run Code Online (Sandbox Code Playgroud)

android opengl-es bitmap grafika

4
推荐指数
1
解决办法
2808
查看次数

MediaCodec 编码的视频底部有绿条,色度搞砸了

我从Grafika开始了一个项目并对其进行了修改。我有一个框架(与原始框架没有太大区别),它可以从 中捕获预览Camera并同时以不同的分辨率将其连续编码为视频。

MediaCodec(用于编码)配置为使用COLOR_FormatSurface,以便我们能够渲染到getInputSurface()使用 GLES查询的 Surface 。

媒体格式设置为 MIME 类型 video/avc

对于大多数手机,此设置非常有效。

但对于一些手机,编码视频的色度值略微倾斜,底部有一个绿色条。

目前编码器表面的分辨率为 640x360。选择渲染到表面的 EGLConfig 支持 32 位 RGBA 格式。

预览是完美的所有手机。

所以我假设应用程序端或操作系统框架端的编码器参数有问题。

它发生在 Android 4.4 上。- 不确定,是否可以在 5.* 上重现。

![绿条图像] 2

encoding android opengl-es grafika android-mediacodec

4
推荐指数
1
解决办法
1732
查看次数

是否可以/如何将 MediaCodec 解码帧直接提供给 MediaCodec 编码器?

我的目标是拼接多个视频文件中的视频片段。片段由任意开始时间和结束时间定义。最初我想使用像 mp4parser 这样的库来做到这一点,但它只能在同步(IFRAME)点切割流,而我需要更高的精度。

我的场景是从文件中提取编码流 -> 解码 -> 编码 -> 将结果混合到 mp4 文件中。目前,代码通常可以工作,但生成的视频是白噪声。在 Nexus-S 和 Galaxy-S3 上进行了测试。我的代码是几个示例的组合:

  • 基于MoviePlayer.java读取之前录制的文件
  • 解码-编码:DecodeEditEncodeTest.java
  • 将视频流复用为 mp4 - 又一个示例,此处不相关

我想简化示例,因为我不需要在中间处理帧。我尝试将缓冲区从解码器输出馈送到编码器输入,而中间没有 Surface。整个过程的工作原理是代码运行完成并生成可播放的视频文件。然而文件的内容是白噪声。

这是将帧从解码器提供给编码器的代码片段。有什么问题以及如何使其发挥作用?

...
} else { // decoderStatus >= 0
    if (VERBOSE) Log.d(TAG, "surface decoder given buffer "
                            + decoderStatus + " (size=" + info.size + ")");
    // The ByteBuffers are null references, but we still get a nonzero
    // size for the decoded data.
    boolean doRender = (info.size != 0);
    // As soon as we call …
Run Code Online (Sandbox Code Playgroud)

video android video-processing grafika android-mediacodec

0
推荐指数
1
解决办法
2120
查看次数