标签: mediacodec

将图像转换为视频

如何在使用FFmpegJCodec的情况下将图像转换为视频,仅使用android MediaCodec.视频图像是位图文件,可以是ARGB888或YUV420(我的选择).最重要的是视频必须可以在Android设备上播放,最大API是16.我知道API 18 MediaMuxer,我不能使用它.

请帮助我,我坚持了很多天.(JCodec要慢,FFmpeg使用起来很复杂).

video android h.264 android-mediaplayer mediacodec

4
推荐指数
2
解决办法
6415
查看次数

使用MediaMuxer创建的不可流式处理的视频文件

MediaCodec用来编码视频.帧通过相机预览回调到MediaCodec实例(没有使用Surface).我正在使用JCodec库进行多路复用,并且我能够流式传输视频(视频播放器显示正确的持续时间,我可以使用搜索栏更改视频位置).

今天我尝试使用MediaMuxer而不是JCodec和我有视频仍然看起来很好,但持续时间绝对不正确(几小时而不是一分钟)和搜索栏根本不工作.

mediaMuxer = new MediaMuxer("/path/to/video.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
Run Code Online (Sandbox Code Playgroud)

我收到以下代码时会被懒惰地调用MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:

videoTrackIndex = mediaMuxer.addTrack(encoder.getMediaFormat());
mediaMuxer.start();
Run Code Online (Sandbox Code Playgroud)

我用以下代码编码帧:

mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo);
Run Code Online (Sandbox Code Playgroud)

byteBuffer并且在一些定位之后bufferInfo直接来自MediaCodec:

byteBuffer.position(bufferInfo.offset);
byteBuffer.limit(bufferInfo.offset + bufferInfo.size);
Run Code Online (Sandbox Code Playgroud)

演示时间设置正确:

mMediaCodec.queueInputBuffer(inputBufferIndex, 0, getWidth() * getHeight() * 1.5, System.nanoTime() / 1000, 0);
Run Code Online (Sandbox Code Playgroud)

在记录的最后我做:

mediaMuxer.stop();
mediaMuxer.release();
Run Code Online (Sandbox Code Playgroud)

日志:

I/MPEG4Writer? setStartTimestampUs: 0
I/MPEG4Writer? Earliest track starting time: 0
D/MPEG4Writer? Stopping Video track
I/MPEG4Writer? Received total/0-length (770/0) buffers and encoded 770 frames. - video
D/MPEG4Writer? Stopping …
Run Code Online (Sandbox Code Playgroud)

android mediacodec mediamuxer

4
推荐指数
1
解决办法
3208
查看次数

如何播放MediaCodec编码器生成的原始h264?

当谈到MediaCodec(以及一般的视频编码/解码)时,我有点新意,所以如果我在这里说的任何错误,请纠正我.

我想用VLC/ffplay播放MediaCodec的原始h264输出.我需要这个才能发挥,因为我的最终目标是将一些实时视频流传输到计算机,而MediaMuxer只在磁盘上生成一个文件,而不是我可以以非常低的延迟流式传输到桌面.(我对其他解决方案持开放态度,但我还没有发现任何符合延迟要求的其他解决方案)

这是我正在使用的代码对视频进行编码并将其写入文件:(它基于此处找到的MediaCodec示例,仅删除了MediaMuxer部分)

package com.jackos2500.droidtop;

