标签: android-mediacodec

在 Xperia Z1 上使用 MediaCodec 编码相机预览帧时视频质量不一致

我正在NV21对来自相机预览的帧进行编码。由于某种原因,在其他设备上运行良好的模式Sony Xperia Z1Android 4.3. 它发送回质量不正确(低)的编码帧。

MediaCodec的格式是COLOR_FormatYUV420SemiPlanar(NV12我通过交换 U 和 V 分量NV21来转换NV12)。发送回给我的输出缓冲区的大小非常小,与我使用的分辨率 ( ) 和比特率 ( )MediaCodec不对应。最初的几帧质量很好,但随后质量显着下降:1280x7201000000

int encoderStatus = mMediaCodec.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
// a few encoderStatus checks skipped
ByteBuffer encodedData = outputBuffers[encoderStatus];
Log.i(Constants.TAG, "Buffer size " + mBufferInfo.size);
Run Code Online (Sandbox Code Playgroud)

Xperia Z1 上的日志如下:

Buffer size 26
Buffer size 52172
Buffer size 23650
Buffer size 14394
Buffer size 3591
Buffer size 1849
Buffer size 3908

... …
Run Code Online (Sandbox Code Playgroud)

android android-mediacodec

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

在 Android 上使用 MediaMuxer 录制音频和视频

我正在尝试使用 Android 4.3 中提供的 和 来录制音频和视频AudioRecordMediaCodec但是MediaMuxer,有时音频编码器线程会停止并且不再进行编码。结果是,mp4 文件损坏,因为复用器未接收任何编码的音频帧。在我的三星 Galaxy Note 3 上,它可以正常工作 99%,但在我的索尼 Xperia Z1 上,编码线程总是卡住。我真的不知道是什么原因,也许有人可以帮助我优化我的代码:

录音机.java

package com.cmdd.horicam;

import java.nio.ByteBuffer;

import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.media.MediaRecorder;
import android.os.Looper;
import android.util.Log;

public class AudioRecorder implements Runnable {
    public static final String TAG = "AudioRecorder";
    public static final boolean VERBOSE = false;

    public MovieMuxerAudioHandler mAudioHandler;

