标签: mediacodec

带表面输入的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直播

我想以Periscope的方式进行直播.我在网上做了一个快速搜索,发现像ffmpeg一样的库使用本机库,但根据MediaCodec编码应该直接支持Android SDK吗?

https://developer.android.com/reference/android/media/MediaCodec.html

所以我想知道为什么编码需要外部本机库?

我也尝试了一些库,但它们似乎太慢了,特别是对于高比特率(我在Nexus 5X上获得16个fps,1280x720,2500Kbps,我希望达到1080),流行的广播应用程序如何做到这一点?

由于涉及如此多的处理,似乎不可能使用普通电话(不是顶级线路)实现高质量的流媒体.

video android rtmp video-streaming mediacodec

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

Android MediaCodec编码器 - 三星设备的奇怪结果

编辑:

似乎问题是这个设备不需要16个维度的多个...但是32的倍数.事实是,我仍然不知道如何确定什么量化为有问题的设备.这似乎使用qcom(我已经看到在Android 4.X上有问题,但这是Android 5.1.1).


我正在Android应用中编码视频.我正在使用Android MediaCodec这样做,将每帧的RGB转换为YUV并传入像素.

我使用的代码已经存在了一段时间,并且适用于我遇到过的任何设备.

一位用户带着一个错误报告来找我说他们的MP4很奇怪.该设备是三星T337A(Galaxy Tab 4).

这是MP4出口的样子:

在此输入图像描述

注 - 出于任何奇怪的原因,它不会在所有分辨率下发生.它确认发生在768x432和1280x720,但不会发生在640x352(例如我的应用程序确保所有分辨率都可以被16整除).

Nexus 5X(使用相同的半平面YUV格式)上,输出适用于所有分辨率.

所以这是该设备的东西,也许是我不知道的其他设备?


我查看了所有输出,它看起来正常并且与我上面提到的Nexus 5X相同(100%的时间都可以工作).

正在使用的MediaCodecInfo是OMX.qcom.video.encoder.avc,使用的颜色格式是2135033992(这是COLOR_FormatYUV420Flexible).所以基本上没什么奇怪的.

代码有点广泛,我会在必要时发布,但只是寻找为什么会发生这种情况的一般想法.我知道它是否更常见,但相同的代码适用于大量其他设​​备,所以一些时髦的东西正在发生......

android video-encoding android-hardware galaxy-tab mediacodec

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

如何直接从Android Surface访问EGL图像以用于MediaCodec视频解码器?

我正在编写一个Android应用程序,我需要缓存视频帧,以便我可以轻松地来回转移,几乎没有延迟.

现在我让android解码视频帧,方法是在MediaCodec对象的Configure调用中提供一个Surface 并调用releaseOutputBufferrender flag设置为true.

的唯一方法,我发现访问解码表面数据(除了解码所返回的字节缓冲区,其格式似乎是依赖于设备的)是调用updateTeximageSurfaceTexture链接到表面,附接这对GL_TEXTURE_EXTERNAL_OES目标和它渲染到GL_TEXTURE2D目标纹理我创建我自己为了缓存它.

我想优化这个缓存过程,并能够解码不同线程上的帧.使用我当前的方法,这意味着我将不得不为视频解码器创建另一个EGL上下文,共享上下文等...

我的问题是:是否可以在不调用的情况下访问与Surface关联的EGL图像或本机缓冲区数据 updateTexImage

这样我就可以缓存egl图像(根据不需要EGL上下文EGL_ANDROID_image_native_buffer).这也将以YUV格式缓存,这比我现在缓存的原始RGB纹理更具存储效率.

video android caching egl mediacodec

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

Android MediaCodec解码h264原始帧

我正在使用Android MediaCodec API来解码h264帧.我可以在视图上解码和渲染帧.我的问题是解码器错过了很多帧,特别是前几帧.DecodeMediaCodec.dequeueOutputBuffer()返回-1.a约150 h264帧,刚解码43帧.我找不到问题所在.这是我的代码.

 /**
 * init decoder
 */
private void initDecodeMediaCodec()
{
    mDecodeMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
    MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE,
            VIDEO_WIDTH_640,
            VIDEO_HEIGHT_480);

    mDecodeMediaCodec.configure(format,
            new Surface(mRemoteVideoView.getSurfaceTexture()),
            null,
            0);
    mDecodeMediaCodec.start();
    mDecodeInputBuffers = mDecodeMediaCodec.getInputBuffers();
    System.out.println("decode-----"
            + mDecodeMediaCodec.getCodecInfo().getName());
}
Run Code Online (Sandbox Code Playgroud)

解码器初始化后,我将启动解码器线程.

 /**
 * 
 * @param frameData
 */
