Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Side by Side Diff: media/base/android/java/src/org/chromium/media/WebAudioMediaCodecBridge.java

Issue 12457043: Android implementation of WebAudio audio file decoder (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compiling DumpRenderTree Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/audio/android/audio_manager_android.cc ('k') | media/base/android/media_jni_registrar.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.media;
6
7 import android.content.Context;
8 import android.media.AudioFormat;
9 import android.media.MediaCodec;
10 import android.media.MediaCodec.BufferInfo;
11 import android.media.MediaExtractor;
12 import android.media.MediaFormat;
13 import android.util.Log;
14
15 import java.nio.ByteBuffer;
16 import android.os.ParcelFileDescriptor;
17
18 import org.chromium.base.CalledByNative;
19 import org.chromium.base.JNINamespace;
20
21 @JNINamespace("media")
22 class WebAudioMediaCodecBridge {
23 static final String LOG_TAG = "WebAudioMediaCodec";
24 // TODO(rtoy): What is the correct timeout value for reading
25 // from a file in memory?
26 static final long TIMEOUT_MICROSECONDS = 500;
27 @CalledByNative
28 private static boolean decodeAudioFile(Context ctx, int nativeMediaCodecBrid ge, int inputFD) {
29 MediaExtractor extractor;
30 extractor = new MediaExtractor();
31
32 ParcelFileDescriptor encodedFD;
33 try {
34 encodedFD = ParcelFileDescriptor.adoptFd(inputFD);
35 extractor.setDataSource(encodedFD.getFileDescriptor());
36 } catch (Exception e) {
37 e.printStackTrace();
digit1 2013/04/04 15:56:47 I assume you would want to call encodedFD.detachFd
38 return false;
39 }
40
41 if (extractor.getTrackCount() <= 0) {
42 encodedFD.detachFd();
43 return false;
44 }
45
46 MediaFormat format = extractor.getTrackFormat(0);
47
48 int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
49 int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
50 String mime = format.getString(MediaFormat.KEY_MIME);
51
52 long duration_microseconds = 0;
53 if (format.containsKey(MediaFormat.KEY_DURATION)) {
54 try {
55 duration_microseconds = format.getLong(MediaFormat.KEY_DURATION) ;
56 } catch (Exception e) {
57 Log.d(LOG_TAG, "Cannot get duration");
digit1 2013/04/04 15:56:47 should you exit here, or is it ok to keep duration
Raymond Toy (Google) 2013/04/04 17:47:35 I believe it's ok to keep going. MediaCodec will
58 }
59 }
60
61 Log.d(LOG_TAG, "Tracks: " + extractor.getTrackCount()
digit1 2013/04/04 15:56:47 This Log.d() call is really slow: it will create a
Raymond Toy (Google) 2013/04/04 17:47:35 Ok. I'll add this, but I do hope to remove this p
62 + " Rate: " + sampleRate
63 + " Channels: " + channelCount
64 + " Mime: " + mime
65 + " Duration: " + duration_microseconds + " microsec");
66
67 // For audio/vorbis files, MediaFormat returns a really huge
68 // (multi-year) duration value even for short files. Tell
69 // nativeInitializeDestination that this is a vorbis file so
70 // it can handle it properly.
71 //
72 // See b/8528051
73 nativeInitializeDestination(nativeMediaCodecBridge,
74 channelCount,
75 sampleRate,
76 duration_microseconds,
77 mime.equals("audio/vorbis"));
78
79 // Create decoder
80 MediaCodec codec = MediaCodec.createDecoderByType(mime);
81 codec.configure(format, null /* surface */, null /* crypto */, 0 /* flag s */);
82 codec.start();
83
84 ByteBuffer[] codecInputBuffers = codec.getInputBuffers();
85 ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers();
86
87 // A track must be selected and will be used to read samples.
88 extractor.selectTrack(0);
89
90 boolean sawInputEOS = false;
91 boolean sawOutputEOS = false;
92
93 // Keep processing until the output is done.
94 while (!sawOutputEOS) {
95 int sampleSize = 0;
96 if (!sawInputEOS) {
97 // Input side
98 int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_MICROSECOND S);
99
100 if (inputBufIndex >= 0) {
101 ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
102 sampleSize = extractor.readSampleData(dstBuf, 0);
103 long presentationTimeMicroSec = 0;
104
105 if (sampleSize < 0) {
106 sawInputEOS = true;
107 sampleSize = 0;
108 } else {
109 presentationTimeMicroSec = extractor.getSampleTime();
110 }
111
112 codec.queueInputBuffer(inputBufIndex,
113 0, /* offset */
114 sampleSize,
115 presentationTimeMicroSec,
116 sawInputEOS ? MediaCodec.BUFFER_FLAG_ END_OF_STREAM : 0);
117
118 if (!sawInputEOS) {
119 extractor.advance();
120 }
121 }
122 }
123
124 // Output side
125 MediaCodec.BufferInfo info = new BufferInfo();
126 final int outputBufIndex = codec.dequeueOutputBuffer(info, TIMEOUT_M ICROSECONDS);
127
128 if (outputBufIndex >= 0) {
digit1 2013/04/04 15:56:47 Shouldn't you also handle INFO_OUTPUT_BUFFERS_CHAN
Raymond Toy (Google) 2013/04/04 17:47:35 Oops. The case for INFO_OUTPUT_BUFFERS_CHANGED wa
129 ByteBuffer buf = codecOutputBuffers[outputBufIndex];
130
131 if (info.size > 0) {
132 nativeOnChunkDecoded(nativeMediaCodecBridge, buf, info.size) ;
133 }
134
135 buf.clear();
136 codec.releaseOutputBuffer(outputBufIndex, false /* render */);
137
138 if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
139 sawOutputEOS = true;
140 }
141 }
142 }
143
144 encodedFD.detachFd();
145
146 codec.stop();
147 codec.release();
148 codec = null;
149
150 return true;
151 }
152
153 private static native void nativeOnChunkDecoded(
154 int nativeWebAudioMediaCodecBridge, ByteBuffer buf, int size);
155
156 private static native void nativeInitializeDestination(
157 int nativeWebAudioMediaCodecBridge,
158 int channelCount,
159 int sampleRate,
160 long duration_microseconds,
161 boolean is_vorbis);
162 }
OLDNEW
« no previous file with comments | « media/audio/android/audio_manager_android.cc ('k') | media/base/android/media_jni_registrar.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698