1

MediaCodec API を使用して mp4 ファイルをデコードします。これで、video/raw の MIME タイプのバイト配列を取得できBitmapましたActivity。ここにすべてのコードがあります。

private Resources mResources;
private Button m_playBtn;
private ImageView imageView = null;
private MyAudioTrack audioTrack = null;

private File f = null;
private FileOutputStream fos = null;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getActionBar().setDisplayHomeAsUpEnabled(true);
    mResources = this.getResources();
    m_playBtn = (Button) findViewById(R.id.playBtn);
    m_playBtn.setOnClickListener(this);
    imageView = (ImageView) findViewById(R.id.imageView);
    imageView.setImageResource(R.drawable.eee);
    audioTrack = new MyAudioTrack(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,AudioFormat.ENCODING_PCM_16BIT);
    audioTrack.init();
    f = new File("/sdcard/rawdata");
    try {
        fos = new FileOutputStream(f);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/*
 * the local file at res/raw R.raw.admiral R.raw.ttt R.raw.ww The h264 file
 * can't decode by MediaCodec . Mp3 or Mp4 can get decode byte[] from
 * MediaCodec
 */
@Override
public void onClick(View v) {
    try {
        decode(R.raw.testmp4, 0.0f);
        //decode("http://192.168.2.14/img/video.mjpeg");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

/**
 * @param testinput
 *            the file to decode
 * @param master
 *            the "golden master" to compared against
 * @param maxerror
 *            the maximum allowed root mean squared error
 * @throws IOException
 */
@SuppressLint("ParserError")
private void decode(int testinput, float maxerror) throws IOException {

    AssetFileDescriptor testFd = mResources.openRawResourceFd(testinput);

    MediaExtractor extractor;
    MediaCodec codec;
    ByteBuffer[] codecInputBuffers;
    ByteBuffer[] codecOutputBuffers;

    extractor = new MediaExtractor();
    //      extractor.setDataSource("http://zhangmenshiting2.baidu.com/data2/music/10547672/10547672.mp3?xcode=bcab1e9a9ffffae03c350b4e1ff22833&mid=0.09955182129452");
    extractor.setDataSource(testFd.getFileDescriptor(),
            testFd.getStartOffset(), testFd.getLength());
    System.out.println("wrong number of tracks:" + 1 + ":"
            + (extractor.getTrackCount()));
    MediaFormat format = extractor.getTrackFormat(0);
    String mime = format.getString(MediaFormat.KEY_MIME);
    System.out.println("mime type=====>" + mime);
    System.out.println("not an audio file:" + (mime.startsWith("audio/")));
    codec = MediaCodec.createDecoderByType(mime);
    codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
    codec.start();
    codecInputBuffers = codec.getInputBuffers();
    codecOutputBuffers = codec.getOutputBuffers();

    extractor.selectTrack(0);

    // start decoding
    int numBytesDecoded = 0;
    int maxdelta = 0;
    // long totalErrorSquared = 0;
    final long kTimeOutUs = 5000;
    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    boolean sawInputEOS = false;
    boolean sawOutputEOS = false;
    while (!sawOutputEOS) {
        if (!sawInputEOS) {
            int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);

            if (inputBufIndex >= 0) {
                ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];

                int sampleSize = extractor
                        .readSampleData(dstBuf, 0 /* offset */);

                long presentationTimeUs = 0;

                if (sampleSize < 0) {
                    System.out.println("saw input EOS.");
                    sawInputEOS = true;
                    sampleSize = 0;
                } else {
                    presentationTimeUs = extractor.getSampleTime();
                }

                codec.queueInputBuffer(inputBufIndex, 0 /* offset */,
                        sampleSize, presentationTimeUs,
                        sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM
                                : 0);

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

        int res = codec.dequeueOutputBuffer(info, kTimeOutUs);
        /**
         * from here can get the decode data
         */
        if (res >= 0) {
            MediaFormat ff = codec.getOutputFormat();// decode format
            System.out.println("Format:" + ff);
            //System.out.println("format information detail" + ff.getInteger("channel-count"));
            int outputBufIndex = res;
            ByteBuffer buf = codecOutputBuffers[outputBufIndex];
            final byte[] chunk = new byte[info.size];// decode data
            System.out.println("chunk.size" + chunk.length);
            buf.get(chunk);
            buf.clear();


            if(chunk.length > 0){
                fos.write(chunk);

            numBytesDecoded += info.size;

            codec.releaseOutputBuffer(outputBufIndex, false /* render */);

            if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                System.out.println("saw output EOS.");
                sawOutputEOS = true;
            }
        } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            codecOutputBuffers = codec.getOutputBuffers();
            System.out.println("output buffers have changed.");
        } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            MediaFormat oformat = codec.getOutputFormat();
            System.out.println("output format has changed to :" + oformat);
        }
    }
    System.out.println("geshu:" + maxdelta);
    fos.flush();
    codec.stop();
    codec.release();
    testFd.close();

}

出力形式は次のようになります。

Format:{height=240, what=1869968451, color-format=19, slice-height=240, crop-left=0, width=320, crop-bottom=239, crop-top=0, mime=video/raw 、ストライド=320、クロップ右=319}

4

1 に答える 1

1

あなたはそれを表面に見せなければなりません。レイアウトVideoViewに追加します。次に、サーフェスホルダーを使用してサーフェスオブジェクトを取得します。その後、オブジェクトをコーデック構成のメソッドに渡し、メソッドreleaseInOutputBufferにtrueを設定します。したがって、ビデオはアクティビティでレンダリングされます。

于 2012-10-22T12:37:00.290 に答える