private void decode()
{
    new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            while (true)
            {
                ByteBuffer decodeDataBuffer = null;
                try
                {
                    //take h264 frame from cache queue
                    decodeDataBuffer = decodeDataQuene.take();
                }
                catch (InterruptedException e)
                { …
Run Code Online (Sandbox Code Playgroud)

android decode mediacodec

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

在Android设备中转码音频/视频/图像文件

我正在开发像whatsApp这样的聊天应用程序,我想在上传到服务器之前对媒体文件进行转码,我已经经历了这么多链接但是无法决定我应该使用哪种方法,是否有任何直接的转码方式在Android中?

  • FFMPEG我发现它是高度cpu密集的过程,它会消耗更多的电池电量

  • Media Codec 我想使用mediacodec进行转码,但无法获得正确的步骤来理解这个过程.

提供有关转码的最佳链接

使用媒体编解码器转码的库(它有很多错误)

transcoding mediacodec

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

使用MediaCodec和Camera2 API录制视频

我正在尝试使用MediaCodec在onImageAvailable回调中记录ImageReader中的原始帧,但无法编写正常工作的代码.大多数示例都使用Camera 1 API或MediaRecorder.我的目标是捕获单个帧处理它并从中创建一个mp4

原始的YUV帧

        @Override
        public void onImageAvailable(ImageReader reader) {
            Image i = reader.acquireLatestImage();
            processImage(i);
            i.close();
            Log.d("hehe", "onImageAvailable");
        }
    };
Run Code Online (Sandbox Code Playgroud)

MediaCodec

MediaCodec codec = MediaCodec.createByCodecName(name);
 MediaFormat mOutputFormat; // member variable
 codec.setCallback(new MediaCodec.Callback() {
   @Override
   void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
     // fill inputBuffer with valid data
     …
     codec.queueInputBuffer(inputBufferId, …);
   }

   @Override
   void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
     // bufferFormat is equivalent to mOutputFormat
     // …
Run Code Online (Sandbox Code Playgroud)

android mediacodec android-camera2 android-mediacodec

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

视频使用OnAudioFilterRead数据编码错误

我正在尝试使用OnAudioFilterRead函数将Unity游戏音频录制到mp4文件.

function OnAudioFilterRead(var data:float[], var channels:int)
Run Code Online (Sandbox Code Playgroud)

我的解决方案概述.
步骤1.将从Unity获取的数据样本转换为bytes []

private void Convert2Bytes(float[] samples) {
    Int16[] intData = new Int16[samples.Length];
    //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]

    Byte[] bytesData = new Byte[samples.Length * 2];
    //bytesData array is twice the size of
    //dataSource array because a float converted in Int16 is 2 bytes.

    float rescaleFactor = 32767; //to convert float to Int16

    for (int i = 0; i<samples.Length; i++) {
        intData[i] = (short) ((samples[i] * gain) * rescaleFactor); …
Run Code Online (Sandbox Code Playgroud)

mp4 android unity-game-engine h.264 mediacodec

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

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

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

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

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

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

audio video android mediacodec grafika

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

如何检查Android MediaCodec是否支持恒定质量模式

我有一个屏幕录制应用程序,它使用MediaCodec编码器对视频帧进行编码.这是我检索视频编码器的一种方法:

videoCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
Run Code Online (Sandbox Code Playgroud)

然后我尝试确定此编码器支持的最佳比特率模式,我的优先顺序是"恒定质量"模式,可变比特率模式,恒定比特率模式.这是我尝试这样做的方式:

MediaCodecInfo.CodecCapabilities capabilities = videoCodec.getCodecInfo().getCapabilitiesForType(MediaFormat.MIMETYPE_VIDEO_AVC);
MediaCodecInfo.EncoderCapabilities encoderCapabilities = capabilities.getEncoderCapabilities();

if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ)) {
    Timber.i("Setting bitrate mode to constant quality");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR)) {
    Timber.w("Setting bitrate mode to variable bitrate");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
} else if (encoderCapabilities.isBitrateModeSupported(MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR)) {
    Timber.w("Setting bitrate mode to constant bitrate");
    videoFormat.setInteger(MediaFormat.KEY_BITRATE_MODE, MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR);
}
Run Code Online (Sandbox Code Playgroud)

在我的三星Galaxy S7上运行它最终选择VBR模式,即据说不支持恒定质量模式.但是,如果我只是将BITRATE_MODE设置为恒定质量,它不仅可以工作,而且实际上可以产生比VBR模式更高质量的视频.

因此,如果此编码器显然支持恒定质量模式,为什么我会从isBitrateModeSupported()获得误报?我在这里错过了什么吗?

android video-capture video-encoding mediacodec

8
推荐指数
1
解决办法
814
查看次数