标签: android-mediacodec

MediaCodec - 处理丢帧的视频

这是一个很长的问题,但我必须解释我正在经历的问题才能正确地解决问题.希望我能找到像@fadden@mstorsjo这样的人来看看这个问题.

有关此问题的最新更新,请参阅编辑3.


我目前正在快速精确地寻求使用MediaCodec.我目前要逐帧跳过的是,我首先得到总帧数:

mediaInfo.totalFrames = videoTrack.getSamples().size();
Run Code Online (Sandbox Code Playgroud)

然后我得到视频文件的长度:

mediaInfo.durationUs = videoTrack.getDuration() * 1000 *1000 / timeScale;

//then calling:
public long getDuration() {
    if (mMediaInfo != null) {
        return (int) mMediaInfo.durationUs / 1000; // to millisecond
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我想要获得下一帧时,我会调用以下内容:

mNextFrame.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            int frames = Integer.parseInt(String.valueOf(getTotalFrames));
            int intervals = Integer.parseInt(String.valueOf(mPlayer.getDuration() / frames));

            if (mPlayer.isPlaying()) {
                mPlayer.pause();
                mPlayer.seekTo(mPlayer.getCurrentPosition() + intervals);
            } else {
                mPlayer.seekTo(mPlayer.getCurrentPosition() + intervals);
            }

        }
    }); …
Run Code Online (Sandbox Code Playgroud)

android mediacodec android-mediacodec

17
推荐指数
0
解决办法
554
查看次数

在Android上以编程方式获取MPEG-4视频流的配置文件

有没有办法使用标准Android API 获取MPEG-4视频文件的个人资料代码

示例配置文件的代码如下:baseline,main,high等.

我不想ffmpeg在Android应用程序中包含二进制文件以获取此信息.

我在MediaCodecInfo.CodecProfileLevel类中找到了配置文件列表的引用.任何人都可以确认这是否是我应该使用的那个?

以下是从MX Player应用程序中 获取的视频信息的示例屏幕截图带视频资料的示例数据


  • 更新#1:我查看了MX Player应用程序,看起来他们使用ffmpeg二进制文件,所以我可以肯定地说他们使用它来提取profile-code.
  • 更新#2:我也查看了ExoPlayer v1 API,它们似乎也没有特定的API来获取此信息.

android mpeg-4 android-mediaplayer mediaextractor android-mediacodec

11
推荐指数
1
解决办法
954
查看次数

使用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
查看次数

Android 无法实例化编解码器“video/avc”

这是我的第一篇文章,所以请耐心等待。

