线代e(ijk)线性代数e是什么意思思

ijke 的BLOG
用户名:ijke
无忧币:13
注册日期:
暂无文章! 等待用户 ijke 添加!
订阅我的博客
一周热赞排行
51CTO推荐博文/ IJK_DEMO
项目语言:ANDROID
权限:read-only(如需更高权限请先加入项目)
Index: IjkMediaPlayer.java
===================================================================
--- IjkMediaPlayer.java (revision 0)
+++ IjkMediaPlayer.java (revision 4)
@@ -0,0 +1,1119 @@
+ * Copyright (C) 2006 The Android Open Source Project
+ * Copyright (C) 2013 Zhang Rui &&
+ * Licensed under the Apache License, Version 2.0 (the &License&);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an &AS IS& BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+package tv.danmaku.ijk.media.
+import android.annotation.SuppressL
+import android.annotation.TargetA
+import android.content.ContentR
+import android.content.C
+import android.content.res.AssetFileD
+import android.graphics.SurfaceT
+import android.media.MediaCodecI
+import android.media.MediaCodecL
+import android.media.RingtoneM
+import android.net.U
+import android.os.B
+import android.os.B
+import android.os.H
+import android.os.L
+import android.os.M
+import android.os.ParcelFileD
+import android.os.PowerM
+import android.provider.S
+import android.text.TextU
+import android.util.L
+import android.view.S
+import android.view.SurfaceH
+import java.io.FileD
+import java.io.FileNotFoundE
+import java.io.IOE
+import java.lang.ref.WeakR
+import java.lang.reflect.F
+import java.security.InvalidParameterE
+import java.util.ArrayL
+import java.util.L
+import java.util.M
+import tv.danmaku.ijk.media.player.annotations.AccessedByN
+import tv.danmaku.ijk.media.player.annotations.CalledByN
+import tv.danmaku.ijk.media.player.misc.IMediaDataS
+import tv.danmaku.ijk.media.player.misc.ITrackI
+import tv.danmaku.ijk.media.player.misc.IjkTrackI
+import tv.danmaku.ijk.media.player.pragma.DebugL
+ * @author bbcallen
Java wrapper of ffplay.
+public final class IjkMediaPlayer extends AbstractMediaPlayer {
private final static String TAG = IjkMediaPlayer.class.getName();
private static final int MEDIA_NOP = 0; // interface test message
private static final int MEDIA_PREPARED = 1;
private static final int MEDIA_PLAYBACK_COMPLETE = 2;
private static final int MEDIA_BUFFERING_UPDATE = 3;
private static final int MEDIA_SEEK_COMPLETE = 4;
private static final int MEDIA_SET_VIDEO_SIZE = 5;
private static final int MEDIA_TIMED_TEXT = 99;
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
protected static final int MEDIA_SET_VIDEO_SAR = 10001;
//----------------------------------------
// options
public static final int IJK_LOG_UNKNOWN = 0;
public static final int IJK_LOG_DEFAULT = 1;
public static final int IJK_LOG_VERBOSE = 2;
public static final int IJK_LOG_DEBUG = 3;
public static final int IJK_LOG_INFO = 4;
public static final int IJK_LOG_WARN = 5;
public static final int IJK_LOG_ERROR = 6;
public static final int IJK_LOG_FATAL = 7;
public static final int IJK_LOG_SILENT = 8;
public static final int OPT_CATEGORY_FORMAT
public static final int OPT_CATEGORY_CODEC
public static final int OPT_CATEGORY_SWS
public static final int OPT_CATEGORY_PLAYER
public static final int SDL_FCC_YV12 = 0x; // YV12
public static final int SDL_FCC_RV16 = 0x; // RGB565
public static final int SDL_FCC_RV32 = 0x; // RGBX8888
//----------------------------------------
//----------------------------------------
// properties
public static final int PROP_FLOAT_VIDEO_DECODE_FRAMES_PER_SECOND = 10001;
public static final int PROP_FLOAT_VIDEO_OUTPUT_FRAMES_PER_SECOND = 10002;
public static final int FFP_PROP_FLOAT_PLAYBACK_RATE
public static final int FFP_PROP_INT64_SELECTED_VIDEO_STREAM
public static final int FFP_PROP_INT64_SELECTED_AUDIO_STREAM
//----------------------------------------
@AccessedByNative
private long mNativeMediaP
@AccessedByNative
private long mNativeMediaDataS
@AccessedByNative
private int mNativeSurfaceT
@AccessedByNative
private int mListenerC
private SurfaceHolder mSurfaceH
private EventHandler mEventH
private PowerManager.WakeLock mWakeLock =
private boolean mScreenOnWhileP
private boolean mStayA
private int mVideoW
private int mVideoH
private int mVideoSarN
private int mVideoSarD
private String mDataS
* Default library loader
* Load them by yourself, if your libraries are not installed at default place.
private static final IjkLibLoader sLocalLibLoader = new IjkLibLoader() {
public void loadLibrary(String libName) throws UnsatisfiedLinkError, SecurityException {
System.loadLibrary(libName);
private static volatile boolean mIsLibLoaded =
public static void loadLibrariesOnce(IjkLibLoader libLoader) {
synchronized (IjkMediaPlayer.class) {
if (!mIsLibLoaded) {
if (libLoader == null)
libLoader = sLocalLibL
libLoader.loadLibrary(&ijkffmpeg&);
libLoader.loadLibrary(&ijksdl&);
libLoader.loadLibrary(&ijkplayer&);
mIsLibLoaded =
private static volatile boolean mIsNativeInitialized =
private static void initNativeOnce() {
synchronized (IjkMediaPlayer.class) {
if (!mIsNativeInitialized) {
native_init();
mIsNativeInitialized =
* Default constructor. Consider using one of the create() methods for
* synchronously instantiating a IjkMediaPlayer from a Uri or resource.
* When done with the IjkMediaPlayer, you should call {@link #release()}, to
* free the resources. If not released, too many IjkMediaPlayer instances
* may result in an exception.
public IjkMediaPlayer() {
this(sLocalLibLoader);
* do not loadLibaray
* @param libLoader
custom library loader, can be null.
public IjkMediaPlayer(IjkLibLoader libLoader) {
initPlayer(libLoader);
private void initPlayer(IjkLibLoader libLoader) {
loadLibrariesOnce(libLoader);
initNativeOnce();
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler(this, looper);
mEventHandler =
* Native setup requires a weak reference to our object. It's easier to
* create it here than in C++.
native_setup(new WeakReference&IjkMediaPlayer&(this));
* Update the IjkMediaPlayer SurfaceTexture. Call after setting a new
* display surface.
private native void _setVideoSurface(Surface surface);
* Sets the {@link SurfaceHolder} to use for displaying the video portion of
* the media.
* Either a surface holder or surface must be set if a display or video sink
* is needed. Not calling this method or {@link #setSurface(Surface)} when
* playing back a video will result in only the audio track being played. A
* null surface holder or surface will result in only the audio track being
* @param sh
the SurfaceHolder to use for video display
public void setDisplay(SurfaceHolder sh) {
mSurfaceHolder =
if (sh != null) {
surface = sh.getSurface();
_setVideoSurface(surface);
updateSurfaceScreenOn();
* Sets the {@link Surface} to be used as the sink for the video portion of
* the media. This is similar to {@link #setDisplay(SurfaceHolder)}, but
* does not support {@link #setScreenOnWhilePlaying(boolean)}. Setting a
* Surface will un-set any Surface or SurfaceHolder that was previously set.
* A null surface will result in only the audio track being played.
* If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
* returned from {@link SurfaceTexture#getTimestamp()} will have an
* unspecified zero point. These timestamps cannot be directly compared
* between different media sources, different instances of the same media
* source, or multiple runs of the same program. The timestamp is normally
* monotonically increasing and is unaffected by time-of-day adjustments,
* but it is reset when the position is set.
* @param surface
The {@link Surface} to be used for the video portion of the
public void setSurface(Surface surface) {
if (mScreenOnWhilePlaying && surface != null) {
DebugLog.w(TAG,
&setScreenOnWhilePlaying(true) is ineffective for Surface&);
mSurfaceHolder =
_setVideoSurface(surface);
updateSurfaceScreenOn();
* Sets the data source as a content Uri.
* @param context the Context to use when resolving the Uri
* @param uri the Content URI of the data you want to play
* @throws IllegalStateException if it is called in an invalid state
public void setDataSource(Context context, Uri uri)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
setDataSource(context, uri, null);
* Sets the data source as a content Uri.
* @param context the Context to use when resolving the Uri
* @param uri the Content URI of the data you want to play
* @param headers the headers to be sent together with the request for the data
Note that the cross domain redirection is allowed by default, but that can be
changed with key/value pairs through the headers parameter with
&android-allow-cross-domain-redirect& as the key and &0& or &1& as the value
to disallow or allow cross domain redirection.
* @throws IllegalStateException if it is called in an invalid state
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public void setDataSource(Context context, Uri uri, Map&String, String& headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
final String scheme = uri.getScheme();
if (ContentResolver.SCHEME_FILE.equals(scheme)) {
setDataSource(uri.getPath());
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
&& Settings.AUTHORITY.equals(uri.getAuthority())) {
// Redirect ringtones to go directly to underlying provider
uri = RingtoneManager.getActualDefaultRingtoneUri(context,
RingtoneManager.getDefaultType(uri));
if (uri == null) {
throw new FileNotFoundException(&Failed to resolve default ringtone&);
AssetFileDescriptor fd =
ContentResolver resolver = context.getContentResolver();
fd = resolver.openAssetFileDescriptor(uri, &r&);
if (fd == null) {
// Note: using getDeclaredLength so that our behavior is the same
// as previous versions when the content provider is returning
// a full file.
if (fd.getDeclaredLength() & 0) {
setDataSource(fd.getFileDescriptor());
setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getDeclaredLength());
} catch (SecurityException ignored) {
} catch (IOException ignored) {
} finally {
if (fd != null) {
fd.close();
Log.d(TAG, &Couldn't open file on client side, trying server side&);
setDataSource(uri.toString(), headers);
* Sets the data source (file-path or http/rtsp URL) to use.
* @param path
the path of the file, or the http/rtsp URL of the stream you
want to play
* @throws IllegalStateException
if it is called in an invalid state
When &code&path&/code& refers to a local file, the file may
actually be opened by a process other than the calling
application. This implies that the pathname should be an
absolute path (as any other process runs with unspecified
current working directory), and that the pathname should
reference a world-readable file.
public void setDataSource(String path)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
mDataSource =
_setDataSource(path, null, null);
* Sets the data source (file-path or http/rtsp URL) to use.
* @param path the path of the file, or the http/rtsp URL of the stream you want to play
* @param headers the headers associated with the http request for the stream you want to play
* @throws IllegalStateException if it is called in an invalid state
public void setDataSource(String path, Map&String, String& headers)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
if (headers != null && !headers.isEmpty()) {
StringBuilder sb = new StringBuilder();
for(Map.Entry&String, String& entry: headers.entrySet()) {
sb.append(entry.getKey());
sb.append(&:&);
String value = entry.getValue();
if (!TextUtils.isEmpty(value))
sb.append(entry.getValue());
sb.append(&\r\n&);
setOption(OPT_CATEGORY_FORMAT, &headers&, sb.toString());
setDataSource(path);
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
* @param fd the FileDescriptor for the file you want to play
* @throws IllegalStateException if it is called in an invalid state
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void setDataSource(FileDescriptor fd)
throws IOException, IllegalArgumentException, IllegalStateException {
if (Build.VERSION.SDK_INT & Build.VERSION_CODES.HONEYCOMB_MR1) {
int native_fd = -1;
Field f = fd.getClass().getDeclaredField(&descriptor&); //NoSuchFieldException
f.setAccessible(true);
native_fd = f.getInt(fd); //IllegalAccessException
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
_setDataSourceFd(native_fd);
ParcelFileDescriptor pfd = ParcelFileDescriptor.dup(fd);
_setDataSourceFd(pfd.getFd());
} finally {
pfd.close();
* Sets the data source (FileDescriptor) to use.
The FileDescriptor must be
* seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
* @param fd the FileDescriptor for the file you want to play
* @param offset the offset into the file where the data to be played starts, in bytes
* @param length the length in bytes of the data to be played
* @throws IllegalStateException if it is called in an invalid state
private void setDataSource(FileDescriptor fd, long offset, long length)
throws IOException, IllegalArgumentException, IllegalStateException {
// FIXME: handle offset, length
setDataSource(fd);
public void setDataSource(IMediaDataSource mediaDataSource)
throws IllegalArgumentException, SecurityException, IllegalStateException {
_setDataSource(mediaDataSource);
private native void _setDataSource(String path, String[] keys, String[] values)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateE
private native void _setDataSourceFd(int fd)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateE
private native void _setDataSource(IMediaDataSource mediaDataSource)
throws IllegalArgumentException, SecurityException, IllegalStateE
public String getDataSource() {
return mDataS
public void prepareAsync() throws IllegalStateException {
_prepareAsync();
public native void _prepareAsync() throws IllegalStateE
public void start() throws IllegalStateException {
stayAwake(true);
private native void _start() throws IllegalStateE
public void stop() throws IllegalStateException {
stayAwake(false);
private native void _stop() throws IllegalStateE
public void pause() throws IllegalStateException {
stayAwake(false);
private native void _pause() throws IllegalStateE
@SuppressLint(&Wakelock&)
public void setWakeMode(Context context, int mode) {
boolean washeld =
if (mWakeLock != null) {
if (mWakeLock.isHeld()) {
mWakeLock.release();
mWakeLock =
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(mode | PowerManager.ON_AFTER_RELEASE,
IjkMediaPlayer.class.getName());
mWakeLock.setReferenceCounted(false);
if (washeld) {
mWakeLock.acquire();
public void setScreenOnWhilePlaying(boolean screenOn) {
if (mScreenOnWhilePlaying != screenOn) {
if (screenOn && mSurfaceHolder == null) {
DebugLog.w(TAG,
&setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder&);
mScreenOnWhilePlaying = screenOn;
updateSurfaceScreenOn();
@SuppressLint(&Wakelock&)
private void stayAwake(boolean awake) {
if (mWakeLock != null) {
if (awake && !mWakeLock.isHeld()) {
mWakeLock.acquire();
} else if (!awake && mWakeLock.isHeld()) {
mWakeLock.release();
mStayAwake =
updateSurfaceScreenOn();
private void updateSurfaceScreenOn() {
if (mSurfaceHolder != null) {
mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
public IjkTrackInfo[] getTrackInfo() {
Bundle bundle = getMediaMeta();
if (bundle == null)
IjkMediaMeta mediaMeta = IjkMediaMeta.parse(bundle);
if (mediaMeta == null || mediaMeta.mStreams == null)
ArrayList&IjkTrackInfo& trackInfos = new ArrayList&IjkTrackInfo&();
for (IjkMediaMeta.IjkStreamMeta streamMeta: mediaMeta.mStreams) {
IjkTrackInfo trackInfo = new IjkTrackInfo(streamMeta);
if (streamMeta.mType.equalsIgnoreCase(IjkMediaMeta.IJKM_VAL_TYPE__VIDEO)) {
trackInfo.setTrackType(ITrackInfo.MEDIA_TRACK_TYPE_VIDEO);
} else if (streamMeta.mType.equalsIgnoreCase(IjkMediaMeta.IJKM_VAL_TYPE__AUDIO)) {
trackInfo.setTrackType(ITrackInfo.MEDIA_TRACK_TYPE_AUDIO);
trackInfos.add(trackInfo);
return trackInfos.toArray(new IjkTrackInfo[trackInfos.size()]);
// TODO: @Override
public int getSelectedTrack(int trackType) {
switch (trackType) {
case ITrackInfo.MEDIA_TRACK_TYPE_VIDEO:
return (int)_getPropertyLong(FFP_PROP_INT64_SELECTED_VIDEO_STREAM, -1);
case ITrackInfo.MEDIA_TRACK_TYPE_AUDIO:
return (int)_getPropertyLong(FFP_PROP_INT64_SELECTED_AUDIO_STREAM, -1);
return -1;
// experimental, should set DEFAULT_MIN_FRAMES and MAX_MIN_FRAMES to 25
// TODO: @Override
public void selectTrack(int track) {
_setStreamSelected(track, true);
// experimental, should set DEFAULT_MIN_FRAMES and MAX_MIN_FRAMES to 25
// TODO: @Override
public void deselectTrack(int track) {
_setStreamSelected(track, false);
private native void _setStreamSelected(int stream, boolean select);
public int getVideoWidth() {
return mVideoW
public int getVideoHeight() {
return mVideoH
public int getVideoSarNum() {
return mVideoSarN
public int getVideoSarDen() {
return mVideoSarD
public native boolean isPlaying();
public native void seekTo(long msec) throws IllegalStateE
public native long getCurrentPosition();
public native long getDuration();
* Releases resources associated with this IjkMediaPlayer object. It is
* considered good practice to call this method when you're done using the
* IjkMediaPlayer. In particular, whenever an Activity of an application is
* paused (its onPause() method is called), or stopped (its onStop() method
* is called), this method should be invoked to release the IjkMediaPlayer
* object, unless the application has a special need to keep the object
* around. In addition to unnecessary resources (such as memory and
* instances of codecs) being held, failure to call this method immediately
* if a IjkMediaPlayer object is no longer needed may also lead to
* continuous battery consumption for mobile devices, and playback failure
* for other applications if no multiple instances of the same codec are
* supported on a device. Even if multiple instances of the same codec are
* supported, some performance degradation may be expected when unnecessary
* multiple instances are used at the same time.
public void release() {
stayAwake(false);
updateSurfaceScreenOn();
resetListeners();
_release();
private native void _release();
public void reset() {
stayAwake(false);
// make sure none of the listeners get called anymore
mEventHandler.removeCallbacksAndMessages(null);
mVideoWidth = 0;
mVideoHeight = 0;
private native void _reset();
* Sets the player to be looping or non-looping.
* @param looping whether to loop or not
public void setLooping(boolean looping) {
int loopCount = looping ? 0 : 1;
setOption(OPT_CATEGORY_PLAYER, &loop&, loopCount);
_setLoopCount(loopCount);
private native void _setLoopCount(int loopCount);
* Checks whether the MediaPlayer is looping or non-looping.
* @return true if the MediaPlayer is currently looping, false otherwise
public boolean isLooping() {
int loopCount = _getLoopCount();
return loopCount != 1;
private native int _getLoopCount();
public float getVideoOutputFramesPerSecond() {
return _getPropertyFloat(PROP_FLOAT_VIDEO_OUTPUT_FRAMES_PER_SECOND, 0.0f);
public float getVideoDecodeFramesPerSecond() {
return _getPropertyFloat(PROP_FLOAT_VIDEO_DECODE_FRAMES_PER_SECOND, 0.0f);
private native float _getPropertyFloat(int property, float defaultValue);
private native void
_setPropertyFloat(int property, float value);
private native long
_getPropertyLong(int property, long defaultValue);
private native void
_setPropertyLong(int property, long value);
public native void setVolume(float leftVolume, float rightVolume);
public native int getAudioSessionId();
public MediaInfo getMediaInfo() {
MediaInfo mediaInfo = new MediaInfo();
mediaInfo.mMediaPlayerName = &ijkplayer&;
String videoCodecInfo = _getVideoCodecInfo();
if (!TextUtils.isEmpty(videoCodecInfo)) {
String nodes[] = videoCodecInfo.split(&,&);
if (nodes.length &= 2) {
mediaInfo.mVideoDecoder = nodes[0];
mediaInfo.mVideoDecoderImpl = nodes[1];
} else if (nodes.length &= 1) {
mediaInfo.mVideoDecoder = nodes[0];
mediaInfo.mVideoDecoderImpl = &&;
String audioCodecInfo = _getAudioCodecInfo();
if (!TextUtils.isEmpty(audioCodecInfo)) {
String nodes[] = audioCodecInfo.split(&,&);
if (nodes.length &= 2) {
mediaInfo.mAudioDecoder = nodes[0];
mediaInfo.mAudioDecoderImpl = nodes[1];
} else if (nodes.length &= 1) {
mediaInfo.mAudioDecoder = nodes[0];
mediaInfo.mAudioDecoderImpl = &&;
mediaInfo.mMeta = IjkMediaMeta.parse(_getMediaMeta());
} catch (Throwable e) {
e.printStackTrace();
return mediaI
public void setLogEnabled(boolean enable) {
// do nothing
public boolean isPlayable() {
private native String _getVideoCodecInfo();
private native String _getAudioCodecInfo();
public void setOption(int category, String name, String value)
_setOption(category, name, value);
public void setOption(int category, String name, long value)
_setOption(category, name, value);
private native void _setOption(int category, String name, String value);
private native void _setOption(int category, String name, long value);
public Bundle getMediaMeta() {
return _getMediaMeta();
private native Bundle _getMediaMeta();
public static String getColorFormatName(int mediaCodecColorFormat) {
return _getColorFormatName(mediaCodecColorFormat);
private static native String _getColorFormatName(int mediaCodecColorFormat);
public void setAudioStreamType(int streamtype) {
// do nothing
public void setKeepInBackground(boolean keepInBackground) {
// do nothing
private static native void native_init();
private native void native_setup(Object IjkMediaPlayer_this);
private native void native_finalize();
private native void native_message_loop(Object IjkMediaPlayer_this);
protected void finalize() throws Throwable {
super.finalize();
native_finalize();
private static class EventHandler extends Handler {
private final WeakReference&IjkMediaPlayer& mWeakP
public EventHandler(IjkMediaPlayer mp, Looper looper) {
super(looper);
mWeakPlayer = new WeakReference&IjkMediaPlayer&(mp);
public void handleMessage(Message msg) {
IjkMediaPlayer player = mWeakPlayer.get();
if (player == null || player.mNativeMediaPlayer == 0) {
DebugLog.w(TAG,
&IjkMediaPlayer went away with unhandled events&);
switch (msg.what) {
case MEDIA_PREPARED:
player.notifyOnPrepared();
case MEDIA_PLAYBACK_COMPLETE:
player.notifyOnCompletion();
player.stayAwake(false);
case MEDIA_BUFFERING_UPDATE:
long bufferPosition = msg.arg1;
if (bufferPosition & 0) {
bufferPosition = 0;
long percent = 0;
long duration = player.getDuration();
if (duration & 0) {
percent = bufferPosition * 100 /
if (percent &= 100) {
percent = 100;
// DebugLog.efmt(TAG, &Buffer (%d%%) %d/%d&,
percent, bufferPosition, duration);
player.notifyOnBufferingUpdate((int)percent);
case MEDIA_SEEK_COMPLETE:
player.notifyOnSeekComplete();
case MEDIA_SET_VIDEO_SIZE:
player.mVideoWidth = msg.arg1;
player.mVideoHeight = msg.arg2;
player.notifyOnVideoSizeChanged(player.mVideoWidth, player.mVideoHeight,
player.mVideoSarNum, player.mVideoSarDen);
case MEDIA_ERROR:
DebugLog.e(TAG, &Error (& + msg.arg1 + &,& + msg.arg2 + &)&);
if (!player.notifyOnError(msg.arg1, msg.arg2)) {
player.notifyOnCompletion();
player.stayAwake(false);
case MEDIA_INFO:
switch (msg.arg1) {
case MEDIA_INFO_VIDEO_RENDERING_START:
DebugLog.i(TAG, &Info: MEDIA_INFO_VIDEO_RENDERING_START\n&);
player.notifyOnInfo(msg.arg1, msg.arg2);
// No real default action so far.
case MEDIA_TIMED_TEXT:
// do nothing
case MEDIA_NOP: // interface test message - ignore
case MEDIA_SET_VIDEO_SAR:
player.mVideoSarNum = msg.arg1;
player.mVideoSarDen = msg.arg2;
player.notifyOnVideoSizeChanged(player.mVideoWidth, player.mVideoHeight,
player.mVideoSarNum, player.mVideoSarDen);
DebugLog.e(TAG, &Unknown message type & + msg.what);
* Called from native code when an interesting event happens. This method
* just uses the EventHandler system to post the event back to the main app
* thread. We use a weak reference to the original IjkMediaPlayer object so
* that the native code is safe from the object disappearing from underneath
* it. (This is the cookie passed to native_setup().)
@CalledByNative
private static void postEventFromNative(Object weakThiz, int what,
int arg1, int arg2, Object obj) {
if (weakThiz == null)
@SuppressWarnings(&rawtypes&)
IjkMediaPlayer mp = (IjkMediaPlayer) ((WeakReference) weakThiz).get();
if (mp == null) {
if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
// this acquires the wakelock if needed, and sets the client side
mp.start();
if (mp.mEventHandler != null) {
Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
mp.mEventHandler.sendMessage(m);
* ControlMessage
private OnControlMessageListener mOnControlMessageL
public void setOnControlMessageListener(OnControlMessageListener listener) {
mOnControlMessageListener =
public interface OnControlMessageListener {
String onControlResolveSegmentUrl(int segment);
* NativeInvoke
private OnNativeInvokeListener mOnNativeInvokeL
public void setOnNativeInvokeListener(OnNativeInvokeListener listener) {
mOnNativeInvokeListener =
public interface OnNativeInvokeListener {
int ON_CONCAT_RESOLVE_SEGMENT = 0x10000;
int ON_TCP_OPEN = 0x10001;
int ON_HTTP_OPEN = 0x10002;
// int ON_HTTP_RETRY = 0x10003;
int ON_LIVE_RETRY = 0x10004;
String ARG_URL = &url&;
String ARG_SEGMENT_INDEX = &segment_index&;
String ARG_RETRY_COUNTER = &retry_counter&;
* @return true if invoke is handled
* @throws Exception on any error
boolean onNativeInvoke(int what, Bundle args);
@CalledByNative
private static boolean onNativeInvoke(Object weakThiz, int what, Bundle args) {
DebugLog.ifmt(TAG, &onNativeInvoke %d&, what);
if (weakThiz == null || !(weakThiz instanceof WeakReference&?&))
throw new IllegalStateException(&&null weakThiz&.onNativeInvoke()&);
@SuppressWarnings(&unchecked&)
WeakReference&IjkMediaPlayer& weakPlayer = (WeakReference&IjkMediaPlayer&) weakT
IjkMediaPlayer player = weakPlayer.get();
if (player == null)
throw new IllegalStateException(&&null weakPlayer&.onNativeInvoke()&);
OnNativeInvokeListener listener = player.mOnNativeInvokeL
if (listener != null && listener.onNativeInvoke(what, args))
switch (what) {
case OnNativeInvokeListener.ON_CONCAT_RESOLVE_SEGMENT: {
OnControlMessageListener onControlMessageListener = player.mOnControlMessageL
if (onControlMessageListener == null)
int segmentIndex = args.getInt(OnNativeInvokeListener.ARG_SEGMENT_INDEX, -1);
if (segmentIndex & 0)
throw new InvalidParameterException(&onNativeInvoke(invalid segment index)&);
String newUrl = onControlMessageListener.onControlResolveSegmentUrl(segmentIndex);
if (newUrl == null)
throw new RuntimeException(new IOException(&onNativeInvoke() = &NULL newUrl&&));
args.putString(OnNativeInvokeListener.ARG_URL, newUrl);
* MediaCodec select
public interface OnMediaCodecSelectListener {
String onMediaCodecSelect(IMediaPlayer mp, String mimeType, int profile, int level);
private OnMediaCodecSelectListener mOnMediaCodecSelectL
public void setOnMediaCodecSelectListener(OnMediaCodecSelectListener listener) {
mOnMediaCodecSelectListener =
public void resetListeners() {
super.resetListeners();
mOnMediaCodecSelectListener =
@CalledByNative
private static String onSelectCodec(Object weakThiz, String mimeType, int profile, int level) {
if (weakThiz == null || !(weakThiz instanceof WeakReference&?&))
@SuppressWarnings(&unchecked&)
WeakReference&IjkMediaPlayer& weakPlayer = (WeakReference&IjkMediaPlayer&) weakT
IjkMediaPlayer player = weakPlayer.get();
if (player == null)
OnMediaCodecSelectListener listener = player.mOnMediaCodecSelectL
if (listener == null)
listener = DefaultMediaCodecSelector.sI
return listener.onMediaCodecSelect(player, mimeType, profile, level);
public static class DefaultMediaCodecSelector implements OnMediaCodecSelectListener {
public static final DefaultMediaCodecSelector sInstance = new DefaultMediaCodecSelector();
@SuppressWarnings(&deprecation&)
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public String onMediaCodecSelect(IMediaPlayer mp, String mimeType, int profile, int level) {
if (Build.VERSION.SDK_INT & Build.VERSION_CODES.JELLY_BEAN)
if (TextUtils.isEmpty(mimeType))
Log.i(TAG, String.format(Locale.US, &onSelectCodec: mime=%s, profile=%d, level=%d&, mimeType, profile, level));
ArrayList&IjkMediaCodecInfo& candidateCodecList = new ArrayList&IjkMediaCodecInfo&();
int numCodecs = MediaCodecList.getCodecCount();
for (int i = 0; i & numC i++) {
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
Log.d(TAG, String.format(Locale.US, &
found codec: %s&, codecInfo.getName()));
if (codecInfo.isEncoder())
String[] types = codecInfo.getSupportedTypes();
if (types == null)
for(String type: types) {
if (TextUtils.isEmpty(type))
Log.d(TAG, String.format(Locale.US, &
mime: %s&, type));
if (!type.equalsIgnoreCase(mimeType))
IjkMediaCodecInfo candidate = IjkMediaCodecInfo.setupCandidate(codecInfo, mimeType);
if (candidate == null)
candidateCodecList.add(candidate);
Log.i(TAG, String.format(Locale.US, &candidate codec: %s rank=%d&, codecInfo.getName(), candidate.mRank));
candidate.dumpProfileLevels(mimeType);
if (candidateCodecList.isEmpty()) {
IjkMediaCodecInfo bestCodec = candidateCodecList.get(0);
for (IjkMediaCodecInfo codec : candidateCodecList) {
if (codec.mRank & bestCodec.mRank) {
bestCodec =
if (bestCodec.mRank & IjkMediaCodecInfo.RANK_LAST_CHANCE) {
Log.w(TAG, String.format(Locale.US, &unaccetable codec: %s&, bestCodec.mCodecInfo.getName()));
Log.i(TAG, String.format(Locale.US, &selected codec: %s rank=%d&, bestCodec.mCodecInfo.getName(), bestCodec.mRank));
return bestCodec.mCodecInfo.getName();
public static native void native_profileBegin(String libName);
public static native void native_profileEnd();
public static native void native_setLogLevel(int level);
(C)&&2013&&Alibaba&&Inc.&&All&&rights&&resvered.
Powered by}

我要回帖

更多关于 e代表什么意思 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信