小编dbr*_*bro的帖子

使用Android的MediaCodec和MediaMuxer复用AAC音频

我正在修改一个Android Framework示例,将MediaCodec生成的基本AAC流打包成一个独立的.mp4文件.我正在使用MediaMuxer包含由MediaCodec实例生成的一个AAC轨道的单个实例.

但是,我总是在调用时始终收到错误消息mMediaMuxer.writeSampleData(trackIndex, encodedData, bufferInfo):

E/MPEG4Writer?timestampUs 0 < lastTimestampUs XXXXX for Audio track

当我将原始输入数据排队时,mCodec.queueInputBuffer(...)我提供0作为每个框架示例的时间戳值(我也尝试使用具有相同结果的单调增加的时间戳值.我已成功将原始相机帧编码为h264/mp4文件同样的方法).

查看完整的来源

最相关的片段:

private static void testEncoder(String componentName, MediaFormat format, Context c) {
    int trackIndex = 0;
    boolean mMuxerStarted = false;
    File f = FileUtils.createTempFileInRootAppStorage(c, "aac_test_" + new Date().getTime() + ".mp4");
    MediaCodec codec = MediaCodec.createByCodecName(componentName);

    try {
        codec.configure(
                format,
                null /* surface */,
                null /* crypto */,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
    } catch (IllegalStateException e) {
        Log.e(TAG, "codec '" + …
Run Code Online (Sandbox Code Playgroud)

android mediacodec

14
推荐指数
1
解决办法
1万
查看次数

带表面输入的MediaCodec:在后台录制

我正在开发一个视频编码应用程序,我希望阻止在托管活动进入后台时停止,或者屏幕循环开/关.

我的编码器的架构源自出色的CameraToMpegTest示例,并在GLSurfaceView中添加了显示相机帧(请参阅下面的Github链接).我目前正在使用双态解决方案进行背景录制:

  • 当托管活动是在前台,在每个呼叫中的一个视频帧编码到GLSurfaceView.RendereronDrawFrame.这允许我以突发方式访问GLSurfaceView的EGL状态,以便不阻止排队到渲染器线程的其他事件.

  • 当托管活动进入后台时,停止onDrawFrame编码并在循环内的另一个后台线程上编码帧.此模式与CameraToMpegTest示例相同.

但是,如果屏幕关闭,GLSurfaceView的EGLContext将丢失并发生新的调用onSurfaceCreated.在这种情况下,我们必须重新创建连接到MediaCodec输入Surface的EGL窗口表面.不幸的是,第二次调用eglCreateWindowSurface产生:

E/libEGL(18839): EGLNativeWindowType 0x7a931098 already connected to another API
Run Code Online (Sandbox Code Playgroud)

在致电之前,我发布了连接到Android Surface的所有EGL资源.

有没有办法交换连接到MediaCodec输入Surface的EGLSurface?

我的测试应用程序的完整源代码是在Github上.主要活动.

更新我根据MediaCodec和MediaMuxer类将此处学到的经验应用到Android视频sdk中.希望能帮助到你!

android mediacodec

10
推荐指数
1
解决办法
5279
查看次数

Android的BLE服务发现(BluetoothGatt#discoverServices())和低能耗与BR/EDR

TLDR:服务发现结果discoverServices()是否会因底层传输(LE与BR/EDR)而有所不同?

我有一个混合模式蓝牙配件,提供蓝牙经典设备和蓝牙LE外设的独特功能.

Android无法发现配件的蓝牙LE GATT服务,除非您使用隐藏的peerBluetoothDevice.connectGatt(context, autoConnect, gattCallback, BluetoothDevice.TRANSPORT_LE)API允许您强制使用其中任何一个TRANSPORT_LETRANSPORT_BREDR.

当我通过设备连接peerBluetoothDevice.connectGatt(context, autoConnect, gattCallback)然后调用时,discoverServices()我只发现通用的服务UUID(并且只有在许多连接尝试失败后才会发送神秘状态133 onConnectionStateChange).

  • "00001800-0000-1000-8000-00805f9b34fb"(通用访问)
  • "00001801-0000-1000-8000-00805f9b34fb"(通用属性).

但是,当我调用隐藏peerBluetoothDevice.connectGatt(context, autoConnect, gattCallback, BluetoothDevice.TRANSPORT_LE)然后调用时,discoverServices()我得到完整的预期服务发现响应:

  • "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"(我的定制服务)
  • "00001800-0000-1000-8000-00805f9b34fb"(通用访问)
  • "00001801-0000-1000-8000-00805f9b34fb"(通用属性).

这是预期的Android框架行为(怀疑它,因此隐藏API)?用这种"混合模式"操作设计外围设备是不好的形式?

android bluetooth-lowenergy android-bluetooth

10
推荐指数
1
解决办法
2777
查看次数

缓冲表面输入到MediaCodec

已经演示了如何使用像SurfacePreview这样的Surface输入提供MediaCodec,但是在提交之前是否有实用的方法来缓冲此输入MediaCodec

在我的实验中,Galaxy Nexus在使用CameraToMpegTest.java中的直接同步编码方法生成音频/视频流时遇到了令人无法接受的打嗝

当使用MediaCodecbyte[]ByteBuffer输入,我们可以提交未编码数据的ExecutorService或类似的队列进行处理,以确保帧不丢失,即使在CPU使用该设备的经验尖峰我们的应用程序的控制.但是,由于要求在Android的Camera和MediaCodec之间执行颜色格式转换,这种方法对于高分辨率的直播视频来说是不现实的.

想法:

  1. 有没有办法喂NativePixmapType以创建EGL14.eglCopyBuffers(EGLDisplay d, EGLSurface s, NativePixmapType p)MediaCodec

  2. 任何来自Android的人都可以评论相机和MediaCodec之间是否协调ByteBuffer格式是否在路线图上?

android mediacodec

7
推荐指数
1
解决办法
4798
查看次数

带Surface输入的MediaCodec:生成分块输出

我正试图通过CameraPreview数据生成短序列mp4文件MediaCodec.createInputSurface().但是,重新创建它MediaCodec和它相关的Surface需要停止相机以允许另一个调用mCamera.setPreviewTexture(...).该延迟导致不可接受的丢帧量.

因此,我需要定期生成CODEC_CONFIGEND_OF_STREAM数据,而无需重新创建输入Surface,因此必须调用mCamera.setPreviewTexture(...).这可能假设MediaFormat不变吗?

(我正在调整fadden的CameraToMpegTest示例.我的完整代码在这里)

不成功的尝试:

呼叫MediaCodec.signalEndOfInputStream(),排空MediaCodec,然后MediaCodec.flush()在块之间调用会产生IllegalStateException第二次呼叫MediaCodec.signalEndOfInputStream().

调用MediaCodec.signalEndOfInputStream(),排空MediaCodec,然后MediaCodec.stop(); MediaCodec.configure(...), MediaCodec.start()在不再调用之间调用块MediaCodec.createInputSurface()会产生以下错误:

    09-30 13:12:49.889  17638-17719/x.xx.xxxx E/Surface? queueBuffer: error queuing buffer to SurfaceTexture, -19
09-30 13:12:49.889  17638-17719/x.xx.xxxx E/IMGSRV? :0: UnlockPostBuffer: Failed to queue buffer 0x592e1e70
09-30 13:12:49.889  17638-17719/x.xx.xxxx E/CameraToMpegTest? Encoding loop exception!
09-30 13:12:49.889  17638-17719/x.xx.xxxx W/System.err? java.lang.RuntimeException: eglSwapBuffers: EGL …
Run Code Online (Sandbox Code Playgroud)

android mediacodec

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

在Android 4.3-4.4上请求具有蓝牙低功耗连接的MTU(API 18-20)

我有蓝牙低功耗应用程序,要求MTU大小超过默认的23个字节.

虽然Android 在API 21中引入了BluetoothGatt#requestMTU(),但是有没有办法,包括使用私有API来完成这个预先的API 21?

android bluetooth bluetooth-lowenergy

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

GLSurfaceView在Nexus 5上出现帧率问题

我有一个示例应用程序(完整源代码),使用MediaCodec对相机帧进行编码,同时在GLSurfaceView上显示它们.

Systrace确认每秒进行30次绘图调用:

Systrace截图

但是,屏幕记录录制(.mp4,YouTube)显示明显的帧速率要低得多.

简而言之,我的编码和显示循环执行以下操作:

  • 使MediaCodec Surface输入EGL上下文当前
  • 将相机框架绘制到MediaCodec EGL表面
  • 使GLSurfaceView EGL上下文成为当前
  • 将相同的相框绘制到GLSurfaceView

在Galaxy Nexus LTE和Nexus 7(均采用AOSP 4.4)上,应用程序按预期执行.到目前为止,只有Nexus 5在屏幕上绘制的帧数与明显的帧数之间存在差异......

我祈祷我不是疯了.

android glsurfaceview mediacodec

3
推荐指数
1
解决办法
2595
查看次数