标签: mediacodec

MediaCodec.dequeInputBuffer/dequeOutputBuffer中的IllegalStateException

我正在尝试将PNG文件转换为单片视频片段,以便在项目中启动.

我有什么代码来实现它是: -

private boolean MediaConversion()
    {
        MediaCodec codec = MediaCodec.createEncoderByType(MIMETYPE);
        MediaFormat mediaFormat = null;
        if(CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)){
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 1280 , 720);
        } else {
            mediaFormat = MediaFormat.createVideoFormat(MIMETYPE, 720, 480);
        }

        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 700000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
        codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

        codec.start();

        ByteBuffer[] inputBuffers = codec.getInputBuffers();
        ByteBuffer[] outputBuffers = codec.getOutputBuffers();
        boolean sawInputEOS = false;
        int inputBufferIndex= -1, outputBufferIndex= -1;
        BufferInfo info=null;        

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Bitmap bitmap = null;
        try {
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.image);                    
            Log.e("Uploaded", "Bitmap:" …
Run Code Online (Sandbox Code Playgroud)

android mediacodec

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

Android MediaCodec:减少mp4视频大小

我正在寻找一种"压缩"mp4视频的方法.为此,我想降低视频的分辨率和/或降低FPS.

经过长时间的研究,我认为这样做的方法是使用MediaCodec和相关的API,如下所示:

- > MediaExtractor从mp4文件中提取编码的媒体数据. - > MediaCodec(解码器):解码每个帧以供以后处理. - > MediaCodec(编码器):此时,我猜我们应该在哪里建立MediaFormat参数,例如视频分辨率,这应该有助于我们减少mp4文件的最终大小. - > MediaMuxer用于生成mp4文件(MinSDK 18,这可能是一个问题,但现在......好吧).

我不想使用SurfaceView/TextureView.关于音频,我不想处理它以降低质量.

我一直在看这里的所有例子:http: //bigflake.com/mediacodec/

我也看过CTS源代码模块.

我一直在研究以下几个项目:https: //github.com/vecio/MediaCodecDemo/blob/master/src/io/vec/demo/mediacodec/DecodeActivity.java

当然,我已经在stackoverflow上阅读了几十篇帖子.

问题是我还没有找到任何适合这个porpuse的代码示例.我尝试将各种代码片段放在一起放在一个项目中,但实际上并没有用.

谢谢.

video mp4 android resolution mediacodec

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

MediaMuxer错误"无法停止复用器"

Camera使用MediaCodecmime-type"video/avc" 编码预览数据,并将编码数据(仅限视频,无音频)传递给MediaMuxer.复用器似乎运行正常并创建一个合理大小的输出文件(即,我记录的时间越长,越大).但是,当我尝试停止复用器时,我得到"无法停止复用器"错误:

10-21 10:39:40.755: E/AndroidRuntime(2166): Caused by: java.lang.IllegalStateException: Failed to stop the muxer
Run Code Online (Sandbox Code Playgroud)

在失败的停止之前有一些可疑的MPEG4Writer日志消息:

10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping Video track
10-21 10:39:40.740: E/MPEG4Writer(2166): Missing codec specific data
10-21 10:39:40.740: W/MPEG4Writer(2166): 0-duration samples found: 122
10-21 10:39:40.740: I/MPEG4Writer(2166): Received total/0-length (123/1) buffers and encoded 123 frames. - video
10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping Video track source
10-21 10:39:40.740: D/MPEG4Writer(2166): Video track stopped
10-21 10:39:40.740: D/MPEG4Writer(2166): Stopping writer thread
10-21 10:39:40.740: D/MPEG4Writer(2166): 0 chunks are written in …
Run Code Online (Sandbox Code Playgroud)

mp4 android muxer mediacodec

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

MediaCodec H264编码器无法在Snapdragon 800设备上运行

我使用Android的MediaCodec API编写了H264流编码器.我在大约十个不同处理器的不同设备上进行了测试,除了Snapdragon 800驱动的设备(谷歌Nexus 5和索尼Xperia Z1)之外,它在所有设备上都有效.在这些设备上,我得到了SPS和PPS以及第一个Keyframe,但之后mEncoder.dequeueOutputBuffer(mBufferInfo,0)只返回MediaCodec.INFO_TRY_AGAIN_LATER.我已经尝试过不同的超时,比特率,分辨率和其他配置选项,但无济于事.结果总是一样的.

我使用以下代码初始化编码器:

        mBufferInfo = new MediaCodec.BufferInfo();
        encoder = MediaCodec.createEncoderByType("video/avc");
        MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 480);
        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 768000);
        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mEncoderColorFormat);
        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
        encoder.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
Run Code Online (Sandbox Code Playgroud)

所选颜色格式为:

MediaCodecInfo.CodecCapabilities capabilities = mCodecInfo.getCapabilitiesForType(MIME_TYPE);
            for (int i = 0; i < capabilities.colorFormats.length && selectedColorFormat == 0; i++)
            {
                int format = capabilities.colorFormats[i];
                switch (format) {
                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedPlanar:
                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
                    case MediaCodecInfo.CodecCapabilities.COLOR_TI_FormatYUV420PackedSemiPlanar:
                    case MediaCodecInfo.CodecCapabilities.COLOR_QCOM_FormatYUV420SemiPlanar:
                        selectedColorFormat = format;
                        break;
                    default:
                        LogHandler.e(LOG_TAG, "Unsupported color format " + …
Run Code Online (Sandbox Code Playgroud)

java android encoder h.264 mediacodec

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

调整android中视频显示中宽高比变化的表面视图大小

我正在开展视频会议项目.我的视频显示使用表面视图.现在,在视频通话期间,传入帧的宽高比可能会发生变化.所以我尝试了以下代码

public void surfaceResize() {

   // WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Point size = new Point();
    int screenWidth = 0;
    //Get the SurfaceView layout parameters

    float aspectRatio = (float) recv_frame_width / recv_frame_height;

    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) 
    {   
        //Get the width of the screen
        getWindowManager().getDefaultDisplay().getSize(size);
        screenWidth = size.x;

        //Set the width of the SurfaceView to the width of the screen
        surflp.width = screenWidth;

        //Set the height of the SurfaceView to match the aspect ratio of the video 
        //be sure to cast these …
Run Code Online (Sandbox Code Playgroud)

video android surfaceview mediacodec

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

在Android中,如何将预定义的Surface传递给MediaCodec进行编码?

我有一个管理自己的GLSurfaceView的应用程序,现在我想使用Android 4.3的新MediaCodec功能,将Surface作为输入.

在我看过的所有示例中,使用MediaCodec.createInputSurface()创建Surface,然后为此Surface创建GL上下文.对于已经稳定的代码库进行改造,这感觉很单一,并且令人难以置信地具有破坏性.

是否可以使用MediaCodec.configure(format,a_predefined_Surface,null,MediaCodec.CONFIGURE_FLAG_ENCODE)?这允许我以即插即用的方式使用MediaCodec.MediaCodec.configure()采用Surface参数的事实表明这应该是可能的.但是,API指出"指定一个表面,在该表面上呈现此解码器的输出" http://developer.android.com/reference/android/media/MediaCodec.html#configure(android.media.MediaFormat,android). view.Surface,android.media.MediaCrypto,int)这是否意味着这仅用于解码而不是编码?如果是这样,有没有办法让MediaCodec使用预定义的Surface进行编码?

我传入的Surface已经创建,EGL_RECORDABLE_ANDROID设置为true,并且验证返回的GL上下文包含所需的EGL_RECORDABLE_ANDROID属性.尽管如此,MediaCodec.configure()失败并出现无用的异常'native_window_api_connect返回错误:无效的参数(-22)':

I/ACodec(32383):  Now uninitialized
I/OMXClient(32383): Using client-side OMX mux.
I/ACodec(32383): [OMX.qcom.video.encoder.avc] Now Loaded
E/MediaCodec(32383): native_window_api_connect returned an error: Invalid argument (-22)
W/System.err(32383): java.lang.IllegalStateException
W/System.err(32383):    at android.media.MediaCodec.native_configure(Native Method)
W/System.err(32383):    at android.media.MediaCodec.configure(MediaCodec.java:259)
[...]
W/System.err(32383):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
W/System.err(32383):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
Run Code Online (Sandbox Code Playgroud)

这是来自Android 4.3的三星Galaxy S4.

android mediacodec

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

无法兼容音频和视频

我正在编写一个使用MediaCodec记录屏幕捕获和音频的应用程序.我使用MediaMuxer来混合视频和音频来创建mp4文件.我成功地分别编写了视频和音频,但是当我尝试将它们混合在一起时,结果出乎意料.音频播放时没有视频,或视频播放后立即播放.我的猜测是我在时间戳上做错了,但我无法弄清楚到底是什么.我已经看过这些例子:https://github.com/OnlyInAmerica/HWEncoderExperiments/tree/audiotest/HWEncoderExperiments/src/main/java/net/openwatch/hwencoderexperiments和bigflake.com上的那些并且无法找到回答.

这是我的媒体格式配置:

    mVideoFormat = createMediaFormat();

    private static MediaFormat createVideoFormat() {
    MediaFormat format = MediaFormat.createVideoFormat(
            Preferences.MIME_TYPE, mScreenWidth, mScreenHeight);
    format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
            MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
    format.setInteger(MediaFormat.KEY_BIT_RATE, Preferences.BIT_RATE);
    format.setInteger(MediaFormat.KEY_FRAME_RATE, Preferences.FRAME_RATE);
    format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
            Preferences.IFRAME_INTERVAL);
    return format;
}
    mAudioFormat = createAudioFormat();

    private static MediaFormat createAudioFormat() {
    MediaFormat format = new MediaFormat();
    format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
    format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    format.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
    return format;
}
Run Code Online (Sandbox Code Playgroud)

音频和视频编码器,复用器:

      mVideoEncoder = MediaCodec.createEncoderByType(Preferences.MIME_TYPE);
    mVideoEncoder.configure(mVideoFormat, null, null,
            MediaCodec.CONFIGURE_FLAG_ENCODE);
    mInputSurface = new InputSurface(mVideoEncoder.createInputSurface(),
            mSavedEglContext);
    mVideoEncoder.start();
    if (recordAudio){
        audioBufferSize = AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, 
        AudioFormat.ENCODING_PCM_16BIT);
        mAudioRecorder …
Run Code Online (Sandbox Code Playgroud)

audio video android h.264 mediacodec

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

Android - 在MediaRecorder,MediaCodec和Ffmpeg之间进行选择

我正在为Android开发视频录制和共享应用程序.该应用程序的规格如下: -

  • 从应用程序内部录制10秒(最大)视频(不使用设备的相机应用程序)
  • 没有进一步编辑视频
  • 将视频存储在Firebase云存储(GCS)存储桶中
  • 其他用户下载和播放所述视频

从研究中我做了SO和其他人的来源,我发现了以下内容(如果我错了请纠正我): -

这三个选项及其各自的特点是: -

1. Ffmpeg

  • 无论如何能够实现上述目标,并在SO等网站上有广泛的答案和解释
  • APK大小增加20-30mb(大型图书馆)
  • 在某些64位设备上运行不正常的风险

2. MediaRecorder

  • 大多数设备可靠且支持
  • 将以.mp4格式存储文件(除非转换为h264)
  • 更易于播放(无需解码)
  • 添加mp4和3gp标头
  • 根据此问题增加延迟

3. MediaCodec

  • 低级
  • 将需要MediaCodec,MediaMuxer和MediaExtractor
  • 以h264输出(不使用MediaMuxer进行播放)
  • 适合视频操作(但在我的用例中不需要)
  • 4.3之前的(API 18)设备不支持
  • 更难以实现和编码(我的意见 - 如果我错了,请纠正我)
  • 没有广泛的信息,教程,答案或样本(Bigflake.com是唯一的例外)

花了好几天后,我仍然无法弄清楚哪种方法适合我的特定用例.请详细说明我应该为我的申请做些什么.如果有一种完全不同的方法,那么我也对此持开放态度.

我最大的标准是视频编码过程尽可能高效,并且要存储在云中的视频应该具有尽可能低的空间使用率,而不会影响视频质量.

另外,如果您可以建议在Firebase存储中保存和分发视频的相应格式,我将不胜感激,并指出我建议方法的教程或示例.

先感谢您!很抱歉长时间阅读.

video android ffmpeg mediarecorder mediacodec

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

我想将Pre-Rolls附加到Android设备上拍摄的视频

我正在使用mp4parser,视频需要是同一种类.我正在考虑使用Android的媒体编解码器来解码和编码预卷视频,以适应相机的相同编码输出(正面和背面)任何关于如何做到这一点的建议(如何获得特定的设备编码参数)?

video android mp4parser mediacodec

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

Android MediaCodec不解码所有输入缓冲区

在Android 4.4.2中,我MediaCodec用来解码mp3文件.我正在使用queueInputBuffer()输入mp3编码帧排队并dequeueOutputBuffer()获得解码帧.但是解码器从第8帧开始提供解码输出(基于bufferInfo.presentationTimeUs)并跳过最初的7帧.此方案仅针对少数流而不针对所有流发生.此外,这种行为在许多运行中都是一致的.

我想要所有帧的解码输出,我不希望任何帧被跳过.任何人都可以帮助我理解为什么帧被跳过?我保证流不会被破坏.因为我要INFO_TRY_AGAIN到第7帧,当`dequeueOutputBuffer'返回有效的缓冲区索引时,它的呈现时间总是第8帧.

以下是排队代码:

Log.e(TAG, "audptOffset = "+audptOffset+"input PT = "+audpt);
                audcodec.queueInputBuffer(audInbufIndex, 0, audchunkSize, audpt, 0);
Run Code Online (Sandbox Code Playgroud)

以下是我如何调用dequeue并写入AudioTrack:

if(!audoutputDone ){
                if(!waitForAudioRelease){
                    auoutBufIndex  = audcodec.dequeueOutputBuffer(auinfo, 100);
                    Log.e(TAG, "Output PT = " + auinfo.presentationTimeUs+"auoutBufIndex = "+auoutBufIndex);
                }
                if (auoutBufIndex >= 0) {
                    waitForAudioRelease = true;
                } else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    auddecOutBufArray = audcodec.getOutputBuffers();
                } else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat newFormat = audcodec.getOutputFormat();
                    int sampleRate1 = newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
                    int …
Run Code Online (Sandbox Code Playgroud)

android audiotrack mediacodec

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