2013-06-20 68 views
2

我正在为Android进行视频压缩项目,我正在考虑通过设计新的视频编解码器(从头开始,我设计了该算法)来实现它。我已经阅读了视频压缩的基础知识,相关的相关算法和编解码器基础知识。我也发现,在Android上,FFmpeg可能是一个很好的解决方案。使用FFmpeg为Android编写自定义编解码器

现在我的问题来了:

  1. 如何一个视频编解码器,如FFmpeg的?我在编写编解码器时仍然是初学者,但是 我该如何启动?我有一个大概的想法,那就是你必须首先编写至少一个分路器,然后编写特定的编码器和解码器等。 (请求引用在这里吧。)

  2. 由于我的编解码器deosn't简单地调整像帧,分辨率,码率等 正在读MediaCodec API和MediaPlayer的API在官方Android SDK足够的视频性能编写新的编解码器? (因为上次我看到它只支持MPEG-4 SP,H.263和H.264,我无法找到是否可以直接编写自己的类和函数)。

谢谢。

+0

是不是有人在那里?请帮忙 。该项目的截止日期是关闭。 –

回答

2

您可以在Android上使用ffmpeg作为工具或ffmpeg库集(libavcodec,libaviformat,...)。您可以跨平台的方式添加或更改ffmpeg编解码器,因为此项目非常重视平台独立性。您可以改用MediaCodec API。 但是没有办法扩展MediaCodec API更新有可能扩展MediaCodec,它记录在http://source.android.com/devices/media.html#codecs)并且没有简单的方法让ffmpeg使用这个API。

+0

感谢您的答复。我最感到困扰的是我不知道如何使用PROGRAM编解码器。用谷歌搜索ffmpeg文档确实给了我一些结果,但它们作为多媒体编程的新手并不可读。任何关于ffmpeg的参考或如何从头开始编写编解码器?再次感谢 。 –

+0

ffmpeg的架构在官方网站上有相当丰富的文档,但我宁愿建议您以现有的编解码器为基础,并逐渐将其改为执行您的任何打算。 –

+0

是的,感谢您的更新。但我想你提到的链接确实是一个硬件编解码器,需要修改固件,这是目前无法完成的工作(我正在尝试编写一个软件编解码器)。我有一个想法,虽然...是否有可能通过添加编解码器到mplayer实现编解码器?有一些链接可以将定制编解码器添加到mplayer中,但我不知道该怎么做;(。请帮忙,再次感谢。 –

2

如果你是一个新手,并且“只想在SW中做”,而不是在SW中做。我假设您的算法不需要实时,并且可以动态压缩视频数据,或者您需要使用硬件编解码器。

这是Android MediaCodec Reference

MediaCodec codec = MediaCodec.createDecoderByType(type); 
codec.configure(format, ...); 
codec.start(); 
ByteBuffer[] inputBuffers = codec.getInputBuffers(); 
ByteBuffer[] outputBuffers = codec.getOutputBuffers(); 
for (;;) { 
    int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs); 
    if (inputBufferIndex >= 0) { 
    // fill inputBuffers[inputBufferIndex] with valid data 
    ... 
    codec.queueInputBuffer(inputBufferIndex, ...); 
    } 

    int outputBufferIndex = codec.dequeueOutputBuffer(timeoutUs); 
    if (outputBufferIndex >= 0) { 
    // outputBuffer is ready to be processed or rendered. 
    ... 
    codec.releaseOutputBuffer(outputBufferIndex, ...); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 
    outputBuffers = codec.getOutputBuffers(); 
    } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 
    // Subsequent data will conform to new format. 
    MediaFormat format = codec.getOutputFormat(); 
    ... 
    } 
} 
codec.stop(); 
codec.release(); 
codec = null; 

上写着“// OutputBuffer中已准备好被处理或呈现”应用你的解码器就行了。

这是你的第一帧将outputBuffers [0]输出到outputBuffers [outputBufferIndex]。保存outputBufferIndex,即outputBufferIndex_old = outputBufferIndex;那么你的下一帧将是outputbuffers [outputBufferIndex_old]到outputbuffers [outputBufferIndex]。但是,这是一个循环缓冲区,所以在for循环... AHHHHH

是这样的:

//init 
int old = 0; 
int len = codec.BufferInfo().size,buff_len=outputBuffers.size; 
Byte[] processBuffer = new Byte[len]; 

... // outputBuffer ready 
for (int i=old; i<old+len; i++){ 
    processBuffer[i-old] = outputBuffers[i%buff_len]; 
} 
old = outputBufferIndex; 

Here就是一个很好的例子。您可能需要查看MediaMetadataRetriever以获取有关输入视频的信息。高度和宽度等。如果您希望您的编码器对不同类型的视频具有较强的鲁棒性,则每像素字节数。无论如何,这应该让你开始。

我强烈建议使用Matlab(或GNU Octave)进行视频编解码器的原型设计。它会为你节省很多时间。这意味着在尝试在几乎不可能的系统上实现它以像Android一样进行调试之前,应确保您的预期编解码器算法有效。

希望这会有所帮助。

0

如果有人碰到这个老问题绊倒的答案是:

  1. 编写程序。
  2. 你想要“编解码器”只需添加一个'空编解码器'(复制输入到输出)。
  3. 测试您的程序仍然有效,并且您可以阅读(所谓的)编码文件。
  4. 添加Codec'null Codec'的编解码器(调用函数以避免对工作文件进行大量编辑)。
  5. 重新测试您的程序以确保它仍然正常工作并读取输出以确保其正确。

就是这样。 ;)

需要考虑的事情:

  • “视频播放器”可以丢弃帧,一个“录像机”最好不要 丢帧。
  • “软件编解码器”(无硬件辅助)将变慢, 在不同的Core上运行它(如果可用)。
  • 除非您仅制作 演示版,否则将需要硬件编解码器(由软件调用)。
  • 将您的程序拆分为可以单独运行的程序段,以便可以进行线程化,并且可以将这些线程分配给不同的内核。您需要检测内核数量并评估其速度,以便您可以在运行时动态地进行一些分区。
  • 使用NDK和汇编语言编程将有必要获得足够的速度来以所需帧速率压缩体面大小的视频(IE:您不希望您的完成的程序仅支持320x176 @ 5 FPS视频)。压缩机必须运行得比输入到达要快。
  • 设计自己的编解码器击败现有的编解码器(x265)将需要您几年(没有帮助)。
  • 如果您是Java,C和ARM Assembly(以及软件工程师)的Wiz,则需要花费几个月的时间;所以提交或退出。尝试找到一些开放源代码作为开始的基础。