我正在尝试将原始 h264 视频播放到 Android 应用程序中的 Surface 对象上。我在 HTC 上使用 android 5.0.1。在阅读了 android 文档后,我发现我需要使用 MediaCodec 对象来解码原始字节,然后将它们释放到 Surface。我已经倾注了大量其他问题和文档,但还没有找到我看似非常简单的问题的答案。这是我的代码片段:

        @Override
        public void surfaceCreated(SurfaceHolder surfHolder) {
            try {
                String codecType = "video/avc";
                MediaFormat mf = MediaFormat.createVideoFormat(codecType, 45 ,45);
                mc = MediaCodec.createByCodecName(codecType);
                mc.configure(mf, surfHolder.getSurface(), null, 0);
                mc.setCallback(vcb);
                mc.start();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是,当它尝试按名称创建编解码器时遇到了问题,并且出现此错误:

08-26 18:09:02.054    9132-9132/com.james.firstclient I/InputMethodManager? [startInputInner] EditorInfo { packageName=com.james.firstclient, inputType=0x20001, imeOptions=0x48000005, privateImeOptions=null }, windowGainingFocus=android.view.ViewRootImpl$W@37cf53de, mServedView=android.widget.EditText{2a8889bf VFED..CL .F....I. 48,177-1032,290 #7f080001 app:id/hostText}, mServedInputConnectionWrapper=android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper@3ed5088c
08-26 18:09:03.964    9132-9292/com.james.firstclient D/libc? [NET] android_getaddrinfofornet+,hn 12(0x3139322e313638),sn(),hints(known),family …
Run Code Online (Sandbox Code Playgroud)

android video-streaming h.264 android-mediacodec

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

如何防止MediaCodec.dequeueInputBuffer产生的java.lang.IllegalStateException

以下代码偶尔会生成 java.lang.IllegalStateException:

 int iInputBufIndex = _mcDecoder.dequeueInputBuffer(TIMEOUT_USEC);
Run Code Online (Sandbox Code Playgroud)

其中 _mcDecoder 是 MediaCodec 的一个实例。解码后的流是 H.264 视频。该代码在大多数情况下运行良好。有没有办法主动检查MediaCodec的状态来避免这个异常?

堆栈跟踪:

java.lang.IllegalStateException
    at android.media.MediaCodec.dequeueInputBuffer(Native Method)
at net.mydomain.android.MYNAMESPACE.MYCLASS.MyMethod0(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS.ProcessH264(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS.MyMethod1(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS.MyMethod2(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS.MyMethod3(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS.access$5(Unknown Source)
at net.mydomain.android.MYNAMESPACE.MYCLASS$1.run(Unknown Source)
at java.lang.Thread.run(Thread.java:841)
Run Code Online (Sandbox Code Playgroud)

android android-mediacodec

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

使用MediaCodec和MediaMuxer录制视频,但码率和帧率不正确

我写了一个演示来使用 MediaCodec 和 MediaMuxer 录制视频。

我用我的demo录制了一段视频,用ffprobe查看视频,结果如下:

  Duration: 00:00:06.86, start: 0.000000, bitrate: 723 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 320x240, 619 kb/s, SAR 1:1 DAR 4:3, 30.02 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : VideoHandle
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 96 kb/s (default)
Metadata:
  creation_time   : 2015-06-05 13:19:24
  handler_name    : SoundHandle
Run Code Online (Sandbox Code Playgroud)

它包含视频和音频信息,我发现音频属性与我在源代码中设置的相同,但视频属性不正确。我的视频设置源码如下:

        MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 384000); …
Run Code Online (Sandbox Code Playgroud)

android bitrate mediamuxer android-mediacodec

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

具有 MediaCodec Surface 可靠性的 AVC 硬件编码器?

我正在开发一个 Android 应用程序,该应用程序使用 MediaCodec 使用 Surface 方法对 H.264 视频进行编码。我的目标是 Android 5.0,并且我遵循了 bigflake.com 上的所有示例和示例(我两年前开始研究这个项目,所以我经历了所有的问题和其他问题)。

在 Nexus 6(它使用 Qualcomm 硬件编码器来执行此操作)上一切正常,并且我能够以多种输出(来自 MP4 本地文件,高达 http 流)。但是,当我尝试在使用 Mediatek 芯片组的 Sony Android TV(运行 Android 5.1)上使用该应用程序时,即使从编码级别开始,一切都变得混乱起来。更具体:

  1. 基本上不可能让硬件编码器正常工作(即“OMX.MTK.VIDEO.ENCODER.AVC”)。使用最基本的设置(在 MediaCodec 级别成功),我将永远不会从中获取输出缓冲区,只有奇怪的、垃圾邮件、logcat 错误消息指出驱动程序在每次应编码帧时遇到错误,如下所示:

    01-20 05:04:30.575 1096-10598/? E/venc_omx_lib: VENC_DrvInit failed(-1)!
    01-20 05:04:30.575 1096-10598/? E/MtkOmxVenc: [ERROR] cannot set param
    01-20 05:04:30.575 1096-10598/? E/MtkOmxVenc: [ERROR] EncSettingH264Enc fail
    
    Run Code Online (Sandbox Code Playgroud)
  2. 有时,尝试将其配置为以 360 x 640 像素分辨率进行编码将成功使编码器实际编码内容,但我会注意到的第一个问题是它只会创建一个关键帧,即第一个视频帧。在那之后,不再创建任何关键帧,只有 P 帧。当然,i-frame-interval 设置为一个不错的值,并且在其他设备上没有问题。不用说,这使得创建可查找的 MP4 文件或任何类型的流媒体解决方案成为不可能。

  3. 大多数情况下,在释放编码器后,logcat 将开始无休止地发送“等待输入帧被释放...”的垃圾邮件,这基本上需要重新启动设备,因为从那时起无论如何都不会起作用。

  4. 如果它没有在简单的 release() 之后大肆破坏,没问题 - 硬件编码器确保它不能被第二次创建,并且它回退到通用的 SOFTWARE avc google 编码器。hich ofcourse 基本上是一个模型编码器,它在尝试编码大于 160p 的任何视频时只会吐出一个错误......

所以,我的问题是:有没有希望让这个 …

android android-mediacodec

6
推荐指数
0
解决办法
1539
查看次数

Android MediaCodec 将原始视频编码为 h264

我正在尝试将我的手机相机输出转换为 .h264 es 格式,但 MediaCodec 编码器在第一帧后停留在 TRY_AGAIN_LATER 输出缓冲区状态。相机预览设置为 NV21。

这是相机到编码器:

    mCamera.setPreviewCallback(new Camera.PreviewCallback() {
            private long timestamp=0;
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                byte[] buffer = new byte[data.length];
                encode(data);
            }
        });
Run Code Online (Sandbox Code Playgroud)

编码器初始化:

private void initCodec() {
        try {
            mBufferInfo = new MediaCodec.BufferInfo();
            mMediaCodec = MediaCodec.createEncoderByType("video/avc");
        } catch (IOException e) {
            e.printStackTrace();
        }
        MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc",
                1920,
                1080);
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 125000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
             MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        mMediaCodec.configure(mediaFormat,
                null,
                null,
                MediaCodec.CONFIGURE_FLAG_ENCODE);
        mMediaCodec.start();
    }
Run Code Online (Sandbox Code Playgroud)

和编码器本身:

private synchronized void encode(byte[] data) { …
Run Code Online (Sandbox Code Playgroud)

encoding android h.264 android-mediacodec

6
推荐指数
0
解决办法
4670
查看次数

Android MediaCodec dequeueInputBuffer 总是返回 -1

我正在尝试从 AudioRecord 对象中获取原始数据,并使用 MediaMuxer 和 MediaCodec 将其保存在文件中。

我启动编解码器,启动多路复用器,将数据加载到输入缓冲区中,但没有这样的运气。

从调试调查中,我发现问题发生在对dequeueInputBuffer(). 看起来前几块数据成功了,但最终dequeueInputBuffer()只是-1不断返回。

有什么明显的东西我失踪了吗?这似乎是我正在填满输入缓冲区,但编解码器永远不会释放它们。

相关代码片段:

int numChunks = input.length / CHUNKSIZE;
mAudioEncoder.start();
    for (int chunk = 0; chunk <= numChunks; chunk++) {
        byte[] passMe = new byte[CHUNKSIZE];
        int inputBufferIndex = -1;
        Log.d("offerAudioEncoder","printing chunk #" + chunk + "of " + numChunks);
        //Copy the data into the chunk array
        if (chunk < input.length / CHUNKSIZE)
            for (int i = 0; i < CHUNKSIZE; i++)
                passMe[i] = input[chunk * …
Run Code Online (Sandbox Code Playgroud)

audio encoding android mediamuxer android-mediacodec

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

如何将 Android MediaCodec Surface 连接到 Vulkan

我对使用 Android MediaCodec 进行解码并将 YUV 通过 Surface 馈送到 OpenGL 纹理有很好的理解。我想用 Vulkan 做类似的事情。但是我没有成功找到任何文档或示例代码。

我的问题是:我将如何连接以下管道?

MediaCodec Video Decoder ? Surface ? texture ? Vulkan
Run Code Online (Sandbox Code Playgroud)

细节

OpenGL 比较

为了进行比较,在 OpenGL 的情况下,Android Surface 的构造和使用方式如下

 textureId = glGenTextures( &textureId )
 surface = new Surface( new SurfaceTexture( textureId ) )
 mediaCodec.configure( surface )
Run Code Online (Sandbox Code Playgroud)

android vulkan android-mediacodec

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