import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.opengl.EGL14;
import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
import android.opengl.EGLExt;
import android.opengl.EGLSurface;
import android.opengl.GLES20;
import android.os.Environment;
import android.util.Log;
import android.view.Surface;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class StreamH264 {
    private static final String TAG = "StreamH264";
    private static final boolean VERBOSE = true;           // lots of logging

    // where to put the output file (note: /sdcard requires WRITE_EXTERNAL_STORAGE permission)
    private static final …
Run Code Online (Sandbox Code Playgroud)

android ffmpeg mediacodec

4
推荐指数
1
解决办法
5137
查看次数

控制VirtualDisplay的帧速率

我正在编写一个Android应用程序,在其中,我有一个VirtualDisplay镜像屏幕上的内容,然后我将帧从屏幕发送到一个实例MediaCodec.它有效,但是,我想添加一种指定编码视频的FPS的方法,但我不确定如何这样做.

根据我的阅读和实验,丢弃编码的帧(基于演示时间)不能很好地工作,因为它最终会产生块状/伪影的视频,而不是低帧率的平滑视频.其他阅读表明,做我想要的唯一方法(限制FPS)将限制传入的FPS到MediaCodec,但是VirtualDisplay刚收到一个SurfaceMediaCodec下面构造的

mSurface = <instance of MediaCodec>.createInputSurface();
mVirtualDisplay = mMediaProjection.createVirtualDisplay(
    "MyDisplay",
    screenWidth,
    screenHeight,
    screenDensity,
    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
    mSurface,
    null,
    null);
Run Code Online (Sandbox Code Playgroud)

我也试过子类Surface和限制被馈送到帧MediaCodec通过unlockCanvasAndPost(Canvas canvas),但该功能似乎从来没有对我的情况下被调用,因此,有可能是我如何延长一些古怪Surface以及与互动ParcelwriteToParcel功能称为上我的实例,但这是在我的实例中调用的唯一函数(我可以告诉).

其他阅读建议我可以从编码器 - >解码器 - >编码器,并限制第二个编码器馈送帧的速率,但这是很多额外的计算,如果我可以避免它,我宁愿不做.

有没有人成功限制VirtualDisplay饲喂它的速度Surface?任何帮助将不胜感激!

android mediacodec

4
推荐指数
1
解决办法
2879
查看次数

使用MediaCodec和Surface进行Android编码

我一直在通过MediaCodec将视频直接渲染到我的UI中从SurfaceView获取的Surface.这非常有效.

我现在正在尝试使用MediaCodec作为编码器.作为测试,我想渲染到Surface(如上所述)并通过配置为编码器的MediaCodec的不同实例进行环回.

我看到编码器的createInputSurface()方法.我想我希望编码器创建这个表面然后让解码器MediaCodec使用它作为要绘制的表面.首先,这可能吗?

其次,我不确定如何从编码器创建的Surface创建SurfaceView.我只从SurfaceView中提取了一个Surface,而我从文档中看不到如何反向执行此操作.

android encoder decoder surfaceview mediacodec

4
推荐指数
1
解决办法
4832
查看次数

Android MediaExtractor readSampleData IllegalArgumentException

我尝试按照这个问题使用android的MediaMuxer连接多个mp4音频文件并连接视频文件.

但由于某种原因,当我调用readSampleData时,MediaExtractor会抛出IllegalArgumentException

在官方API中,此函数不应该抛出任何异常!这是怎么回事 ?

我发现了一个旧问题,表明ByteBuffer的大小可能是负责的:Android MediaMuxer readSampleData IllegalStateException

我已经尝试了大量的大小值,但没有一个让问题消失.我应该知道标准尺寸吗?

任何提示都可以提供帮助!

    boolean VERBOSE = true;


private boolean concatenateFiles(File dst, List<File> sources) {
    if ((sources == null) || (sources.size() == 0)) {
        return false;
    }

    boolean result;
    MediaExtractor extractor = null;
    MediaMuxer muxer = null;
    try {
        // Set up MediaMuxer for the destination.
        muxer = new MediaMuxer(dst.getPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

        // Copy the samples from MediaExtractor to MediaMuxer.
        boolean sawEOS = false;

        int frameCount = 0;
        int offset = 100; …
Run Code Online (Sandbox Code Playgroud)

android mediacodec mediaextractor mediamuxer

4
推荐指数
1
解决办法
3949
查看次数

如何检测android设备中的芯片组?

我需要检测android设备的芯片组.所以我可以在MediaTek芯片组上禁用某些功能.(此问题中讨论的1080p编码MediaCodec编码视频底部有绿色条,色度搞定了)

我已经看了http://developer.android.com/reference/android/os/Build.html,但似乎没什么关系.

encoding android opengl-es mediacodec

4
推荐指数
2
解决办法
2912
查看次数

如何知道Android解码器MediaCodec.createDecoderByType(type)是硬件还是软件解码器?

有没有办法找出使用MediaCodec.createDecoderByType(type)接收的解码器是硬件解码器还是软件解码器?

android hardware-acceleration android-mediaplayer mediacodec

4
推荐指数
1
解决办法
2493
查看次数

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

使用带有MediaCodec的getInputImage进行编码

背景:我做视频文件解复用,解码视频轨道,对接收到的帧应用一些更改,再次解码和复用它们.

在Android中执行此操作的已知问题是供应商指定编码器/解码器颜色格式的数量.Android 4.3引入了表面以使设备独立,但我发现很难使用它们,因为我的帧更改例程需要Canvas写入.

自Android 5.0以来,使用灵活的YUV420颜色格式很有前途.与用于解码的getOutputImage和用于编码的getInputImage一起,Image对象可以用作从解码MediaCodec检索的格式.我使用getOutputImage进行解码工作,并可以在RGB转换后可视化结果.为了编码YUV图像并将其排队到MediaCodec(编码器),似乎缺少链接:

从MediaCodec中取出输入缓冲区后

int inputBufferId = encoder.dequeueInputBuffer (5000);
Run Code Online (Sandbox Code Playgroud)

我可以访问返回的正确图像

encoder.getInputImage (inputBufferId);
Run Code Online (Sandbox Code Playgroud)

我填写图像缓冲区 - 这也工作,但我没有看到一种方法将输入缓冲区排队回编解码器进行编码...只有一个

encoder.queueInputBuffer (inputBufferId, position, size, presentationUs, 0);
Run Code Online (Sandbox Code Playgroud)

方法可用,但没有任何匹配图像.可以使用检索呼叫所需的大小

ByteBuffer  byteBuffer = encoder.getInputBuffer (inputBufferId);
Run Code Online (Sandbox Code Playgroud)

byteBuffer.remaining ();
Run Code Online (Sandbox Code Playgroud)

但是除了getInputImage()之外,这似乎会在调用时搞砸编码器.

另一个缺少的文档或者我错了什么?

encoding android mediacodec

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