haoge921026 发表于 2015-10-10 11:41:54

关于H.264硬编码&硬解码

现在看到了你们H.264硬编码&硬解码 http://www.t-firefly.com/zh/firenow/firefly_rk3288/case/2015/0529/3.html 的实现过程,本人也很想学习硬解码这方面,请问各位有没有谁有 编码: Camcodec.apk      解码: RTPclinet.apk 的源码?如果没有的话,有没有相关可以实现的帖子,本人正在学习在3288上构建硬解码这一块!

zhansb 发表于 2015-10-10 11:51:58

可以直接找Android的mediacodec的资料

haoge921026 发表于 2015-10-10 15:06:20

zhansb 发表于 2015-10-10 11:51
可以直接找Android的mediacodec的资料

好的!:)

haoge921026 发表于 2015-10-12 14:04:38

zhansb 发表于 2015-10-10 11:51
可以直接找Android的mediacodec的资料

private final String TAG = "MediaCodeSample";
    /** 用来解码 */
    private MediaCodec mMediaCodec;
    /** 用来读取音频文件 */
    private MediaExtractor extractor;
    private MediaFormat format;
    private String mime = null;
    private int sampleRate = 0, channels = 0, bitrate = 0;
    private long presentationTimeUs = 0, duration = 0;
    public void decode(String url)
    {

      extractor = new MediaExtractor();
      // 根据路径获取源文件
      try
      {
            extractor.setDataSource(url);
      } catch (Exception e)
      {
            Log.e(TAG, " 设置文件路径错误" + e.getMessage());
      }
      try
      {
            // 音频文件信息
            format = extractor.getTrackFormat(0);
            mime = format.getString(MediaFormat.KEY_MIME);
            sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
            // 声道个数:单声道或双声道
            channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
            // if duration is 0, we are probably playing a live stream
            duration = format.getLong(MediaFormat.KEY_DURATION);
            // System.out.println("歌曲总时间秒:"+duration/1000000);
            bitrate = format.getInteger(MediaFormat.KEY_BIT_RATE);
      } catch (Exception e)
      {
            Log.e(TAG, "音频文件信息读取出错:" + e.getMessage());
            // 不要退出,下面进行判断
      }
      Log.d(TAG, "Track info: mime:" + mime + " 采样率sampleRate:" + sampleRate + " channels:" + channels + " bitrate:"
                + bitrate + " duration:" + duration);
      // 检查是否为音频文件
      if (format == null || !mime.startsWith("audio/"))
      {
            Log.e(TAG, "不是音频文件 end !");
            return;
      }
      // 实例化一个指定类型的解码器,提供数据输出
      // Instantiate an encoder supporting output data of the given mime type
      mMediaCodec = MediaCodec.createDecoderByType(mime);

      if (mMediaCodec == null)
      {
            Log.e(TAG, "创建解码器失败!");
            return;
      }
      mMediaCodec.configure(format, null, null, 0);

      mMediaCodec.start();
      // 用来存放目标文件的数据
      ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
      // 解码后的数据
      ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
      // 设置声道类型:AudioFormat.CHANNEL_OUT_MONO单声道,AudioFormat.CHANNEL_OUT_STEREO双声道
      int channelConfiguration = channels == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO;
      Log.i(TAG, "channelConfiguration=" + channelConfiguration);
      extractor.selectTrack(0);
      // ==========开始解码=============
      boolean sawInputEOS = false;
      boolean sawOutputEOS = false;
      final long kTimeOutUs = 10;
      MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
      while (!sawOutputEOS)
      {
            try
            {
                if (!sawInputEOS)
                {
                  int inputBufIndex = mMediaCodec.dequeueInputBuffer(kTimeOutUs);
                  if (inputBufIndex >= 0)
                  {
                        ByteBuffer dstBuf = inputBuffers;

                        int sampleSize = extractor.readSampleData(dstBuf, 0);
                        if (sampleSize < 0)
                        {
                            Log.d(TAG, "saw input EOS. Stopping playback");
                            sawInputEOS = true;
                            sampleSize = 0;
                        } else
                        {
                            presentationTimeUs = extractor.getSampleTime();
                        }

                        mMediaCodec.queueInputBuffer(inputBufIndex, 0, sampleSize, presentationTimeUs,
                              sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);

                        if (!sawInputEOS)
                        {
                            extractor.advance();
                        }

                  } else
                  {
                        Log.e(TAG, "inputBufIndex " + inputBufIndex);
                  }
                } // !sawInputEOS

                // decode to PCM and push it to the AudioTrack player
                int res = mMediaCodec.dequeueOutputBuffer(info, kTimeOutUs);

                if (res >= 0)
                {
                  int outputBufIndex = res;
                  ByteBuffer buf = outputBuffers;
                  final byte[] chunk = new byte;
                  buf.get(chunk);
                  buf.clear();
                  if (chunk.length > 0)
                  {

                        // chunk解码后的音频流
                        // TODO:处理...
                  }
                  mMediaCodec.releaseOutputBuffer(outputBufIndex, false);
                  if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0)
                  {
                        Log.d(TAG, "saw output EOS.");
                        sawOutputEOS = true;
                  }

                } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
                {
                  outputBuffers = mMediaCodec.getOutputBuffers();
                  Log.w(TAG, "output buffers have changed.");
                } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
                {
                  MediaFormat oformat = mMediaCodec.getOutputFormat();
                  Log.w(TAG, "output format has changed to " + oformat);
                } else
                {
                  Log.w(TAG, " dequeueOutputBuffer returned " + res);
                }

            } catch (RuntimeException e)
            {
                Log.e(TAG, " error:" + e.getMessage());
            }
      }
      // =================================================================================
      if (mMediaCodec != null)
      {
            mMediaCodec.stop();
            mMediaCodec.release();
            mMediaCodec = null;
      }
      if (extractor != null)
      {
            extractor.release();
            extractor = null;
      }
      // clear source and the other globals
      duration = 0;
      mime = null;
      sampleRate = 0;
      channels = 0;
      bitrate = 0;
      presentationTimeUs = 0;
      duration = 0;
    }

你们官方是基于mediacodec做的么?为何你们那个实时性那么好,一点都没有卡顿! 网上的硬解码代码在3288上跑很卡!

脑残丞相 发表于 2016-2-22 16:44:57

我也有点糊涂,放一下代码出来看看?

qiong 发表于 2016-4-13 21:40:29

我现在也在做视频解码,多多交流啊

脑残丞相 发表于 2016-4-27 11:28:27

MeidaCodec的编码能正常跑,但是解码,从来没有跑成功过
页: [1]
查看完整版本: 关于H.264硬编码&硬解码