     // audio format settings
    public static final String MIME_TYPE_AUDIO = "audio/mp4a-latm";
    public static final int …
Run Code Online (Sandbox Code Playgroud)

audio video android mediamuxer android-mediacodec

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

如何使用 NDK 创建 ANativeWindow?

我想使用 NDK 和 opengl 在后台(无 UI)中分析视频。我想解码视频并在纹理(内存)上渲染。我们怎么做?

我尝试使用 AMediaCodec 直接在纹理上渲染。但问题是它需要 ANativeWindow(在 AMediaCodec_configure 中),我无法从 opengl 纹理(使用 glGenTextures 创建)创建它。任何人都可以请建议吗?

video android android-ndk android-mediacodec

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

预览分辨率与编解码器分辨率不匹配

我正在尝试在设备之间流式传输视频。我想尽可能支持旧设备。所以我从MediaRecorderGingerbread (API 10) 的课程开始,但它有问题。所以现在,我要转向 Jelly Bean (API 16) 和MediaCodec.

我正在向 Camera 中的编解码器提供数据PreviewCallback。我必须使用相同的分辨率进行预览和编解码器。但是在我们的一些测试设备上,预览分辨率和编解码器及其分辨率之间没有交集。

那么,如何在这些设备上捕捉视频呢?我知道有 createInputSurfacein MediaCodec,但它需要 API 18,我将不得不削减超过 35%的设备,这是不可接受的。

那么如何解决呢?

寻找最佳分辨率的代码:

CamcorderProfile bestProfile() {
    final int[] profiles;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        profiles = new int[]{CamcorderProfile.QUALITY_HIGH, CamcorderProfile.QUALITY_2160P, CamcorderProfile.QUALITY_1080P, CamcorderProfile.QUALITY_720P, CamcorderProfile.QUALITY_480P, CamcorderProfile.QUALITY_CIF, CamcorderProfile.QUALITY_QCIF, CamcorderProfile.QUALITY_LOW};
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        profiles = new int[]{CamcorderProfile.QUALITY_HIGH, CamcorderProfile.QUALITY_1080P, CamcorderProfile.QUALITY_720P, CamcorderProfile.QUALITY_480P, CamcorderProfile.QUALITY_CIF, CamcorderProfile.QUALITY_QCIF, CamcorderProfile.QUALITY_LOW};
    } else {
        profiles = new int[]{CamcorderProfile.QUALITY_HIGH, CamcorderProfile.QUALITY_LOW};
    }
    for (final …
Run Code Online (Sandbox Code Playgroud)

android android-camera android-mediacodec

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

使用 MediaCodec 和 MediaMuxer 将位图编码为电影,每个图像的自定义呈现时间

我正在尝试从一系列位图创建电影。我想以 API 19 为目标,但也可以利用 API 21(如果它在设备上可用)。

我一直在阅读 bigflake CTS 测试,尤其是这里的EncodeAndMux 和 EncodeDecodeTest

我想使用 MediaCodec 和 MediaMuxer 类,而不是 FFMpeg 或 Jcodec 等。

如果您能指出我哪里出错以及如何解决,我将不胜感激。我是 Android 新手,为此苦苦挣扎了好几天!我正在三星 Galaxy Note 3 上进行测试

更新:我能够访问 EOS,但在尝试释放编码器时出现编解码器错误。

这是更新后的代码:

public void createMovie(View view) {

        Log.v(TAG,"CREATING MOVIE");


        //1. Prepare the encoder and the GPUImageView
        try {
            prepareEncoder();
            presentationTime = 0;
            int j = 0;
            for (int i = firstImageIndex; i <= lastImageIndex; i++) {

                Log.v(TAG, "inLoop: " + i);


                //1

                durationInNanosec = (long) ((float) durations.get(j) * 100000); …
Run Code Online (Sandbox Code Playgroud)

android mediamuxer android-mediacodec

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

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 音频在某些带有 MediaCodec 和 AudioTrack 的设备上过快

我使用的解码音频MediaExtractorMediaCodecAudioTrack。我配置AudioTrack使用MediaFormat由归国MediaCodec.getOutputFormat()接收后MediaCodec.INFO_OUTPUT_FORMAT_CHANGEDMediaCodec。在某些设备上,这会导致音频加速,而MediaFormat返回的则MediaExtractor正常工作。(在其他设备上,情况正好相反。)

以下是一些细节:

  • 有问题的音频文件主要是 22050 Hz 单声道 MP3。
  • 播放速度过快的设备包括 Prestigio PMP3007C3G、ASUS MeMO Pad HD 7 (ME173X)、Lenovo A5500-H (A5500-H) 和一些 Wiko 设备。
  • 不幸的是,我不知道返回的参数MediaFormat,因为我无法访问这些设备,但我假设它返回单声道的立体声,或 22050 Hz 的 44100 Hz,而不实际重新采样文件。

任何帮助,将不胜感激。谢谢!

audio mp3 android audiotrack android-mediacodec

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

如何使用 MediaMuxer 混合两个音频样本并编码回音频文件

我目前有两个单独的媒体提取器和编解码器,用于将每个单独的样本分解为ByteBuffers。然后我将每个样本存储到两个short数组中。然后我调用我的混合函数,它将两个样本合并为一个short[],如果我short[]AudioTrack它来播放,结果会很好,两种声音都可以根据需要同时播放。

但是,我真正想做的是使用MediaMuxer将我的新short[]文件转换回 mp4 音频文件并将其存储到设备以供以后播放。有人可以帮我弄清楚我做错了什么吗?

这是我拥有的一些代码......正如你所看到的,我注释掉了AudioTrack,这就是我试图将short[]背面变成 的地方,ByteBuffer所以我可以使用媒体复用器来创建音频文件。这给我的结果是一个新的音频文件,它是存储在我设备上的正确名称和总长度……但是当我尝试播放它时……它在几分之一秒内从头跳到尾,实际上并没有播放和音频。

        songOutPath = Environment.getExternalStorageDirectory()+"/My Folder/song.raw";
        muxer = new MediaMuxer(songOutPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        mTrackIndex = muxer.addTrack(format);
        muxer.start();
        mMuxerStarted = true;

        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        final long timeoutUs = 5000;
        boolean sawInputEOS = false;
        boolean sawOutputEOS = false;
        int noOutputCounter = 0;

        MediaCodec.BufferInfo info2 = new MediaCodec.BufferInfo();
        final long timeoutUs2 = 5000;
        boolean sawInputEOS2 = false;
        boolean sawOutputEOS2 …
Run Code Online (Sandbox Code Playgroud)

mp4 android mediamuxer android-mediacodec

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

如何从MediaCodec的解码输出中获取YUV并绘制在GLSurfaceView上?

我需要使用 GLSurfaceView 播放视频流。我试图获取输出并渲染它们。但是颜色不对。

我将输出缓冲区转储到文件并用 yuv 查看器打开它,颜色也不正确。所以我怀疑我使用错误的方式来获取输出缓冲区?这是代码:

mediaCodec = MediaCodec.createDecoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 500000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, 0);
mediaCodec.start();

ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();

int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0) {
   ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
   inputBuffer.clear();
   inputBuffer.put(avFrame.frmData);
   mediaCodec.queueInputBuffer(inputBufferIndex, 0, avFrame.frmData.length, 0L, 0);
  }

MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
byte[] outData = new byte[bufferInfo.size];
while (outputBufferIndex >= 0) {
    ByteBuffer outputBuffer = …
Run Code Online (Sandbox Code Playgroud)

android yuv glsurfaceview android-mediacodec

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

MediaMuxer writeSampleData 错误

我使用 MediaMuxer 混合音频和无线电数据,数据来自两个编码器,流程正确,我得到输出并播放。但是 MediaMuxer 在 writeSampleData 时可能会因为错误而失败:

 E/MPEG4Writer: timestampUs 21932611 < lastTimestampUs 22055361 for Video track
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime: FATAL EXCEPTION: MediaMuxer
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime: Process: org.cocos2dx.simplegame, PID: 20089
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime: java.lang.IllegalStateException: writeSampleData returned an error
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at android.media.MediaMuxer.nativeWriteSampleData(Native Method)
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at android.media.MediaMuxer.writeSampleData(MediaMuxer.java:334)
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at com.duapps.durecorder.muxer.DuMediaMuxer.handleMessage(DuMediaMuxer.java:53)
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:102)
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:136)
10-14 14:23:41.580 20089-20230/org.cocos2dx.simplegame E/AndroidRuntime:     at android.os.HandlerThread.run(HandlerThread.java:61)
Run Code Online (Sandbox Code Playgroud)

我看到MPEG4Writer,错误的根本原因是视频的时间戳,它让MediaMuxer运行到IllegalState。经过大量测试后,我知道视频和音频时间戳都可能出现错误,并且当我更改音频采样率时,重复率会发生变化。

当我只录制音频或广播时,错误不会再次发生。

有人可以给我一些建议吗?

audio android mediamuxer android-mediacodec

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