summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahesh Lanka <mlanka@codeaurora.org>2014-03-20 16:04:37 +0530
committerSteve Kondik <steve@cyngn.com>2015-10-13 09:14:20 -1000
commite20c801118f537471c5443601c8505418eaff159 (patch)
tree22fcbbb0974bb821926284cffe89b3f9fb897a00
parent0e94962e3af8b1dd75c1f4dbb88590c737d7e6d9 (diff)
downloadandroid_hardware_qcom_media-e20c801118f537471c5443601c8505418eaff159.tar.gz
android_hardware_qcom_media-e20c801118f537471c5443601c8505418eaff159.tar.bz2
android_hardware_qcom_media-e20c801118f537471c5443601c8505418eaff159.zip
dashplayer: Remove dashplayer and QCMediaPlayer projects.
dashplayer and QCMediaPlayer projects are moved to external/mm-dash Change-Id: I828d4877fb8638ad43a438caccb60740ce5245fc
-rw-r--r--Android.mk7
-rw-r--r--QCMediaPlayer/Android.mk27
-rw-r--r--QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java556
-rw-r--r--QCMediaPlayer/com/qualcomm/qcmedia/QCMediaPlayer.java368
-rw-r--r--QCMediaPlayer/com/qualcomm/qcmedia/QCTimedText.java801
-rw-r--r--dashplayer/Android.mk60
-rw-r--r--dashplayer/DashCodec.cpp4671
-rw-r--r--dashplayer/DashCodec.h313
-rw-r--r--dashplayer/DashFactory.cpp60
-rw-r--r--dashplayer/DashPacketSource.cpp265
-rw-r--r--dashplayer/DashPacketSource.h87
-rw-r--r--dashplayer/DashPlayer.cpp2523
-rw-r--r--dashplayer/DashPlayer.h307
-rw-r--r--dashplayer/DashPlayerDecoder.cpp592
-rw-r--r--dashplayer/DashPlayerDecoder.h105
-rw-r--r--dashplayer/DashPlayerDriver.cpp503
-rw-r--r--dashplayer/DashPlayerDriver.h109
-rw-r--r--dashplayer/DashPlayerRenderer.cpp798
-rw-r--r--dashplayer/DashPlayerRenderer.h151
-rw-r--r--dashplayer/DashPlayerSource.h123
-rw-r--r--dashplayer/DashPlayerStats.cpp290
-rw-r--r--dashplayer/DashPlayerStats.h98
-rw-r--r--dashplayer/jni/Android.mk26
-rwxr-xr-xdashplayer/jni/android_media_ExtMediaPlayer.cpp158
-rw-r--r--dashplayer/jni/android_media_ExtMediaPlayer.h60
25 files changed, 0 insertions, 13058 deletions
diff --git a/Android.mk b/Android.mk
index 2c1137e8..303e151a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,11 +14,4 @@ ifneq ($(filter msm8610 msm8226 msm8974 msm8960 apq8084 mpq8092,$(TARGET_BOARD_P
include $(QCOM_MEDIA_ROOT)/libc2dcolorconvert/Android.mk
endif
-ifneq ($(filter msm8974 msm8960 msm8226 apq8084 mpq8092 msm8610 ,$(TARGET_BOARD_PLATFORM)),)
-include $(QCOM_MEDIA_ROOT)/QCMediaPlayer/Android.mk
-include $(QCOM_MEDIA_ROOT)/QCMediaPlayer/native/Android.mk
-include $(QCOM_MEDIA_ROOT)/dashplayer/Android.mk
-include $(QCOM_MEDIA_ROOT)/dashplayer/jni/Android.mk
-endif
-
endif
diff --git a/QCMediaPlayer/Android.mk b/QCMediaPlayer/Android.mk
deleted file mode 100644
index ec52901d..00000000
--- a/QCMediaPlayer/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#/******************************************************************************
-#*@file Android.mk
-#*brief Rules for copiling the source files
-#* ******************************************************************************/
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := eng
-
-#LOCAL_SRC_FILES := $(call all-subdir-java-files)
-ifeq ($(PLATFORM_VERSION),4.3)
-LOCAL_SRC_FILES :=com/qualcomm/qcmedia/QCMediaPlayer.java
-else
-LOCAL_SRC_FILES :=NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
-endif
-
-LOCAL_SRC_FILES += com/qualcomm/qcmedia/QCTimedText.java
-
-LOCAL_MODULE := qcmediaplayer
-LOCAL_MODULE_PATH := $(TARGET_OUT_JAVA_LIBRARIES)
-
-ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS), true)
-ifndef TARGET_DISABLE_DASH
-include $(BUILD_JAVA_LIBRARY)
-endif
-endif
diff --git a/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java b/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
deleted file mode 100644
index a93eb160..00000000
--- a/QCMediaPlayer/NonJB/com/qualcomm/qcmedia/QCMediaPlayer.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
- *
- * File: QCMediaPlayer.java
- * Description: Snapdragon SDK for Android support class.
- *
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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 com.qualcomm.qcmedia;
-
-import android.media.MediaPlayer;
-import android.util.Log;
-import android.media.TimedText;
-import java.lang.ref.WeakReference;
-import com.qualcomm.qcmedia.QCTimedText;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import java.util.HashSet;
-import java.io.IOException;
-import android.content.Context;
-import android.net.Uri;
-import java.util.Map;
-
-/**
-* QCMediaPlayer extends MediaPlayer from package android.media and provides
-* extended APIs and interfaces to get and set MPD attributes for DASH protocol
-* in compatible Snapdragon builds.
-*{@hide}
-*/
-
-public class QCMediaPlayer extends MediaPlayer
-{
- private final static String TAG = "QCMediaPlayer";
- private QCMediaEventHandler mEventHandler;
-
- //Stores the supported keys for getParameter invoke call
- public static final HashSet<Integer> VALID_GET_PARAM_KEYS = new HashSet<Integer>();
- static
- {
- VALID_GET_PARAM_KEYS.add(new Integer(OnMPDAttributeListener.ATTRIBUTES_WHOLE_MPD));
- VALID_GET_PARAM_KEYS.add(new Integer(OnMPDAttributeListener.INVOKE_ID_GET_ATTRIBUTES_TYPE_MPD));
- VALID_GET_PARAM_KEYS.add(new Integer(OnQOEEventListener.ATTRIBUTES_QOE_EVENT_PERIODIC));
- VALID_GET_PARAM_KEYS.add(new Integer(QCMediaPlayer.KEY_DASH_REPOSITION_RANGE));
- }
-
- public QCMediaPlayer()
- {
- super();
- Looper looper;
- if ((looper = Looper.myLooper()) != null)
- {
- mEventHandler = new QCMediaEventHandler(this, looper);
- }
- else if ((looper = Looper.getMainLooper()) != null)
- {
- mEventHandler = new QCMediaEventHandler(this, looper);
- }
- else
- {
- mEventHandler = null;
- }
-
- ePlayerState = MediaPlayerState.PLAYER_IDLE;
-
- Log.d(TAG, "QCMediaPlayer::QCMediaPlayer");
- }
-
- public void setDataSource(Context context, Uri uri)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
- {
- Log.d(TAG, "setDataSource");
- super.setDataSource(context, uri);
- ePlayerState = MediaPlayerState.PLAYER_INITIALIZED;
- TurnOnOffTimedTextListener();
- }
-
- public void setDataSource(Context context, Uri uri, Map<String, String> headers)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
- {
- Log.d(TAG, "setDataSource");
- super.setDataSource(context, uri, headers);
- ePlayerState = MediaPlayerState.PLAYER_INITIALIZED;
- TurnOnOffTimedTextListener();
- }
-
- public void setDataSource(String path)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
- {
- Log.d(TAG, "setDataSource");
- super.setDataSource(path);
- ePlayerState = MediaPlayerState.PLAYER_INITIALIZED;
- TurnOnOffTimedTextListener();
- }
-
- public void setDataSource(String path, Map<String, String> headers)
- throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
- {
- Log.d(TAG, "setDataSource");
- super.setDataSource(path, headers);
- ePlayerState = MediaPlayerState.PLAYER_INITIALIZED;
- TurnOnOffTimedTextListener();
- }
-
- public void reset() {
- Log.d(TAG, "reset");
- super.reset();
- ePlayerState = MediaPlayerState.PLAYER_IDLE;
- }
-
- public void release() {
- Log.d(TAG, "release");
-
- mQCOnPreparedListener = null;
- mOnMPDAttributeListener = null;
- mOnQCTimedTextListener = null;
- mOnQOEEventListener = null;
-
- super.release();
-
- ePlayerState = MediaPlayerState.PLAYER_IDLE;
- }
-
- public void TurnOnOffTimedTextListener()
- {
- //Turn on/off timedtext registered flag in dashplayer. setOnQCTimedTextListener can be called
- //anytime from app. Below qcsetparameter call uses invoke() which needs to be called only
- //after mediaplayer.cpp transitioned out of IDLE state
- if(ePlayerState != MediaPlayerState.PLAYER_IDLE)
- {
- int val = (mOnQCTimedTextListener == null) ? 0 : 1;
- Log.d(TAG, "TurnOnOffTimedTextListener set listener flag" + val);
- QCsetParameter(KEY_QCTIMEDTEXT_LISTENER, val);
- }
- }
-
- private void callOnPreparedListener()
- {
- Log.d(TAG, "callOnPreparedListener");
- if (mQCOnPreparedListener != null)
- mQCOnPreparedListener.onPrepared(this);
- }
-
- private void callOnMPDAttributeListener()
- {
- Log.d(TAG, "callOnMPDAttributeListener");
- if (mOnMPDAttributeListener != null)
- {
- String mpdAttributes = QCgetStringParameter(OnMPDAttributeListener.INVOKE_ID_GET_ATTRIBUTES_TYPE_MPD);
- mOnMPDAttributeListener.onMPDAttribute(OnMPDAttributeListener.ATTRIBUTES_TYPE_MPD, mpdAttributes, this);
- }
- }
- private void callQCTimedTextListener(QCTimedText text)
- {
- if(mOnQCTimedTextListener != null)
- {
- mOnQCTimedTextListener.onQCTimedText(this, text);
- }
- }
- private void callOnQOEEventListener(int key,Parcel parcel)
- {
- Log.d(TAG, "callOnQOEEventListener");
- if (mOnQOEEventListener != null)
- {
- mOnQOEEventListener.onQOEAttribute(key,parcel,this);
- }
- }
-
- /**
- * Additional propreitary interface definition of a callback to be invoked
- * when a Qtimed text is available for display.
- * {@hide}
- */
- public interface OnQCTimedTextListener
- {
- /**
- * Called to indicate an avaliable timed text
- *
- * @param mp the QCMediaPlayer associated with this
- * callback
- * @param text the Qtimed text sample which contains the text
- * needed to be displayed and the display format.
- * {@hide}
- */
- public void onQCTimedText(QCMediaPlayer mp, QCTimedText text);
- }
-
- /**
- * Register a callback to be invoked when a Qtimed text is available
- * for display.
- *
- * @param listener the callback that will be run
- * {@hide}
- */
- public void setOnQCTimedTextListener(OnQCTimedTextListener listener)
- {
- Log.d(TAG, "setOnQCTimedTextListener");
-
- mOnQCTimedTextListener = listener;
- TurnOnOffTimedTextListener();
- }
- private OnQCTimedTextListener mOnQCTimedTextListener;
-
- /**
- * Register a callback to be invoked when the media source is ready
- * for playback.
- *
- * @param listener the callback that will be run
- */
- public void setOnPreparedListener(OnPreparedListener listener)
- {
- mQCOnPreparedListener = listener;
- Log.d(TAG, "setOnPreparedListener");
- }
- private OnPreparedListener mQCOnPreparedListener;
-
- /**
- * Interface definition for a callback to be invoked when the media
- * source is ready for MPD attribute retrieval
- */
- public interface OnMPDAttributeListener
- {
- /**
- * Key to identify type of MPD attributes
- */
- public static final int ATTRIBUTES_TYPE_MPD = 8002;
- /**
- * Key to be used to retrieve complete MPD.
- */
- public static final int ATTRIBUTES_WHOLE_MPD = 8003;
- /**
- * Key to Get MPD attributes
- */
- public static final int INVOKE_ID_GET_ATTRIBUTES_TYPE_MPD = 8010;
-
- /**
- * Key to Set MPD attributes
- */
- public static final int INVOKE_ID_SET_ATTRIBUTES_TYPE_MPD = 8011;
-
- /**
- * Called when attributes are available.
- *
- * @param attributekey the key identifying the type of attributes available
- * @param value the value for the attribute
- * @param mp the MediaPlayer to which MPD attribute is applicable
- *
- */
- public void onMPDAttribute(int attributekey, String value, QCMediaPlayer mp);
- }
-
- /**
- * Register a callback to be invoked when MPD attributes are avaialble
- *
- * @param listener the callback that will be run
- */
- public void setOnMPDAttributeListener(OnMPDAttributeListener listener)
- {
- mOnMPDAttributeListener = listener;
- }
-
- private OnMPDAttributeListener mOnMPDAttributeListener;
-
- /**
- * Process the parameter indicated by key.
- * @param key the key idicated the parameter to be processed
- * @param value the value for the parameter identified by key
- * @return true if successful in processing the parameter else returns false
- * @see OnMPDAttributeListener the interface for valid keys to be used
- *
- */
- public boolean processMPDAttribute(int key, String value)
- {
- boolean retval = false;
- if(key == OnMPDAttributeListener.ATTRIBUTES_TYPE_MPD)
- {
- key = OnMPDAttributeListener.INVOKE_ID_SET_ATTRIBUTES_TYPE_MPD;
- }
- return QCsetStringParameter(key, value);
- }
- public String QCGetParameter(int key)
- {
- if(key == OnMPDAttributeListener.ATTRIBUTES_TYPE_MPD)
- {
- key = OnMPDAttributeListener.INVOKE_ID_GET_ATTRIBUTES_TYPE_MPD;
- }
-
- return QCgetStringParameter(key);
- }
- public Parcel QCPeriodicParameter(int key)
- {
- if(key == mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PERIODIC)
- {
- return QCgetParcelParameter(key);
- }
- return null;
- }
- public boolean QCSetParameter(int key, int value)
- {
- Log.d(TAG, "QCMediaPlayer : QCSetParameter");
- return QCsetParameter(key, value);
- }
-
- /**
- * Interface definition for a callback to be invoked when the media
- * source is ready for QOE data retrieval.
- */
- public interface OnQOEEventListener
- {
- /**
- * Key to identify type of QOE Event
- */
- public static final int ATTRIBUTES_QOE_EVENT_REG = 8004;
- public static final int ATTRIBUTES_QOE_EVENT_PLAY = 8005;
- public static final int ATTRIBUTES_QOE_EVENT_STOP = 8006;
- public static final int ATTRIBUTES_QOE_EVENT_SWITCH = 8007;
- public static final int ATTRIBUTES_QOE_EVENT_PERIODIC = 8008;
-
- /**
- * Called when attributes are available.
- *
- * @param attributekey the key identifying the type of attributes available
- * @param value the value for the attribute
- * @param mp the MediaPlayer to which QOE event is
- * applicable
- *
- */
- public void onQOEAttribute(int key, Parcel value,QCMediaPlayer mp);
- }
- /**
- * Register a callback to be invoked when QOE event happens
- * @param listener the callback that will be run
- */
- public void setOnQOEEventListener(OnQOEEventListener listener)
- {
- mOnQOEEventListener = listener;
- }
-
- private OnQOEEventListener mOnQOEEventListener;
- /* Do not change these values without updating their counterparts
- * in include/media/mediaplayer.h!
- */
- 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;
- private static final int MEDIA_QOE = 300;
-
-/* This sequence needs to be same as defined in NuPlayer.h*/
- private static final int QOEPlay = 1;
- private static final int QOEStop = 2;
- private static final int QOESwitch = 3;
- private static final int QOEPeriodic =4;
-
- /*enum QOEEvent{
- QOE,
- QOEPlay,
- QOEStop,
- QOESwitch,
- QOEPeriodic
- };*/
-
- /**
- * Key to query reposition range. Value needs to be same as defined in DashPlayer.h
- */
- public static final int KEY_DASH_REPOSITION_RANGE = 9000;
-
- /**
- * Keys for dash playback modes. Value needs to be same as defined in DashPlayer.h
- */
- public static final int KEY_DASH_SEEK_EVENT = 7001;
- public static final int KEY_DASH_PAUSE_EVENT = 7002;
- public static final int KEY_DASH_RESUME_EVENT = 7003;
-
- public static final int KEY_QCTIMEDTEXT_LISTENER = 6000;
-
- enum MediaPlayerState {
- PLAYER_IDLE,
- PLAYER_INITIALIZED
- };
-
- public MediaPlayerState ePlayerState;
-
- private class QCMediaEventHandler extends Handler
- {
- private QCMediaPlayer mQCMediaPlayer;
-
- public QCMediaEventHandler(QCMediaPlayer mp, Looper looper){
- super(looper);
- Log.d(TAG, "QCMediaEventHandler calling mp.mEventHandler.sendMessage()m");
- mQCMediaPlayer = mp;
- }
-
- public void handleMessage(Message msg)
- {
- Log.d(TAG, "QCMediaPlayer::QCMediaEventHandler::handleMessage");
- switch(msg.what)
- {
- case MEDIA_PREPARED:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_PREPARED calling callOnMPDAttributeListener");
- callOnMPDAttributeListener();
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_PREPARED calling callOnPreparedListener");
- callOnPreparedListener();
- return;
-
- case MEDIA_TIMED_TEXT:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_TIMED_TEXT");
- if(mOnQCTimedTextListener != null)
- {
- if (msg.obj instanceof Parcel) {
- Parcel parcel = (Parcel)msg.obj;
- QCTimedText text = new QCTimedText(parcel);
- callQCTimedTextListener(text);
- }
- }
- return;
-
- case MEDIA_QOE:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_QOE Received " + msg.arg2);
- if(mOnQOEEventListener != null)
- {
- if (msg.obj instanceof Parcel)
- {
- int key = 0;
- Parcel parcel = (Parcel)msg.obj;
- if(msg.arg2 == /*(int)QOEEvent.*/QOEPlay)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PLAY;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOEPeriodic)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PERIODIC;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOESwitch)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_SWITCH;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOEStop)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_STOP;
- }
- callOnQOEEventListener(key,parcel);
- }
- }
- return;
-
- default:
- Log.d(TAG, "Unknown message type " + msg.what);
- return;
- }
- }
- }
-
- /**
- * 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 QCMediaPlayer object so that the native
- * code is safe from the object disappearing from underneath it. (This is
- * the cookie passed to native_setup().)
- */
- private static void QCMediaPlayerNativeEventHandler(Object mediaplayer_ref,
- int what, int arg1, int arg2, Object obj)
- {
- Log.d(TAG, "QCMediaPlayerNativeEventHandler");
- QCMediaPlayer mp = (QCMediaPlayer)((WeakReference)mediaplayer_ref).get();
- if (mp == null)
- {
- Log.d(TAG, "QCMediaPlayerNativeEventHandler mp == null");
- return;
- }
- if (mp.mEventHandler != null)
- {
- Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
- Log.d(TAG, "QCMediaPlayerNativeEventHandler calling mp.mEventHandler.sendMessage()");
- mp.mEventHandler.sendMessage(m);
- }
- }
-
- private String QCgetStringParameter(int key)
- {
- if(!VALID_GET_PARAM_KEYS.contains(new Integer(key))) {
- Log.d(TAG, "QCgetStringParameter Unsupported key "+key+" Return null");
- return null;
- }
-
- Parcel request = newRequest();
- Parcel reply = Parcel.obtain();
- reply.setDataPosition(0);
- request.writeInt(key);
- invoke(request, reply);
- String ret = reply.readString();
- request.recycle();
- reply.recycle();
- return ret;
- }
-
- public boolean QCsetStringParameter(int key, String value) {
- boolean retval = false;
- Parcel request = newRequest();
- Parcel reply = Parcel.obtain();
- request.writeInt(key);
- request.writeString(value);
- invoke(request, reply);
- retval = reply.readInt() > 0 ? true : false;
- request.recycle();
- reply.recycle();
- return retval;
- }
-
- public boolean QCsetParameter(int key, int value) {
- boolean retval = false;
- Parcel request = newRequest();
- Parcel reply = Parcel.obtain();
- request.writeInt(key);
- request.writeInt(value);
- invoke(request, reply);
- retval = reply.readInt() > 0 ? true : false;
- request.recycle();
- reply.recycle();
- return retval;
- }
-
- public Parcel QCgetParcelParameter(int key) {
-
- if(!VALID_GET_PARAM_KEYS.contains(new Integer(key))) {
- Log.d(TAG, "QCgetParcelParameter Unsupported key "+key+" Return null");
- return null;
- }
- Parcel request = newRequest();
- Parcel reply = Parcel.obtain();
- request.writeInt(key);
- invoke(request, reply);
- request.recycle();
- return reply;
- }
-}
diff --git a/QCMediaPlayer/com/qualcomm/qcmedia/QCMediaPlayer.java b/QCMediaPlayer/com/qualcomm/qcmedia/QCMediaPlayer.java
deleted file mode 100644
index 432abf3e..00000000
--- a/QCMediaPlayer/com/qualcomm/qcmedia/QCMediaPlayer.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * File: QCMediaPlayer.java
- * Description: Snapdragon SDK for Android support class.
- * Provides access to QC-provided MediaPlayer APIs and interfaces
-
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Copyright (C) 2006 The Android Open Source Project
- *
- * 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 com.qualcomm.qcmedia;
-
-import android.media.MediaPlayer;
-import android.util.Log;
-import android.media.TimedText;
-import java.lang.ref.WeakReference;
-import java.io.*;
-import com.qualcomm.qcmedia.QCTimedText;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-
-/**
-* QCMediaPlayer extends MediaPlayer from package android.media and provides
-* extended APIs and interfaces to get and set MPD attributes for DASH protocol
-* in compatible Snapdragon builds.
-*{@hide}
-*/
-
-public class QCMediaPlayer extends MediaPlayer
-{
- private final static String TAG = "QCMediaPlayer";
- private QCMediaEventHandler mEventHandler;
-
- public QCMediaPlayer()
- {
- super();
- Looper looper;
- if ((looper = Looper.myLooper()) != null)
- {
- mEventHandler = new QCMediaEventHandler(this, looper);
- }
- else if ((looper = Looper.getMainLooper()) != null)
- {
- mEventHandler = new QCMediaEventHandler(this, looper);
- }
- else
- {
- mEventHandler = null;
- }
- Log.d(TAG, "QCMediaPlayer::QCMediaPlayer");
- }
-
- private void callOnPreparedListener()
- {
- Log.d(TAG, "callOnPreparedListener");
- if (mQCOnPreparedListener != null)
- mQCOnPreparedListener.onPrepared(this);
- }
-
- private void callOnMPDAttributeListener()
- {
- Log.d(TAG, "callOnMPDAttributeListener");
- String mpdAttributes = getStringParameter(OnMPDAttributeListener.ATTRIBUTES_TYPE_MPD);
- if (mOnMPDAttributeListener != null)
- mOnMPDAttributeListener.onMPDAttribute(OnMPDAttributeListener.ATTRIBUTES_TYPE_MPD, mpdAttributes, this);
- }
- private void callQCTimedTextListener(QCTimedText text)
- {
- if(mOnQCTimedTextListener != null)
- {
- mOnQCTimedTextListener.onQCTimedText(this, text);
- }
- }
- private void callOnQOEEventListener(int key,Parcel parcel)
- {
- Log.d(TAG, "callOnQOEEventListener");
- if (mOnQOEEventListener != null)
- {
- mOnQOEEventListener.onQOEAttribute(key,parcel,this);
- }
- }
-
- /**
- * Additional propreitary interface definition of a callback to be invoked
- * when a Qtimed text is available for display.
- * {@hide}
- */
- public interface OnQCTimedTextListener
- {
- /**
- * Called to indicate an avaliable timed text
- *
- * @param mp the QCMediaPlayer associated with this
- * callback
- * @param text the Qtimed text sample which contains the text
- * needed to be displayed and the display format.
- * {@hide}
- */
- public void onQCTimedText(QCMediaPlayer mp, QCTimedText text);
- }
-
- /**
- * Register a callback to be invoked when a Qtimed text is available
- * for display.
- *
- * @param listener the callback that will be run
- * {@hide}
- */
- public void setOnQCTimedTextListener(OnQCTimedTextListener listener)
- {
- mOnQCTimedTextListener = listener;
- }
- private OnQCTimedTextListener mOnQCTimedTextListener;
-
- /**
- * Register a callback to be invoked when the media source is ready
- * for playback.
- *
- * @param listener the callback that will be run
- */
- public void setOnPreparedListener(OnPreparedListener listener)
- {
- mQCOnPreparedListener = listener;
- Log.d(TAG, "QCMediaPlayer::setOnPreparedListener");
- }
- private OnPreparedListener mQCOnPreparedListener;
-
- /**
- * Interface definition for a callback to be invoked when the media
- * source is ready for MPD attribute retrieval
- */
- public interface OnMPDAttributeListener
- {
- /**
- * Key to identify type of MPD attributes
- */
- public static final int ATTRIBUTES_TYPE_MPD = 8002;
- /**
- * Key to be used to retrieve complete MPD.
- */
- public static final int ATTRIBUTES_WHOLE_MPD = 8003;
- /**
- * Called when attributes are available.
- *
- * @param attributekey the key identifying the type of attributes available
- * @param value the value for the attribute
- * @param mp the MediaPlayer to which MPD attribute is applicable
- *
- */
- public void onMPDAttribute(int attributekey, String value, QCMediaPlayer mp);
- }
-
- /**
- * Register a callback to be invoked when MPD attributes are avaialble
- *
- * @param listener the callback that will be run
- */
- public void setOnMPDAttributeListener(OnMPDAttributeListener listener)
- {
- mOnMPDAttributeListener = listener;
- }
-
- private OnMPDAttributeListener mOnMPDAttributeListener;
-
- /**
- * Process the parameter indicated by key.
- * @param key the key idicated the parameter to be processed
- * @param value the value for the parameter identified by key
- * @return true if successful in processing the parameter else returns false
- * @see OnMPDAttributeListener the interface for valid keys to be used
- *
- */
- public boolean processMPDAttribute(int key, String value)
- {
- return setParameter(key, value);
- }
- public String QCGetParameter(int key)
- {
- return getStringParameter(key);
- }
- public Parcel QCPeriodicParameter(int key)
- {
- if(key == mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PERIODIC)
- {
- Log.d(TAG, "QCMediaPlayer : QCGetParameter(int key , Parcel& data)");
- return getParcelParameter(key);
- }
- return null;
- }
- public boolean QCSetParameter(int key, int value)
- {
- Log.d(TAG, "QCMediaPlayer : QCSetParameter");
- return setParameter(key, value);
- }
- /**
- * Interface definition for a callback to be invoked when the media
- * source is ready for QOE data retrieval.
- */
- public interface OnQOEEventListener
- {
- /**
- * Key to identify type of QOE Event
- */
- public static final int ATTRIBUTES_QOE_EVENT_REG = 8004;
- public static final int ATTRIBUTES_QOE_EVENT_PLAY = 8005;
- public static final int ATTRIBUTES_QOE_EVENT_STOP = 8006;
- public static final int ATTRIBUTES_QOE_EVENT_SWITCH = 8007;
- public static final int ATTRIBUTES_QOE_EVENT_PERIODIC = 8008;
-
- /**
- * Called when attributes are available.
- *
- * @param attributekey the key identifying the type of attributes available
- * @param value the value for the attribute
- * @param mp the MediaPlayer to which QOE event is
- * applicable
- *
- */
- public void onQOEAttribute(int key, Parcel value,QCMediaPlayer mp);
- }
- /**
- * Register a callback to be invoked when QOE event happens
- * @param listener the callback that will be run
- */
- public void setOnQOEEventListener(OnQOEEventListener listener)
- {
- mOnQOEEventListener = listener;
- }
-
- private OnQOEEventListener mOnQOEEventListener;
- /* Do not change these values without updating their counterparts
- * in include/media/mediaplayer.h!
- */
- 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;
- private static final int MEDIA_QOE = 300;
-
-/* This sequence needs to be same as defined in NuPlayer.h*/
- private static final int QOEPlay = 1;
- private static final int QOEStop = 2;
- private static final int QOESwitch = 3;
- private static final int QOEPeriodic =4;
-
- /*enum QOEEvent{
- QOE,
- QOEPlay,
- QOEStop,
- QOESwitch,
- QOEPeriodic
- };*/
-
- private class QCMediaEventHandler extends Handler
- {
- private QCMediaPlayer mQCMediaPlayer;
-
- public QCMediaEventHandler(QCMediaPlayer mp, Looper looper){
- super(looper);
- Log.d(TAG, "QCMediaEventHandler calling mp.mEventHandler.sendMessage()m");
- mQCMediaPlayer = mp;
- }
-
- public void handleMessage(Message msg)
- {
- Log.d(TAG, "QCMediaPlayer::QCMediaEventHandler::handleMessage");
- switch(msg.what)
- {
- case MEDIA_PREPARED:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_PREPARED calling callOnMPDAttributeListener");
- callOnMPDAttributeListener();
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_PREPARED calling callOnPreparedListener");
- callOnPreparedListener();
- return;
-
- case MEDIA_TIMED_TEXT:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_TIMED_TEXT");
- if(mOnQCTimedTextListener != null)
- {
- if (msg.obj instanceof Parcel) {
- Parcel parcel = (Parcel)msg.obj;
- QCTimedText text = new QCTimedText(parcel);
- callQCTimedTextListener(text);
- }
- }
- return;
-
- case MEDIA_QOE:
- Log.d(TAG, "QCMediaEventHandler::handleMessage::MEDIA_QOE Received " + msg.arg2);
- if(mOnQOEEventListener != null)
- {
- if (msg.obj instanceof Parcel)
- {
- int key = 0;
- Parcel parcel = (Parcel)msg.obj;
- if(msg.arg2 == /*(int)QOEEvent.*/QOEPlay)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PLAY;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOEPeriodic)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_PERIODIC;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOESwitch)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_SWITCH;
- }else if(msg.arg2 == /*(int)QOEEvent.*/QOEStop)
- {
- key = mOnQOEEventListener.ATTRIBUTES_QOE_EVENT_STOP;
- }
- callOnQOEEventListener(key,parcel);
- }
- }
- return;
-
- default:
- Log.d(TAG, "Unknown message type " + msg.what);
- return;
- }
- }
- }
-
- /**
- * 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 QCMediaPlayer object so that the native
- * code is safe from the object disappearing from underneath it. (This is
- * the cookie passed to native_setup().)
- */
- private static void QCMediaPlayerNativeEventHandler(Object mediaplayer_ref,
- int what, int arg1, int arg2, Object obj)
- {
- Log.d(TAG, "QCMediaPlayerNativeEventHandler");
- QCMediaPlayer mp = (QCMediaPlayer)((WeakReference)mediaplayer_ref).get();
- if (mp == null)
- {
- Log.d(TAG, "QCMediaPlayerNativeEventHandler mp == null");
- return;
- }
- if (mp.mEventHandler != null)
- {
- Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
- Log.d(TAG, "QCMediaPlayerNativeEventHandler calling mp.mEventHandler.sendMessage()");
- mp.mEventHandler.sendMessage(m);
- }
- }
-}
diff --git a/QCMediaPlayer/com/qualcomm/qcmedia/QCTimedText.java b/QCMediaPlayer/com/qualcomm/qcmedia/QCTimedText.java
deleted file mode 100644
index ef092c21..00000000
--- a/QCMediaPlayer/com/qualcomm/qcmedia/QCTimedText.java
+++ /dev/null
@@ -1,801 +0,0 @@
-/*
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- */
-
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * 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.
- */
-
-/*
- * File: QCTimedText.java
- * Description: Snapdragon SDK for Android support class.
- * Provides access to QC-provided TimedText APIs and interfaces
- *
- */
-package com.qualcomm.qcmedia;
-
-import android.media.MediaPlayer;
-import android.util.Log;
-
-import android.os.Parcel;
-import android.util.Log;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Class to hold the timed text's metadata.
- * It holds local settings(per sample) as well as global settings.
- *
- * {@hide}
- */
-public class QCTimedText
-{
- private static final int FIRST_PUBLIC_KEY = 1;
-
- // These keys must be in sync with the keys in TextDescription.h
- public static final int KEY_DISPLAY_FLAGS = 1; // int
- public static final int KEY_STYLE_FLAGS = 2; // int
- public static final int KEY_BACKGROUND_COLOR_RGBA = 3; // int
- public static final int KEY_HIGHLIGHT_COLOR_RGBA = 4; // int
- public static final int KEY_SCROLL_DELAY = 5; // int
- public static final int KEY_WRAP_TEXT = 6; // int
- public static final int KEY_START_TIME = 7; // int
- public static final int KEY_STRUCT_BLINKING_TEXT_LIST = 8; // List<CharPos>
- public static final int KEY_STRUCT_FONT_LIST = 9; // List<Font>
- public static final int KEY_STRUCT_HIGHLIGHT_LIST = 10; // List<CharPos>
- public static final int KEY_STRUCT_HYPER_TEXT_LIST = 11; // List<HyperText>
- public static final int KEY_STRUCT_KARAOKE_LIST = 12; // List<Karaoke>
- public static final int KEY_STRUCT_STYLE_LIST = 13; // List<Style>
- public static final int KEY_STRUCT_TEXT_POS = 14; // TextPos
- public static final int KEY_STRUCT_JUSTIFICATION = 15; // Justification
- public static final int KEY_STRUCT_TEXT = 16; // Text
- public static final int KEY_HEIGHT = 17;
- public static final int KEY_WIDTH = 18;
- public static final int KEY_DURATION = 19;
- public static final int KEY_START_OFFSET = 20;
- public static final int KEY_SUBS_ATOM = 21;
- //The type of text - SMPTE, CEA, WebVTT, SRT or Unknown
- public static final int KEY_TEXT_FORMAT = 22;
-
- private static final int LAST_PUBLIC_KEY = 22;
-
- private static final int FIRST_PRIVATE_KEY = 101;
-
- // The following keys are used between QCTimedText.java and
- // TextDescription.cpp in order to parce the Parcel.
- private static final int KEY_GLOBAL_SETTING = 101;
- private static final int KEY_LOCAL_SETTING = 102;
- private static final int KEY_START_CHAR = 103;
- private static final int KEY_END_CHAR = 104;
- private static final int KEY_FONT_ID = 105;
- private static final int KEY_FONT_SIZE = 106;
- private static final int KEY_TEXT_COLOR_RGBA = 107;
- private static final int KEY_TEXT_EOS = 108;
- private static final int KEY_TEXT_FLAG_TYPE = 109;
- private static final int KEY_TEXT_DISCONTINUITY = 110;
- private static final int LAST_PRIVATE_KEY = 110;
-
-
- private static final String TAG = "QCTimedText";
-
- private final HashMap<Integer, Object> mKeyObjectMap =
- new HashMap<Integer, Object>();
-
- private int mDisplayFlags = -1;
- private int mBackgroundColorRGBA = -1;
- private int mHighlightColorRGBA = -1;
- private int mScrollDelay = -1;
- private int mWrapText = -1;
-
- private List<CharPos> mBlinkingPosList = null;
- private List<CharPos> mHighlightPosList = null;
- private List<Karaoke> mKaraokeList = null;
- private List<Font> mFontList = null;
- private List<Style> mStyleList = null;
- private List<HyperText> mHyperTextList = null;
-
- private TextPos mTextPos;
- private Justification mJustification;
- private Text mTextStruct;
- private SubsAtom mSubsAtomStruct;
-
- /**
- * Helper class to hold the text length and text content of
- * one text sample. The member variables in this class are
- * read-only.
- */
- public class Text {
-
- public static final int TIMED_TEXT_FLAG_FRAME = 0; // int
- public static final int TIMED_TEXT_FLAG_CODEC_CONFIG = 1; // int
- public static final int TIMED_TEXT_FLAG_EOS = 2; // int
-
- /**
- * The byte-count of this text sample
- */
- public int textLen;
- /**
- * The flags associated with frame
- */
- public int flags;
- /**
- * The discontinuity in samples
- */
- public boolean discontinuity = false;
-
- /**
- * The text sample
- */
- public byte[] text;
-
- public Text() { }
- }
-
- /**
- * Helper class to hold the start char offset and end char offset
- * for Blinking Text or Highlight Text. endChar is the end offset
- * of the text (startChar + number of characters to be highlighted
- * or blinked). The member variables in this class are read-only.
- */
- public class CharPos {
- /**
- * The offset of the start character
- */
- public int startChar = -1;
-
- /**
- * The offset of the end character
- */
- public int endChar = -1;
-
- public CharPos() { }
- }
-
- /**
- * Helper class to hold the box position to display the text sample.
- * The member variables in this class are read-only.
- */
- public class TextPos {
- /**
- * The top position of the text
- */
- public int top = -1;
-
- /**
- * The left position of the text
- */
- public int left = -1;
-
- /**
- * The bottom position of the text
- */
- public int bottom = -1;
-
- /**
- * The right position of the text
- */
- public int right = -1;
-
- public TextPos() { }
- }
-
- /**
- * Helper class to hold the justification for text display in the text box.
- * The member variables in this class are read-only.
- */
- public class Justification {
- /**
- * horizontalJustification 0: left, 1: centered, -1: right
- */
- public int horizontalJustification = -1;
-
- /**
- * verticalJustification 0: top, 1: centered, -1: bottom
- */
- public int verticalJustification = -1;
-
- public Justification() { }
- }
-
- /**
- * Helper class to hold the style information to display the text.
- * The member variables in this class are read-only.
- */
- public class Style {
- /**
- * The offset of the start character which applys this style
- */
- public int startChar = -1;
-
- /**
- * The offset of the end character which applys this style
- */
- public int endChar = -1;
-
- /**
- * ID of the font. This ID will be used to choose the font
- * to be used from the font list.
- */
- public int fontID = -1;
-
- /**
- * True if the characters should be bold
- */
- public boolean isBold = false;
-
- /**
- * True if the characters should be italic
- */
- public boolean isItalic = false;
-
- /**
- * True if the characters should be underlined
- */
- public boolean isUnderlined = false;
-
- /**
- * The size of the font
- */
- public int fontSize = -1;
-
- /**
- * To specify the RGBA color: 8 bits each of red, green, blue,
- * and an alpha(transparency) value
- */
- public int colorRGBA = -1;
-
- public Style() { }
- }
-
- /**
- * Helper class to hold the font ID and name.
- * The member variables in this class are read-only.
- */
- public class Font {
- /**
- * The font ID
- */
- public int ID = -1;
-
- /**
- * The font name
- */
- public String name;
-
- public Font() { }
- }
-
- /**
- * Helper class to hold the karaoke information.
- * The member variables in this class are read-only.
- */
- public class Karaoke {
- /**
- * The start time (in milliseconds) to highlight the characters
- * specified by startChar and endChar.
- */
- public int startTimeMs = -1;
-
- /**
- * The end time (in milliseconds) to highlight the characters
- * specified by startChar and endChar.
- */
- public int endTimeMs = -1;
-
- /**
- * The offset of the start character to be highlighted
- */
- public int startChar = -1;
-
- /**
- * The offset of the end character to be highlighted
- */
- public int endChar = -1;
-
- public Karaoke() { }
- }
-
- /**
- * Helper class to hold the hyper text information.
- * The member variables in this class are read-only.
- */
- public class HyperText {
- /**
- * The offset of the start character
- */
- public int startChar = -1;
-
- /**
- * The offset of the end character
- */
- public int endChar = -1;
-
- /**
- * The linked-to URL
- */
- public String URL;
-
- /**
- * The "alt" string for user display
- */
- public String altString;
-
- public HyperText() { }
- }
-
- /* Subs Atom*/
- public class SubsAtom {
- /**
- * The byte-count of this subs
- */
- public int subsAtomLen;
-
- /**
- * The subs data
- */
- public byte[] subsAtomData;
-
- public SubsAtom () { }
- }
-
- /**
- * @param obj the byte array which contains the timed text.
- * @throws IllegalArgumentExcept if parseParcel() fails.
- * {@hide}
- */
- public QCTimedText(Parcel mParcel) {
-
- if (!parseParcel(mParcel)) {
- mKeyObjectMap.clear();
- throw new IllegalArgumentException("parseParcel() fails");
- }
- }
-
- /**
- * Go over all the records, collecting metadata keys and fields in the
- * Parcel. These are stored in mKeyObjectMap for application to retrieve.
- * @return false if an error occurred during parsing. Otherwise, true.
- */
- private boolean parseParcel(Parcel mParcel) {
- mParcel.setDataPosition(0);
- if (mParcel.dataAvail() == 0) {
- Log.e(TAG, "Invalid mParcel.dataAvail()");
- return false;
- }
-
- int type = mParcel.readInt();
-
- if (type == KEY_LOCAL_SETTING) {
-
- mTextStruct = new Text();
-
- //PARSE TIMEDTEXT SAMPLE TYPE
- type = mParcel.readInt();
- if (type != KEY_TEXT_FORMAT) {
- Log.e(TAG, "Invalid KEY_TEXT_FORMAT key");
- return false;
- }
-
- String format = mParcel.readString();
- mKeyObjectMap.put(type, format);
-
- //PARSE TIMEDTEXT SAMPLE FLAGS
- type = mParcel.readInt();
- if (type != KEY_TEXT_FLAG_TYPE) {
- Log.e(TAG, "Invalid KEY_TEXT_FLAG_TYPE key");
- return false;
- }
-
- type = mParcel.readInt();
- if (type == Text.TIMED_TEXT_FLAG_EOS)
- {
- mTextStruct.flags = type;
- mTextStruct.textLen = 0; //Zero length buffer in case of EOS
- mKeyObjectMap.put(KEY_STRUCT_TEXT, mTextStruct);
- mKeyObjectMap.put(KEY_START_TIME, 0);
- mKeyObjectMap.put(KEY_HEIGHT, 0);
- mKeyObjectMap.put(KEY_WIDTH, 0);
- mKeyObjectMap.put(KEY_DURATION, 0);
- mKeyObjectMap.put(KEY_START_OFFSET, 0);
-
- return true;
- }
-
- if(type != Text.TIMED_TEXT_FLAG_FRAME && type != Text.TIMED_TEXT_FLAG_CODEC_CONFIG) {
- Log.e(TAG, "Invalid TIMED_TEXT_FLAG_FRAME key");
- return false;
- }
- mTextStruct.flags = type;
-
- type = mParcel.readInt();
- if(type == KEY_TEXT_DISCONTINUITY) {
- mTextStruct.discontinuity = true;
- type = mParcel.readInt();
- }
-
- //PARSE TIMEDTEXT SAMPLE TEXT DATA
- if (type != KEY_STRUCT_TEXT) {
- Log.e(TAG, "Invalid KEY_STRUCT_TEXT key");
- return false;
- }
-
- mTextStruct.textLen = mParcel.readInt();
- mTextStruct.text = mParcel.createByteArray();
-
- mKeyObjectMap.put(type, mTextStruct);
-
- //PARSE TIMEDTEXT SAMPLE PROPERTIES
- type = mParcel.readInt();
- if (type != KEY_START_TIME) {
- Log.e(TAG, "Invalid KEY_START_TIME key");
- return false;
- }
- int mStartTimeMs = mParcel.readInt();
- mKeyObjectMap.put(type, mStartTimeMs);
-
- } else if (type != KEY_GLOBAL_SETTING) {
- Log.e(TAG, "Invalid timed text key found: " + type);
- return false;
- }
-
- while (mParcel.dataAvail() > 0) {
- int key = mParcel.readInt();
- if (!isValidKey(key)) {
- Log.w(TAG, "Invalid timed text key found: " + key);
- return false;
- }
-
- Object object = null;
-
- switch (key) {
- case KEY_HEIGHT: {
- int mHeight = mParcel.readInt();
- Log.e(TAG, "mHeight: " + mHeight);
- mKeyObjectMap.put(key, mHeight);
- break;
- }
-
- case KEY_WIDTH: {
- int mWidth = mParcel.readInt();
- Log.e(TAG, "mWidth: " + mWidth);
- mKeyObjectMap.put(key, mWidth);
- break;
- }
-
- case KEY_DURATION: {
- int mDuration = mParcel.readInt();
- Log.e(TAG, "mDuration: " + mDuration);
- mKeyObjectMap.put(key, mDuration);
- break;
- }
-
- case KEY_START_OFFSET: {
- int mStartOffset = mParcel.readInt();
- Log.e(TAG, "mStartOffset: " + mStartOffset);
- mKeyObjectMap.put(key, mStartOffset);
- break;
- }
-
- //Parse SubsAtom
- case KEY_SUBS_ATOM: {
- mSubsAtomStruct = new SubsAtom();
- mSubsAtomStruct.subsAtomLen = mParcel.readInt();
- mSubsAtomStruct.subsAtomData = mParcel.createByteArray();
- mKeyObjectMap.put(key, mSubsAtomStruct);
- break;
- }
-
- case KEY_STRUCT_STYLE_LIST: {
- readStyle(mParcel);
- object = mStyleList;
- break;
- }
- case KEY_STRUCT_FONT_LIST: {
- readFont(mParcel);
- object = mFontList;
- break;
- }
- case KEY_STRUCT_HIGHLIGHT_LIST: {
- readHighlight(mParcel);
- object = mHighlightPosList;
- break;
- }
- case KEY_STRUCT_KARAOKE_LIST: {
- readKaraoke(mParcel);
- object = mKaraokeList;
- break;
- }
- case KEY_STRUCT_HYPER_TEXT_LIST: {
- readHyperText(mParcel);
- object = mHyperTextList;
-
- break;
- }
- case KEY_STRUCT_BLINKING_TEXT_LIST: {
- readBlinkingText(mParcel);
- object = mBlinkingPosList;
-
- break;
- }
- case KEY_WRAP_TEXT: {
- mWrapText = mParcel.readInt();
- object = mWrapText;
- break;
- }
- case KEY_HIGHLIGHT_COLOR_RGBA: {
- mHighlightColorRGBA = mParcel.readInt();
- object = mHighlightColorRGBA;
- break;
- }
- case KEY_DISPLAY_FLAGS: {
- mDisplayFlags = mParcel.readInt();
- object = mDisplayFlags;
- break;
- }
- case KEY_STRUCT_JUSTIFICATION: {
- mJustification = new Justification();
-
- mJustification.horizontalJustification = mParcel.readInt();
- mJustification.verticalJustification = mParcel.readInt();
-
- object = mJustification;
- break;
- }
- case KEY_BACKGROUND_COLOR_RGBA: {
- mBackgroundColorRGBA = mParcel.readInt();
- object = mBackgroundColorRGBA;
- break;
- }
- case KEY_STRUCT_TEXT_POS: {
- mTextPos = new TextPos();
-
- mTextPos.top = mParcel.readInt();
- mTextPos.left = mParcel.readInt();
- mTextPos.bottom = mParcel.readInt();
- mTextPos.right = mParcel.readInt();
-
- object = mTextPos;
- break;
- }
- case KEY_SCROLL_DELAY: {
- mScrollDelay = mParcel.readInt();
- object = mScrollDelay;
- break;
- }
- default: {
- break;
- }
- }
-
- if (object != null) {
- if (mKeyObjectMap.containsKey(key)) {
- mKeyObjectMap.remove(key);
- }
- mKeyObjectMap.put(key, object);
- }
- }
-
- return true;
- }
-
- /**
- * To parse and store the Style list.
- */
- private void readStyle(Parcel mParcel) {
- Style style = new Style();
- boolean endOfStyle = false;
-
- while (!endOfStyle && (mParcel.dataAvail() > 0)) {
- int key = mParcel.readInt();
- switch (key) {
- case KEY_START_CHAR: {
- style.startChar = mParcel.readInt();
- break;
- }
- case KEY_END_CHAR: {
- style.endChar = mParcel.readInt();
- break;
- }
- case KEY_FONT_ID: {
- style.fontID = mParcel.readInt();
- break;
- }
- case KEY_STYLE_FLAGS: {
- int flags = mParcel.readInt();
- // In the absence of any bits set in flags, the text
- // is plain. Otherwise, 1: bold, 2: italic, 4: underline
- style.isBold = ((flags % 2) == 1);
- style.isItalic = ((flags % 4) >= 2);
- style.isUnderlined = ((flags / 4) == 1);
- break;
- }
- case KEY_FONT_SIZE: {
- style.fontSize = mParcel.readInt();
- break;
- }
- case KEY_TEXT_COLOR_RGBA: {
- style.colorRGBA = mParcel.readInt();
- break;
- }
- default: {
- // End of the Style parsing. Reset the data position back
- // to the position before the last mParcel.readInt() call.
- mParcel.setDataPosition(mParcel.dataPosition() - 4);
- endOfStyle = true;
- break;
- }
- }
- }
-
- if (mStyleList == null) {
- mStyleList = new ArrayList<Style>();
- }
- mStyleList.add(style);
- }
-
- /**
- * To parse and store the Font list
- */
- private void readFont(Parcel mParcel) {
- int entryCount = mParcel.readInt();
-
- for (int i = 0; i < entryCount; i++) {
- Font font = new Font();
-
- font.ID = mParcel.readInt();
- int nameLen = mParcel.readInt();
-
- byte[] text = mParcel.createByteArray();
- font.name = new String(text, 0, nameLen);
-
- if (mFontList == null) {
- mFontList = new ArrayList<Font>();
- }
- mFontList.add(font);
- }
- }
-
- /**
- * To parse and store the Highlight list
- */
- private void readHighlight(Parcel mParcel) {
- CharPos pos = new CharPos();
-
- pos.startChar = mParcel.readInt();
- pos.endChar = mParcel.readInt();
-
- if (mHighlightPosList == null) {
- mHighlightPosList = new ArrayList<CharPos>();
- }
- mHighlightPosList.add(pos);
- }
-
- /**
- * To parse and store the Karaoke list
- */
- private void readKaraoke(Parcel mParcel) {
- int entryCount = mParcel.readInt();
-
- for (int i = 0; i < entryCount; i++) {
- Karaoke kara = new Karaoke();
-
- kara.startTimeMs = mParcel.readInt();
- kara.endTimeMs = mParcel.readInt();
- kara.startChar = mParcel.readInt();
- kara.endChar = mParcel.readInt();
-
- if (mKaraokeList == null) {
- mKaraokeList = new ArrayList<Karaoke>();
- }
- mKaraokeList.add(kara);
- }
- }
-
- /**
- * To parse and store HyperText list
- */
- private void readHyperText(Parcel mParcel) {
- HyperText hyperText = new HyperText();
-
- hyperText.startChar = mParcel.readInt();
- hyperText.endChar = mParcel.readInt();
-
- int len = mParcel.readInt();
- byte[] url = mParcel.createByteArray();
- hyperText.URL = new String(url, 0, len);
-
- len = mParcel.readInt();
- byte[] alt = mParcel.createByteArray();
- hyperText.altString = new String(alt, 0, len);
-
- if (mHyperTextList == null) {
- mHyperTextList = new ArrayList<HyperText>();
- }
- mHyperTextList.add(hyperText);
- }
-
- /**
- * To parse and store blinking text list
- */
- private void readBlinkingText(Parcel mParcel) {
- CharPos blinkingPos = new CharPos();
-
- blinkingPos.startChar = mParcel.readInt();
- blinkingPos.endChar = mParcel.readInt();
-
- if (mBlinkingPosList == null) {
- mBlinkingPosList = new ArrayList<CharPos>();
- }
- mBlinkingPosList.add(blinkingPos);
- }
-
- /**
- * To check whether the given key is valid.
- * @param key the key to be checked.
- * @return true if the key is a valid one. Otherwise, false.
- */
- public boolean isValidKey(final int key) {
- if (!((key >= FIRST_PUBLIC_KEY) && (key <= LAST_PUBLIC_KEY))
- && !((key >= FIRST_PRIVATE_KEY) && (key <= LAST_PRIVATE_KEY))) {
- return false;
- }
- return true;
- }
-
- /**
- * To check whether the given key is contained in this QCTimedText object.
- * @param key the key to be checked.
- * @return true if the key is contained in this QCTimedText object.
- * Otherwise, false.
- */
- public boolean containsKey(final int key) {
- if (isValidKey(key) && mKeyObjectMap.containsKey(key)) {
- return true;
- }
- return false;
- }
- /**
- * @return a set of the keys contained in this QCTimedText object.
- */
- public Set keySet() {
- return mKeyObjectMap.keySet();
- }
-
- /**
- * To retrieve the object associated with the key. Caller must make sure
- * the key is present using the containsKey method otherwise a
- * RuntimeException will occur.
- * @param key the key used to retrieve the object.
- * @return an object. The object could be an instanceof Integer, List, or
- * any of the helper classes such as TextPos, Justification, and Text.
- */
- public Object getObject(final int key) {
- if (containsKey(key)) {
- return mKeyObjectMap.get(key);
- }
- return null;
-/*
- //!Warning : Not Sure if to throw an exception or return null , return null is good option
- else {
- throw new IllegalArgumentException("Invalid key: " + key);
- }
-*/
- }
-}
diff --git a/dashplayer/Android.mk b/dashplayer/Android.mk
deleted file mode 100644
index acf9a7a7..00000000
--- a/dashplayer/Android.mk
+++ /dev/null
@@ -1,60 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# ---------------------------------------------------------------------------------
-# Common definitons
-# ---------------------------------------------------------------------------------
-LOCAL_SRC_FILES:= \
- DashPlayer.cpp \
- DashPlayerDriver.cpp \
- DashPlayerRenderer.cpp \
- DashPlayerStats.cpp \
- DashPlayerDecoder.cpp \
- DashPacketSource.cpp \
- DashFactory.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- libcamera_client \
- libcutils \
- libdl \
- libgui \
- libmedia \
- libstagefright \
- libstagefright_foundation \
- libstagefright_omx \
- libutils \
- libui \
-
-LOCAL_C_INCLUDES := \
- $(TOP)/frameworks/av/media/libstagefright/timedtext \
- $(TOP)/frameworks/native/include/media/hardware \
- $(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/av/media/libstagefright/httplive \
- $(TOP)/frameworks/av/media/libmediaplayerservice/nuplayer \
- $(TOP)/frameworks/av/media/libmediaplayerservice \
- $(TOP)/frameworks/av/media/libstagefright/include \
- $(TOP)/frameworks/av/media/libstagefright/mpeg2ts \
- $(TOP)/frameworks/av/media/libstagefright/rtsp \
- $(TOP)/$(call project-path-for,qcom-media)/mm-core/inc \
- $(TOP)/$(call project-path-for,qcom-display)/libgralloc \
- $(LOCAL_PATH)/../QCMediaPlayer/native \
- $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
-
-ifeq ($(PLATFORM_SDK_VERSION), 18)
- LOCAL_CFLAGS += -DANDROID_JB_MR2
-endif
-
-
-LOCAL_MODULE:= libdashplayer
-
-LOCAL_MODULE_TAGS := eng
-
-ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS), true)
-ifndef TARGET_DISABLE_DASH
- include $(BUILD_SHARED_LIBRARY)
-endif
-endif
-
diff --git a/dashplayer/DashCodec.cpp b/dashplayer/DashCodec.cpp
deleted file mode 100644
index c8db281d..00000000
--- a/dashplayer/DashCodec.cpp
+++ /dev/null
@@ -1,4671 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DashCodec"
-
-#include "DashCodec.h"
-#include "QCMediaDefs.h"
-
-#include <binder/MemoryDealer.h>
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <media/stagefright/MediaCodecList.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/NativeWindowWrapper.h>
-#include <media/stagefright/OMXClient.h>
-#include <media/stagefright/OMXCodec.h>
-
-#include <media/hardware/HardwareAPI.h>
-#include <OMX_QCOMExtns.h>
-#include <OMX_Component.h>
-#include <cutils/properties.h>
-#include "avc_utils.h"
-
-#ifdef BFAMILY_TARGET /* Venus macros and dynamic mode support present only for B-family targets.*/
-#include <media/msm_media_info.h>
-#endif
-
-//Smmoth streaming settings
-//Max resolution 1080p
-#define MAX_WIDTH 1920
-#define MAX_HEIGHT 1080
-
-//Min resolution QVGA
-#define MIN_WIDTH 480
-#define MIN_HEIGHT 320
-
-#define MAX_SUPPORTED_BUF_SZ (((MAX_WIDTH * MAX_HEIGHT)*3/2)/2)
-// Alignment Macro
-#define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
-#define SZ_4K 0x1000
-
-namespace android {
-
-template<class T>
-static void InitOMXParams(T *params) {
- params->nSize = sizeof(T);
- params->nVersion.s.nVersionMajor = 1;
- params->nVersion.s.nVersionMinor = 0;
- params->nVersion.s.nRevision = 0;
- params->nVersion.s.nStep = 0;
-}
-
-struct CodecObserver : public BnOMXObserver {
- CodecObserver() {}
-
- void setNotificationMessage(const sp<AMessage> &msg) {
- mNotify = msg;
- }
-
- // from IOMXObserver
- virtual void onMessage(const omx_message &omx_msg) {
- sp<AMessage> msg = mNotify->dup();
-
- msg->setInt32("type", omx_msg.type);
- msg->setInt32("node", omx_msg.node);
-
- switch (omx_msg.type) {
- case omx_message::EVENT:
- {
- msg->setInt32("event", omx_msg.u.event_data.event);
- msg->setInt32("data1", omx_msg.u.event_data.data1);
- msg->setInt32("data2", omx_msg.u.event_data.data2);
- break;
- }
-
- case omx_message::EMPTY_BUFFER_DONE:
- {
- msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
- break;
- }
-
- case omx_message::FILL_BUFFER_DONE:
- {
- msg->setInt32(
- "buffer", omx_msg.u.extended_buffer_data.buffer);
- msg->setInt32(
- "range_offset",
- omx_msg.u.extended_buffer_data.range_offset);
- msg->setInt32(
- "range_length",
- omx_msg.u.extended_buffer_data.range_length);
- msg->setInt32(
- "flags",
- omx_msg.u.extended_buffer_data.flags);
- msg->setInt64(
- "timestamp",
- omx_msg.u.extended_buffer_data.timestamp);
- //msg->setPointer(
- // "platform_private",
- // omx_msg.u.extended_buffer_data.platform_private);
- //msg->setPointer(
- // "data_ptr",
- // omx_msg.u.extended_buffer_data.data_ptr);
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-
- msg->post();
- }
-
-protected:
- virtual ~CodecObserver() {}
-
-private:
- sp<AMessage> mNotify;
-
- DISALLOW_EVIL_CONSTRUCTORS(CodecObserver);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::BaseState : public AState {
- BaseState(DashCodec *codec, const sp<AState> &parentState = NULL);
-
-protected:
- enum PortMode {
- KEEP_BUFFERS,
- RESUBMIT_BUFFERS,
- FREE_BUFFERS,
- };
-
- DashCodec *mCodec;
-
- virtual PortMode getPortMode(OMX_U32 portIndex);
-
- virtual bool onMessageReceived(const sp<AMessage> &msg);
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
- virtual void onOutputBufferDrained(const sp<AMessage> &msg);
- virtual void onInputBufferFilled(const sp<AMessage> &msg);
-
- void postFillThisBuffer(BufferInfo *info);
-
-private:
- bool onOMXMessage(const sp<AMessage> &msg);
-
- bool onOMXEmptyBufferDone(IOMX::buffer_id bufferID);
-
- bool onOMXFillBufferDone(
- IOMX::buffer_id bufferID,
- size_t rangeOffset, size_t rangeLength,
- OMX_U32 flags,
- int64_t timeUs,
- void *platformPrivate,
- void *dataPtr);
-
- void getMoreInputDataIfPossible();
-
- DISALLOW_EVIL_CONSTRUCTORS(BaseState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::UninitializedState : public DashCodec::BaseState {
- UninitializedState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
-private:
- void onSetup(const sp<AMessage> &msg);
- bool onAllocateComponent(const sp<AMessage> &msg);
-
- DISALLOW_EVIL_CONSTRUCTORS(UninitializedState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::LoadedState : public DashCodec::BaseState {
- LoadedState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
-private:
- friend struct DashCodec::UninitializedState;
-
- bool onConfigureComponent(const sp<AMessage> &msg);
- void onStart();
- void onShutdown(bool keepComponentAllocated);
-
- DISALLOW_EVIL_CONSTRUCTORS(LoadedState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::LoadedToIdleState : public DashCodec::BaseState {
- LoadedToIdleState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
- virtual void stateEntered();
-
-private:
- status_t allocateBuffers();
-
- DISALLOW_EVIL_CONSTRUCTORS(LoadedToIdleState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::IdleToExecutingState : public DashCodec::BaseState {
- IdleToExecutingState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
- virtual void stateEntered();
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(IdleToExecutingState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::ExecutingState : public DashCodec::BaseState {
- ExecutingState(DashCodec *codec);
-
- void submitRegularOutputBuffers();
- void submitOutputMetaBuffers();
- void submitOutputBuffers();
-
- // Submit output buffers to the decoder, submit input buffers to client
- // to fill with data.
- void resume();
-
- // Returns true iff input and output buffers are in play.
- bool active() const { return mActive; }
-
-protected:
- virtual PortMode getPortMode(OMX_U32 portIndex);
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
-private:
- bool mActive;
-
- DISALLOW_EVIL_CONSTRUCTORS(ExecutingState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::OutputPortSettingsChangedState : public DashCodec::BaseState {
- OutputPortSettingsChangedState(DashCodec *codec);
-
-protected:
- virtual PortMode getPortMode(OMX_U32 portIndex);
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void enableOutputPort(OMX_U32 data1, OMX_U32 data2);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(OutputPortSettingsChangedState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::ExecutingToIdleState : public DashCodec::BaseState {
- ExecutingToIdleState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
- virtual void onOutputBufferDrained(const sp<AMessage> &msg);
- virtual void onInputBufferFilled(const sp<AMessage> &msg);
-
-private:
- void changeStateIfWeOwnAllBuffers();
-
- bool mComponentNowIdle;
-
- DISALLOW_EVIL_CONSTRUCTORS(ExecutingToIdleState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::IdleToLoadedState : public DashCodec::BaseState {
- IdleToLoadedState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(IdleToLoadedState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::FlushingState : public DashCodec::BaseState {
- FlushingState(DashCodec *codec);
-
-protected:
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
- virtual void onOutputBufferDrained(const sp<AMessage> &msg);
- virtual void onInputBufferFilled(const sp<AMessage> &msg);
-
-private:
- bool mFlushComplete[2];
-
- void changeStateIfWeOwnAllBuffers();
-
- DISALLOW_EVIL_CONSTRUCTORS(FlushingState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-struct DashCodec::FlushingOutputState : public DashCodec::BaseState {
- FlushingOutputState(DashCodec *codec);
-
-protected:
- virtual PortMode getPortMode(OMX_U32 portIndex);
- virtual bool onMessageReceived(const sp<AMessage> &msg);
- virtual void stateEntered();
-
- virtual bool onOMXEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2);
-
- virtual void onOutputBufferDrained(const sp<AMessage> &msg);
- virtual void onInputBufferFilled(const sp<AMessage> &msg);
-
-private:
- bool mFlushComplete;
-
- void changeStateIfWeOwnAllBuffers();
-
- DISALLOW_EVIL_CONSTRUCTORS(FlushingOutputState);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::DashCodec()
- : mQuirks(0),
- mNode(NULL),
- mSentFormat(false),
- mPostFormat(false),
- mIsEncoder(false),
- mShutdownInProgress(false),
- mEncoderDelay(0),
- mEncoderPadding(0),
- mChannelMaskPresent(false),
- mChannelMask(0),
- mDequeueCounter(0),
- mStoreMetaDataInOutputBuffers(false),
- mMetaDataBuffersToSubmit(0),
- mCurrentWidth(0),
- mCurrentHeight(0),
- mAdaptivePlayback(false) {
- mUninitializedState = new UninitializedState(this);
- mLoadedState = new LoadedState(this);
- mLoadedToIdleState = new LoadedToIdleState(this);
- mIdleToExecutingState = new IdleToExecutingState(this);
- mExecutingState = new ExecutingState(this);
-
- mOutputPortSettingsChangedState =
- new OutputPortSettingsChangedState(this);
-
- mExecutingToIdleState = new ExecutingToIdleState(this);
- mIdleToLoadedState = new IdleToLoadedState(this);
- mFlushingState = new FlushingState(this);
- mFlushingOutputState = new FlushingOutputState(this);
-
- mPortEOS[kPortIndexInput] = mPortEOS[kPortIndexOutput] = false;
- mInputEOSResult = OK;
-
- changeState(mUninitializedState);
-}
-
-DashCodec::~DashCodec() {
- clearCachedFormats();
-}
-
-void DashCodec::setNotificationMessage(const sp<AMessage> &msg) {
- mNotify = msg;
-}
-
-void DashCodec::initiateSetup(const sp<AMessage> &msg) {
- msg->setWhat(kWhatSetup);
- msg->setTarget(id());
- msg->post();
-}
-
-void DashCodec::initiateAllocateComponent(const sp<AMessage> &msg) {
- msg->setWhat(kWhatAllocateComponent);
- msg->setTarget(id());
- msg->post();
-}
-
-void DashCodec::initiateConfigureComponent(const sp<AMessage> &msg) {
- msg->setWhat(kWhatConfigureComponent);
- msg->setTarget(id());
- msg->post();
-}
-
-void DashCodec::initiateStart() {
- (new AMessage(kWhatStart, id()))->post();
-}
-
-void DashCodec::signalFlush() {
- ALOGV("[%s] signalFlush", mComponentName.c_str());
- (new AMessage(kWhatFlush, id()))->post();
-}
-
-void DashCodec::signalResume() {
- (new AMessage(kWhatResume, id()))->post();
-}
-
-void DashCodec::initiateShutdown(bool keepComponentAllocated) {
- sp<AMessage> msg = new AMessage(kWhatShutdown, id());
- msg->setInt32("keepComponentAllocated", keepComponentAllocated);
- msg->post();
-}
-
-void DashCodec::signalRequestIDRFrame() {
- (new AMessage(kWhatRequestIDRFrame, id()))->post();
-}
-
-status_t DashCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
- CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
-
- CHECK(mDealer[portIndex] == NULL);
- CHECK(mBuffers[portIndex].isEmpty());
-
- status_t err;
- if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
- if (mStoreMetaDataInOutputBuffers) {
- err = allocateOutputMetaDataBuffers();
- } else {
- err = allocateOutputBuffersFromNativeWindow();
- }
- } else {
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = portIndex;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err == OK) {
- ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
- mComponentName.c_str(),
- def.nBufferCountActual, def.nBufferSize,
- portIndex == kPortIndexInput ? "input" : "output");
-
- size_t totalSize = def.nBufferCountActual * def.nBufferSize;
- mDealer[portIndex] = new MemoryDealer(totalSize, "DashCodec");
-
- for (OMX_U32 i = 0; i < def.nBufferCountActual; ++i) {
- sp<IMemory> mem = mDealer[portIndex]->allocate(def.nBufferSize);
- CHECK(mem.get() != NULL);
-
- BufferInfo info;
- info.mStatus = BufferInfo::OWNED_BY_US;
-
- uint32_t requiresAllocateBufferBit =
- (portIndex == kPortIndexInput)
- ? OMXCodec::kRequiresAllocateBufferOnInputPorts
- : OMXCodec::kRequiresAllocateBufferOnOutputPorts;
-
- if (portIndex == kPortIndexInput && (mFlags & kFlagIsSecure)) {
- mem.clear();
-
- void *ptr;
- err = mOMX->allocateBuffer(
- mNode, portIndex, def.nBufferSize, &info.mBufferID,
- &ptr);
-
- info.mData = new ABuffer(ptr, def.nBufferSize);
- } else if (mQuirks & requiresAllocateBufferBit) {
- err = mOMX->allocateBufferWithBackup(
- mNode, portIndex, mem, &info.mBufferID);
- } else {
- err = mOMX->useBuffer(mNode, portIndex, mem, &info.mBufferID);
- }
-
- if (mem != NULL) {
- info.mData = new ABuffer(mem->pointer(), def.nBufferSize);
- }
-
- mBuffers[portIndex].push(info);
- }
- }
- }
-
- if (err != OK) {
- return err;
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
-
- notify->setInt32("portIndex", portIndex);
-
- sp<PortDescription> desc = new PortDescription;
-
- for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- const BufferInfo &info = mBuffers[portIndex][i];
-
- desc->addBuffer(info.mBufferID, info.mData);
- }
-
- notify->setObject("portDesc", desc);
- notify->post();
-
- return OK;
-}
-
-status_t DashCodec::configureOutputBuffersFromNativeWindow(
-OMX_U32 *bufferCount, OMX_U32 *bufferSize,
- OMX_U32 *minUndequeuedBuffers) {
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- err = native_window_set_buffers_dimensions(
- mNativeWindow.get(),
- def.format.video.nFrameWidth,
- def.format.video.nFrameHeight);
-
- if (err != NO_ERROR) {
- ALOGE("native_window_set_buffers_dimensions failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_set_buffers_format(
- mNativeWindow.get(),
- def.format.video.eColorFormat);
-
- if (err != NO_ERROR) {
- ALOGE("native_window_set_buffers_format failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- // Set up the native window.
- OMX_U32 usage = 0;
- err = mOMX->getGraphicBufferUsage(mNode, kPortIndexOutput, &usage);
- if (err != 0) {
- ALOGW("querying usage flags from OMX IL component failed: %d", err);
- // XXX: Currently this error is logged, but not fatal.
- usage = 0;
- }
-
- if (mFlags & kFlagIsSecure || mFlags & kFlagIsSecureOPOnly) {
- usage |= GRALLOC_USAGE_PROTECTED;
- }
-
- // Make sure to check whether either Stagefright or the video decoder
- // requested protected buffers.
- if (usage & GRALLOC_USAGE_PROTECTED) {
- // Verify that the ANativeWindow sends images directly to
- // SurfaceFlinger.
- int queuesToNativeWindow = 0;
- err = mNativeWindow->query(
- mNativeWindow.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
- &queuesToNativeWindow);
- if (err != 0) {
- ALOGE("error authenticating native window: %d", err);
- return err;
- }
- if (queuesToNativeWindow != 1) {
- ALOGE("native window could not be authenticated");
- return PERMISSION_DENIED;
- }
- }
-
- err = native_window_set_usage(
- mNativeWindow.get(),
- usage | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_EXTERNAL_DISP);
-
- if (err != 0) {
- ALOGE("native_window_set_usage failed: %s (%d)", strerror(-err), -err);
- return err;
- }
-
- *minUndequeuedBuffers = 0;
- err = mNativeWindow->query(
- mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- (int *)minUndequeuedBuffers);
-
- if (err != 0) {
- ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- //add an extra buffer to display queue to get around dequeue+wait
- //blocking too long (more than 1 Vsync) in case BufferQeuue is in
- //sync-mode and advertizes only 1 buffer
- (*minUndequeuedBuffers)++;
- ALOGI("NOTE: Overriding minUndequeuedBuffers to %lu",*minUndequeuedBuffers);
-
- // XXX: Is this the right logic to use? It's not clear to me what the OMX
- // buffer counts refer to - how do they account for the renderer holding on
- // to buffers?
- if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
- OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
- def.nBufferCountActual = newBufferCount;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
- mComponentName.c_str(), newBufferCount, err);
- return err;
- }
- }
-
-
- err = native_window_set_buffer_count(
- mNativeWindow.get(), def.nBufferCountActual);
-
- if (err != 0) {
- ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err),
- -err);
- return err;
- }
-
- *bufferCount = def.nBufferCountActual;
- *bufferSize = def.nBufferSize;
- return err;
-}
-
-status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
- OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
- status_t err = configureOutputBuffersFromNativeWindow(
- &bufferCount, &bufferSize, &minUndequeuedBuffers);
- if (err != 0)
- return err;
-
- ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
- "output port",
- mComponentName.c_str(), bufferCount, bufferSize);
-
- // Dequeue buffers and send them to OMX
- for (OMX_U32 i = 0; i < bufferCount; i++) {
- ANativeWindowBuffer *buf;
- err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
- if (err != 0) {
- ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
- break;
- }
-
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
- BufferInfo info;
- info.mStatus = BufferInfo::OWNED_BY_US;
- info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
- info.mGraphicBuffer = graphicBuffer;
- mBuffers[kPortIndexOutput].push(info);
-
- IOMX::buffer_id bufferId;
- err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
- &bufferId);
- if (err != 0) {
- ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
- "%d", i, err);
- break;
- }
-
- mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
-
- ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
- mComponentName.c_str(),
- bufferId, graphicBuffer.get());
- }
-
- OMX_U32 cancelStart;
- OMX_U32 cancelEnd;
-
- if (err != 0) {
- // If an error occurred while dequeuing we need to cancel any buffers
- // that were dequeued.
- cancelStart = 0;
- cancelEnd = mBuffers[kPortIndexOutput].size();
- } else {
- // Return the required minimum undequeued buffers to the native window.
- cancelStart = bufferCount - minUndequeuedBuffers;
- cancelEnd = bufferCount;
- }
-
- for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
- BufferInfo *info = &mBuffers[kPortIndexOutput].editItemAt(i);
- cancelBufferToNativeWindow(info);
- }
-
- return err;
-}
-
-status_t DashCodec::allocateOutputMetaDataBuffers() {
- OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
- status_t err = configureOutputBuffersFromNativeWindow(
- &bufferCount, &bufferSize, &minUndequeuedBuffers);
- if (err != 0)
- return err;
-
- ALOGV("[%s] Allocating %lu meta buffers on output port",
- mComponentName.c_str(), bufferCount);
-
- size_t totalSize = bufferCount * 8;
- mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "DashCodec");
-
- // Dequeue buffers and send them to OMX
- for (OMX_U32 i = 0; i < bufferCount; i++) {
- BufferInfo info;
- info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
- info.mGraphicBuffer = NULL;
- info.mDequeuedAt = mDequeueCounter;
-
- sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
- sizeof(struct VideoDecoderOutputMetaData));
- CHECK(mem.get() != NULL);
- info.mData = new ABuffer(mem->pointer(), mem->size());
-
- // we use useBuffer for metadata regardless of quirks
- err = mOMX->useBuffer(
- mNode, kPortIndexOutput, mem, &info.mBufferID);
-
- mBuffers[kPortIndexOutput].push(info);
-
- ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
- mComponentName.c_str(), info.mBufferID, mem->pointer());
- }
-
- mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
- return err;
-}
-
-status_t DashCodec::submitOutputMetaDataBuffer() {
- CHECK(mStoreMetaDataInOutputBuffers);
- if (mMetaDataBuffersToSubmit == 0)
- return OK;
-
- BufferInfo *info = dequeueBufferFromNativeWindow();
- if (info == NULL)
- return ERROR_IO;
-
- ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
- mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
-
- --mMetaDataBuffersToSubmit;
- CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- return OK;
-}
-
-status_t DashCodec::cancelBufferToNativeWindow(BufferInfo *info) {
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
-
- ALOGV("[%s] Calling cancelBuffer on buffer %p",
- mComponentName.c_str(), info->mBufferID);
-
- int err = mNativeWindow->cancelBuffer(
- mNativeWindow.get(), info->mGraphicBuffer.get(), -1);
-
- CHECK_EQ(err, 0);
-
- info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
-
- return OK;
-}
-
-DashCodec::BufferInfo *DashCodec::dequeueBufferFromNativeWindow() {
- ANativeWindowBuffer *buf;
- int fenceFd = -1;
- CHECK(mNativeWindow.get() != NULL);
- if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
- ALOGE("dequeueBuffer failed.");
- return NULL;
- }
-
- BufferInfo *oldest = NULL;
- for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
- BufferInfo *info =
- &mBuffers[kPortIndexOutput].editItemAt(i);
-
- if (info->mGraphicBuffer != NULL &&
- info->mGraphicBuffer->handle == buf->handle) {
- CHECK_EQ((int)info->mStatus,
- (int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
-
- info->mStatus = BufferInfo::OWNED_BY_US;
-
- return info;
- }
-
- if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
- (oldest == NULL ||
- // avoid potential issues from counter rolling over
- mDequeueCounter - info->mDequeuedAt >
- mDequeueCounter - oldest->mDequeuedAt)) {
- oldest = info;
- }
- }
-
- if (oldest) {
- CHECK(mStoreMetaDataInOutputBuffers);
-
- // discard buffer in LRU info and replace with new buffer
- oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
- oldest->mStatus = BufferInfo::OWNED_BY_US;
-
- mOMX->updateGraphicBufferInMeta(
- mNode, kPortIndexOutput, oldest->mGraphicBuffer,
- oldest->mBufferID);
- VideoDecoderOutputMetaData *metaData =
- reinterpret_cast<VideoDecoderOutputMetaData *>(
- oldest->mData->base());
- CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
-
- ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
- oldest - &mBuffers[kPortIndexOutput][0],
- mDequeueCounter - oldest->mDequeuedAt,
- metaData->pHandle,
- oldest->mGraphicBuffer->handle, oldest->mData->base());
-
- return oldest;
- }
-
- TRESPASS();
-
- return NULL;
-}
-
-status_t DashCodec::freeBuffersOnPort(OMX_U32 portIndex) {
- for (size_t i = mBuffers[portIndex].size(); i-- > 0;) {
- CHECK_EQ((status_t)OK, freeBuffer(portIndex, i));
- }
-
- mDealer[portIndex].clear();
-
- return OK;
-}
-
-status_t DashCodec::freeOutputBuffersNotOwnedByComponent() {
- for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
- BufferInfo *info =
- &mBuffers[kPortIndexOutput].editItemAt(i);
-
- // At this time some buffers may still be with the component
- // or being drained.
- if (info->mStatus != BufferInfo::OWNED_BY_COMPONENT &&
- info->mStatus != BufferInfo::OWNED_BY_DOWNSTREAM) {
- CHECK_EQ((status_t)OK, freeBuffer(kPortIndexOutput, i));
- }
- }
-
- return OK;
-}
-
-status_t DashCodec::freeBuffer(OMX_U32 portIndex, size_t i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
-
- CHECK(info->mStatus == BufferInfo::OWNED_BY_US
- || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
-
- if (portIndex == kPortIndexOutput && mNativeWindow != NULL
- && info->mStatus == BufferInfo::OWNED_BY_US) {
- CHECK_EQ((status_t)OK, cancelBufferToNativeWindow(info));
- }
-
- CHECK_EQ(mOMX->freeBuffer(
- mNode, portIndex, info->mBufferID),
- (status_t)OK);
-
- mBuffers[portIndex].removeAt(i);
-
- return OK;
-}
-
-DashCodec::BufferInfo *DashCodec::findBufferByID(
- uint32_t portIndex, IOMX::buffer_id bufferID,
- ssize_t *index) {
- for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
-
- if (info->mBufferID == bufferID) {
- if (index != NULL) {
- *index = i;
- }
- return info;
- }
- }
-
- TRESPASS();
-
- return NULL;
-}
-
-status_t DashCodec::setComponentRole(
- bool isEncoder, const char *mime) {
- struct MimeToRole {
- const char *mime;
- const char *decoderRole;
- const char *encoderRole;
- };
-
- static const MimeToRole kMimeToRole[] = {
- { MEDIA_MIMETYPE_AUDIO_MPEG,
- "audio_decoder.mp3", "audio_encoder.mp3" },
- { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_I,
- "audio_decoder.mp1", "audio_encoder.mp1" },
- { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II,
- "audio_decoder.mp2", "audio_encoder.mp2" },
- { MEDIA_MIMETYPE_AUDIO_AMR_NB,
- "audio_decoder.amrnb", "audio_encoder.amrnb" },
- { MEDIA_MIMETYPE_AUDIO_AMR_WB,
- "audio_decoder.amrwb", "audio_encoder.amrwb" },
- // commenting out AMR_WM_PLUS for bringing up dash on MR2
- /* { MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS,
- "audio_decoder.amrwbplus", "audio_encoder.amrwbplus" }, */
- { MEDIA_MIMETYPE_AUDIO_AAC,
- "audio_decoder.aac", "audio_encoder.aac" },
- { MEDIA_MIMETYPE_AUDIO_VORBIS,
- "audio_decoder.vorbis", "audio_encoder.vorbis" },
- { MEDIA_MIMETYPE_AUDIO_G711_MLAW,
- "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" },
- { MEDIA_MIMETYPE_AUDIO_G711_ALAW,
- "audio_decoder.g711alaw", "audio_encoder.g711alaw" },
- { MEDIA_MIMETYPE_VIDEO_AVC,
- "video_decoder.avc", "video_encoder.avc" },
- { MEDIA_MIMETYPE_VIDEO_MPEG4,
- "video_decoder.mpeg4", "video_encoder.mpeg4" },
- { MEDIA_MIMETYPE_VIDEO_H263,
- "video_decoder.h263", "video_encoder.h263" },
- { MEDIA_MIMETYPE_AUDIO_RAW,
- "audio_decoder.raw", "audio_encoder.raw" },
- { MEDIA_MIMETYPE_AUDIO_FLAC,
- "audio_decoder.flac", "audio_encoder.flac" },
- { MEDIA_MIMETYPE_VIDEO_HEVC,
- "video_decoder.hevc", "video_encoder.hevc" },
- };
-
- static const size_t kNumMimeToRole =
- sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
-
- size_t i;
- for (i = 0; i < kNumMimeToRole; ++i) {
- if (!strcasecmp(mime, kMimeToRole[i].mime)) {
- break;
- }
- }
-
- if (i == kNumMimeToRole) {
- return ERROR_UNSUPPORTED;
- }
-
- const char *role =
- isEncoder ? kMimeToRole[i].encoderRole
- : kMimeToRole[i].decoderRole;
-
- if (role != NULL) {
- OMX_PARAM_COMPONENTROLETYPE roleParams;
- InitOMXParams(&roleParams);
-
- strncpy((char *)roleParams.cRole,
- role, OMX_MAX_STRINGNAME_SIZE - 1);
-
- roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
-
- status_t err = mOMX->setParameter(
- mNode, OMX_IndexParamStandardComponentRole,
- &roleParams, sizeof(roleParams));
-
- if (err != OK) {
- ALOGW("[%s] Failed to set standard component role '%s'.",
- mComponentName.c_str(), role);
-
- return err;
- }
- }
-
- return OK;
-}
-
-status_t DashCodec::configureCodec(
- const char *mime, const sp<AMessage> &msg) {
- int32_t encoder;
- if (!msg->findInt32("encoder", &encoder)) {
- encoder = false;
- }
-
- mIsEncoder = encoder;
-
- status_t err = setComponentRole(encoder /* isEncoder */, mime);
-
- if (err != OK) {
- return err;
- }
-
- int32_t bitRate = 0;
- // FLAC encoder doesn't need a bitrate, other encoders do
- if (encoder && strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)
- && !msg->findInt32("bitrate", &bitRate)) {
- return INVALID_OPERATION;
- }
-
- int32_t storeMeta;
- if (encoder
- && msg->findInt32("store-metadata-in-buffers", &storeMeta)
- && storeMeta != 0) {
- err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexInput, OMX_TRUE);
-
- if (err != OK) {
- ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
- mComponentName.c_str(), err);
-
- return err;
- }
- else
- {
- ALOGE("[%s] storeMetaDataInBuffers succedded", mComponentName.c_str());
- }
- }
-
- int32_t prependSPSPPS;
- if (encoder
- && msg->findInt32("prepend-sps-pps-to-idr-frames", &prependSPSPPS)
- && prependSPSPPS != 0) {
- OMX_INDEXTYPE index;
- err = mOMX->getExtensionIndex(
- mNode,
- "OMX.google.android.index.prependSPSPPSToIDRFrames",
- &index);
-
- if (err == OK) {
- PrependSPSPPSToIDRFramesParams params;
- InitOMXParams(&params);
- params.bEnable = OMX_TRUE;
-
- err = mOMX->setParameter(
- mNode, index, &params, sizeof(params));
- }
-
- if (err != OK) {
- ALOGE("Encoder could not be configured to emit SPS/PPS before "
- "IDR frames. (err %d)", err);
-
- return err;
- }
- }
-
- // Always try to enable dynamic output buffers on native surface
- int32_t video = !strncasecmp(mime, "video/", 6);
- sp<RefBase> obj;
- int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
- obj != NULL;
- mStoreMetaDataInOutputBuffers = false;
-
- bool mEnableDynamicBuffering = true;
- char property_value[PROPERTY_VALUE_MAX];
- property_value[0] = '\0';
- property_get("persist.dash.dbm.enable", property_value, "1");
- if(*property_value)
- {
- mEnableDynamicBuffering = atoi(property_value) > 0 ? true: false;
- ALOGE("DynamicBuffering is set to [%d]", mEnableDynamicBuffering);
- }
- // Do not use Dynamic Buffer or Adaptive playback for HEVC, the HEVC decoder hybrid solution
- // that is being used doesnt support these mode , so just use port reconfig mode
- if (!encoder && video && haveNativeWindow && (strcmp(mime,"video/hevc")!= 0)) {
-
- if (mEnableDynamicBuffering)
- {
- ALOGE("Enabling Dynamic Buffering Mode");
- err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
- }
- else
- {
- ALOGE("Disabling Dynamic Buffering Mode Thru SetProp");
- err = INVALID_OPERATION;
- }
- if (err != OK) {
-
- ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
- mComponentName.c_str(), err);
-
- // if adaptive playback has been requested, try JB fallback
- // NOTE: THIS FALLBACK MECHANISM WILL BE REMOVED DUE TO ITS
- // LARGE MEMORY REQUIREMENT
-
- // we will not do adaptive playback on software accessed
- // surfaces as they never had to respond to changes in the
- // crop window, and we don't trust that they will be able to.
- int usageBits = 0;
-
- sp<NativeWindowWrapper> windowWrapper(
- static_cast<NativeWindowWrapper *>(obj.get()));
- sp<ANativeWindow> nativeWindow = windowWrapper->getNativeWindow();
-
- if (nativeWindow->query(
- nativeWindow.get(),
- NATIVE_WINDOW_CONSUMER_USAGE_BITS,
- &usageBits) != OK) {
- } else {
- mAdaptivePlayback =
- (usageBits &
- (GRALLOC_USAGE_SW_READ_MASK |
- GRALLOC_USAGE_SW_WRITE_MASK)) == 0;
- }
- int32_t maxWidth = MAX_WIDTH;
- int32_t maxHeight = MAX_HEIGHT;
- if (mAdaptivePlayback) {
- ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
- mComponentName.c_str(), maxWidth, maxHeight);
-
- err = mOMX->prepareForAdaptivePlayback(
- mNode, kPortIndexOutput, OMX_TRUE, maxWidth, maxHeight);
- if (err != OK)
- {
- ALOGE("[%s] prepareForAdaptivePlayback failed w/ err %d",
- mComponentName.c_str(), err);
- }
- else
- {
- ALOGV("[%s] prepareForAdaptivePlayback : Success",
- mComponentName.c_str(), err);
- }
- }
- // allow failure
- err = OK;
- } else {
- ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
- mStoreMetaDataInOutputBuffers = true;
- }
-
- int32_t push;
- if (msg->findInt32("push-blank-buffers-on-shutdown", &push)
- && push != 0) {
- mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
- }
- }
- if (!strncasecmp(mime, "video/", 6)) {
- if (encoder) {
- err = setupVideoEncoder(mime, msg);
- } else {
- int32_t width, height;
- if (!msg->findInt32("width", &width)
- || !msg->findInt32("height", &height)) {
- err = INVALID_OPERATION;
- } else {
- //override height & width with max for smooth streaming
- if (mAdaptivePlayback) {
- width = MAX_WIDTH;
- height = MAX_HEIGHT;
- }
- ALOGE("[%s] setupVideoDecoder with width %d, height %d",
- mComponentName.c_str(),width,height);
- err = setupVideoDecoder(mime, width, height);
-
- QOMX_VIDEO_CUSTOM_BUFFERSIZE sCustomBufferSize;
- sCustomBufferSize.nPortIndex = kPortIndexInput;
- sCustomBufferSize.nBufferSize = (OMX_U32)(MAX_SUPPORTED_BUF_SZ);
-
- ALOGV("[%s] Set Inputbuffers size %lu Input Port [Before Alignment]",
- mComponentName.c_str(),
- sCustomBufferSize.nBufferSize);
- //Doing 4K alignment
- sCustomBufferSize.nBufferSize = ALIGN(sCustomBufferSize.nBufferSize, SZ_4K);
-
- err = mOMX->setParameter(mNode,
- (OMX_INDEXTYPE)OMX_QcomIndexParamVideoCustomBufferSize,
- &sCustomBufferSize, sizeof(sCustomBufferSize));
-
- if (err != OK) {
- ALOGE("[%s] Set Inputbuffers thru extn size %lu InputPort Failed",
- mComponentName.c_str(),
- sCustomBufferSize.nBufferSize);
- }
- else
- {
- ALOGV("[%s] Set Inputbuffers thru extn size %lu InputPort Success",
- mComponentName.c_str(),
- sCustomBufferSize.nBufferSize);
- }
-
- //Enable component support to extract SEI extradata if present in AVC stream
- QOMX_ENABLETYPE extra_data;
- extra_data.bEnable = OMX_TRUE;
-
- status_t errVal = mOMX->setParameter(
- mNode, (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData,
- (OMX_PTR)&extra_data, sizeof(extra_data));
-
- if (errVal != OK) {
- ALOGE("[%s] setting OMX_QcomIndexEnableExtnUserData failed: %d",
- mComponentName.c_str(), err);
- }
- else
- {
- ALOGE("[%s] setting OMX_QcomIndexEnableExtnUserData success",
- mComponentName.c_str());
- }
- }
- }
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
- int32_t numChannels = 0, sampleRate = 0;
- if (!msg->findInt32("channel-count", &numChannels)
- || !msg->findInt32("sample-rate", &sampleRate)) {
- err = INVALID_OPERATION;
- } else {
- int32_t isADTS, aacProfile;
- if (!msg->findInt32("is-adts", &isADTS)) {
- isADTS = 0;
- }
- if (!msg->findInt32("aac-profile", &aacProfile)) {
- aacProfile = OMX_AUDIO_AACObjectNull;
- }
-
- err = setupAACCodec(
- encoder, numChannels, sampleRate, bitRate, aacProfile, isADTS != 0);
- }
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) {
- err = setupAMRCodec(encoder, false /* isWAMR */, bitRate);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) {
- err = setupAMRCodec(encoder, true /* isWAMR */, bitRate);
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_ALAW)
- || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_G711_MLAW)) {
- // These are PCM-like formats with a fixed sample rate but
- // a variable number of channels.
-
- int32_t numChannels = 0;
- if (!msg->findInt32("channel-count", &numChannels)) {
- err = INVALID_OPERATION;
- } else {
- err = setupG711Codec(encoder, numChannels);
- }
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) {
- int32_t numChannels = 0, sampleRate = 0, compressionLevel = -1;
- if (encoder &&
- (!msg->findInt32("channel-count", &numChannels)
- || !msg->findInt32("sample-rate", &sampleRate))) {
- ALOGE("missing channel count or sample rate for FLAC encoder");
- err = INVALID_OPERATION;
- } else {
- if (encoder) {
- if (!msg->findInt32("flac-compression-level", &compressionLevel)) {
- compressionLevel = 5;// default FLAC compression level
- } else if (compressionLevel < 0) {
- ALOGW("compression level %d outside [0..8] range, using 0", compressionLevel);
- compressionLevel = 0;
- } else if (compressionLevel > 8) {
- ALOGW("compression level %d outside [0..8] range, using 8", compressionLevel);
- compressionLevel = 8;
- }
- }
- err = setupFlacCodec(encoder, numChannels, sampleRate, compressionLevel);
- }
- } else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)) {
- int32_t numChannels =0 , sampleRate = 0;
- if (encoder
- || !msg->findInt32("channel-count", &numChannels)
- || !msg->findInt32("sample-rate", &sampleRate)) {
- err = INVALID_OPERATION;
- } else {
- err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
- }
- }
-
- if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
- mEncoderDelay = 0;
- }
-
- if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
- mEncoderPadding = 0;
- }
-
- if (msg->findInt32("channel-mask", &mChannelMask)) {
- mChannelMaskPresent = true;
- } else {
- mChannelMaskPresent = false;
- }
-
- int32_t maxInputSize;
- if (msg->findInt32("max-input-size", &maxInputSize)) {
- err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
- } else if (!strcmp("OMX.Nvidia.aac.decoder", mComponentName.c_str())) {
- err = setMinBufferSize(kPortIndexInput, 8192); // XXX
- }
-
- return err;
-}
-
-status_t DashCodec::setMinBufferSize(OMX_U32 portIndex, size_t size) {
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = portIndex;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- if (def.nBufferSize >= size) {
- return OK;
- }
-
- def.nBufferSize = size;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- CHECK(def.nBufferSize >= size);
-
- return OK;
-}
-
-status_t DashCodec::selectAudioPortFormat(
- OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat) {
- OMX_AUDIO_PARAM_PORTFORMATTYPE format;
- InitOMXParams(&format);
-
- format.nPortIndex = portIndex;
- for (OMX_U32 index = 0;; ++index) {
- format.nIndex = index;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamAudioPortFormat,
- &format, sizeof(format));
-
- if (err != OK) {
- return err;
- }
-
- if (format.eEncoding == desiredFormat) {
- break;
- }
- }
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamAudioPortFormat, &format, sizeof(format));
-}
-
-status_t DashCodec::setupAACCodec(
- bool encoder, int32_t numChannels, int32_t sampleRate,
- int32_t bitRate, int32_t aacProfile, bool isADTS) {
- if (encoder && isADTS) {
- return -EINVAL;
- }
-
- status_t err = setupRawAudioFormat(
- encoder ? kPortIndexInput : kPortIndexOutput,
- sampleRate,
- numChannels);
-
- if (err != OK) {
- return err;
- }
-
- if (encoder) {
- err = selectAudioPortFormat(kPortIndexOutput, OMX_AUDIO_CodingAAC);
-
- if (err != OK) {
- return err;
- }
-
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexOutput;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- def.format.audio.bFlagErrorConcealment = OMX_TRUE;
- def.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- OMX_AUDIO_PARAM_AACPROFILETYPE profile;
- InitOMXParams(&profile);
- profile.nPortIndex = kPortIndexOutput;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-
- if (err != OK) {
- return err;
- }
-
- profile.nChannels = numChannels;
-
- profile.eChannelMode =
- (numChannels == 1)
- ? OMX_AUDIO_ChannelModeMono: OMX_AUDIO_ChannelModeStereo;
-
- profile.nSampleRate = sampleRate;
- profile.nBitRate = bitRate;
- profile.nAudioBandWidth = 0;
- profile.nFrameLength = 0;
- profile.nAACtools = OMX_AUDIO_AACToolAll;
- profile.nAACERtools = OMX_AUDIO_AACERNone;
- profile.eAACProfile = (OMX_AUDIO_AACPROFILETYPE) aacProfile;
- profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4FF;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-
- if (err != OK) {
- return err;
- }
-
- return err;
- }
-
- OMX_AUDIO_PARAM_AACPROFILETYPE profile;
- InitOMXParams(&profile);
- profile.nPortIndex = kPortIndexInput;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-
- if (err != OK) {
- return err;
- }
-
- profile.nChannels = numChannels;
- profile.nSampleRate = sampleRate;
-
- profile.eAACStreamFormat =
- isADTS
- ? OMX_AUDIO_AACStreamFormatMP4ADTS
- : OMX_AUDIO_AACStreamFormatMP4FF;
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
-}
-
-static OMX_AUDIO_AMRBANDMODETYPE pickModeFromBitRate(
- bool isAMRWB, int32_t bps) {
- if (isAMRWB) {
- if (bps <= 6600) {
- return OMX_AUDIO_AMRBandModeWB0;
- } else if (bps <= 8850) {
- return OMX_AUDIO_AMRBandModeWB1;
- } else if (bps <= 12650) {
- return OMX_AUDIO_AMRBandModeWB2;
- } else if (bps <= 14250) {
- return OMX_AUDIO_AMRBandModeWB3;
- } else if (bps <= 15850) {
- return OMX_AUDIO_AMRBandModeWB4;
- } else if (bps <= 18250) {
- return OMX_AUDIO_AMRBandModeWB5;
- } else if (bps <= 19850) {
- return OMX_AUDIO_AMRBandModeWB6;
- } else if (bps <= 23050) {
- return OMX_AUDIO_AMRBandModeWB7;
- }
-
- // 23850 bps
- return OMX_AUDIO_AMRBandModeWB8;
- } else { // AMRNB
- if (bps <= 4750) {
- return OMX_AUDIO_AMRBandModeNB0;
- } else if (bps <= 5150) {
- return OMX_AUDIO_AMRBandModeNB1;
- } else if (bps <= 5900) {
- return OMX_AUDIO_AMRBandModeNB2;
- } else if (bps <= 6700) {
- return OMX_AUDIO_AMRBandModeNB3;
- } else if (bps <= 7400) {
- return OMX_AUDIO_AMRBandModeNB4;
- } else if (bps <= 7950) {
- return OMX_AUDIO_AMRBandModeNB5;
- } else if (bps <= 10200) {
- return OMX_AUDIO_AMRBandModeNB6;
- }
-
- // 12200 bps
- return OMX_AUDIO_AMRBandModeNB7;
- }
-}
-
-status_t DashCodec::setupAMRCodec(bool encoder, bool isWAMR, int32_t bitrate) {
- OMX_AUDIO_PARAM_AMRTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = encoder ? kPortIndexOutput : kPortIndexInput;
-
- status_t err =
- mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
- def.eAMRBandMode = pickModeFromBitRate(isWAMR, bitrate);
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- return setupRawAudioFormat(
- encoder ? kPortIndexInput : kPortIndexOutput,
- isWAMR ? 16000 : 8000 /* sampleRate */,
- 1 /* numChannels */);
-}
-
-status_t DashCodec::setupG711Codec(bool encoder, int32_t numChannels) {
- CHECK(!encoder); // XXX TODO
-
- return setupRawAudioFormat(
- kPortIndexInput, 8000 /* sampleRate */, numChannels);
-}
-
-status_t DashCodec::setupFlacCodec(
- bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel) {
-
- if (encoder) {
- OMX_AUDIO_PARAM_FLACTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = kPortIndexOutput;
-
- // configure compression level
- status_t err = mOMX->getParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
- if (err != OK) {
- ALOGE("setupFlacCodec(): Error %d getting OMX_IndexParamAudioFlac parameter", err);
- return err;
- }
- def.nCompressionLevel = compressionLevel;
- err = mOMX->setParameter(mNode, OMX_IndexParamAudioFlac, &def, sizeof(def));
- if (err != OK) {
- ALOGE("setupFlacCodec(): Error %d setting OMX_IndexParamAudioFlac parameter", err);
- return err;
- }
- }
-
- return setupRawAudioFormat(
- encoder ? kPortIndexInput : kPortIndexOutput,
- sampleRate,
- numChannels);
-}
-
-status_t DashCodec::setupRawAudioFormat(
- OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = portIndex;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
- InitOMXParams(&pcmParams);
- pcmParams.nPortIndex = portIndex;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-
- if (err != OK) {
- return err;
- }
-
- pcmParams.nChannels = numChannels;
- pcmParams.eNumData = OMX_NumericalDataSigned;
- pcmParams.bInterleaved = OMX_TRUE;
- pcmParams.nBitPerSample = 16;
- pcmParams.nSamplingRate = sampleRate;
- pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
-
- if (getOMXChannelMapping(numChannels, pcmParams.eChannelMapping) != OK) {
- return OMX_ErrorNone;
- }
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-}
-
-status_t DashCodec::setVideoPortFormatType(
- OMX_U32 portIndex,
- OMX_VIDEO_CODINGTYPE compressionFormat,
- OMX_COLOR_FORMATTYPE colorFormat) {
- OMX_VIDEO_PARAM_PORTFORMATTYPE format;
- InitOMXParams(&format);
- format.nPortIndex = portIndex;
- format.nIndex = 0;
- bool found = false;
-
- OMX_U32 index = 0;
- for (;;) {
- format.nIndex = index;
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
-
- if (err != OK) {
- return err;
- }
-
- // The following assertion is violated by TI's video decoder.
- // CHECK_EQ(format.nIndex, index);
-
- if (!strcmp("OMX.TI.Video.encoder", mComponentName.c_str())) {
- if (portIndex == kPortIndexInput
- && colorFormat == format.eColorFormat) {
- // eCompressionFormat does not seem right.
- found = true;
- break;
- }
- if (portIndex == kPortIndexOutput
- && compressionFormat == format.eCompressionFormat) {
- // eColorFormat does not seem right.
- found = true;
- break;
- }
- }
-
- if (format.eCompressionFormat == compressionFormat
- && format.eColorFormat == colorFormat) {
- found = true;
- break;
- }
-
- ++index;
- }
-
- if (!found) {
- return UNKNOWN_ERROR;
- }
-
- status_t err = mOMX->setParameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
-
- return err;
-}
-
-status_t DashCodec::setSupportedOutputFormat() {
- OMX_VIDEO_PARAM_PORTFORMATTYPE format;
- InitOMXParams(&format);
- format.nPortIndex = kPortIndexOutput;
- format.nIndex = 0;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
- CHECK_EQ(err, (status_t)OK);
- CHECK_EQ((int)format.eCompressionFormat, (int)OMX_VIDEO_CodingUnused);
-
- CHECK(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
- || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
- || format.eColorFormat == OMX_COLOR_FormatCbYCrY
- || format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
- || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
- || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
- || format.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m
- );
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
-}
-
-static status_t GetVideoCodingTypeFromMime(
- const char *mime, OMX_VIDEO_CODINGTYPE *codingType) {
- if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
- *codingType = OMX_VIDEO_CodingAVC;
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
- *codingType = OMX_VIDEO_CodingMPEG4;
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
- *codingType = OMX_VIDEO_CodingH263;
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG2, mime)) {
- *codingType = OMX_VIDEO_CodingMPEG2;
- } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
- *codingType = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
- } else {
- *codingType = OMX_VIDEO_CodingUnused;
- return ERROR_UNSUPPORTED;
- }
-
- return OK;
-}
-
-status_t DashCodec::setupVideoDecoder(
- const char *mime, int32_t width, int32_t height) {
- OMX_VIDEO_CODINGTYPE compressionFormat;
- status_t err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
-
- if (err != OK) {
- return err;
- }
-
- err = setVideoPortFormatType(
- kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
-
- if (err != OK) {
- return err;
- }
-
- err = setSupportedOutputFormat();
-
- if (err != OK) {
- return err;
- }
-
- err = setVideoFormatOnPort(
- kPortIndexInput, width, height, compressionFormat);
-
- if (err != OK) {
- return err;
- }
-
- err = setVideoFormatOnPort(
- kPortIndexOutput, width, height, OMX_VIDEO_CodingUnused);
-
- if (err != OK) {
- return err;
- }
-
- return OK;
-}
-
-status_t DashCodec::setupVideoEncoder(const char *mime, const sp<AMessage> &msg) {
- int32_t tmp;
- if (!msg->findInt32("color-format", &tmp)) {
- return INVALID_OPERATION;
- }
-
- OMX_COLOR_FORMATTYPE colorFormat =
- static_cast<OMX_COLOR_FORMATTYPE>(tmp);
-
- status_t err = setVideoPortFormatType(
- kPortIndexInput, OMX_VIDEO_CodingUnused, colorFormat);
-
- if (err != OK) {
- ALOGE("[%s] does not support color format %d",
- mComponentName.c_str(), colorFormat);
-
- return err;
- }
-
- /* Input port configuration */
-
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
-
- OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
- def.nPortIndex = kPortIndexInput;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- int32_t width, height, bitrate;
- if (!msg->findInt32("width", &width)
- || !msg->findInt32("height", &height)
- || !msg->findInt32("bitrate", &bitrate)) {
- return INVALID_OPERATION;
- }
-
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
-
- int32_t stride;
- if (!msg->findInt32("stride", &stride)) {
- stride = width;
- }
-
- video_def->nStride = stride;
-
- int32_t sliceHeight;
- if (!msg->findInt32("slice-height", &sliceHeight)) {
- sliceHeight = height;
- }
-
- video_def->nSliceHeight = sliceHeight;
-
- def.nBufferSize = (video_def->nStride * video_def->nSliceHeight * 3) / 2;
-
- float frameRate;
- if (!msg->findFloat("frame-rate", &frameRate)) {
- int32_t tmp;
- if (!msg->findInt32("frame-rate", &tmp)) {
- return INVALID_OPERATION;
- }
- frameRate = (float)tmp;
- }
-
- video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
- video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
- video_def->eColorFormat = colorFormat;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- ALOGE("[%s] failed to set input port definition parameters.",
- mComponentName.c_str());
-
- return err;
- }
-
- /* Output port configuration */
-
- OMX_VIDEO_CODINGTYPE compressionFormat;
- err = GetVideoCodingTypeFromMime(mime, &compressionFormat);
-
- if (err != OK) {
- return err;
- }
-
- err = setVideoPortFormatType(
- kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
-
- if (err != OK) {
- ALOGE("[%s] does not support compression format %d",
- mComponentName.c_str(), compressionFormat);
-
- return err;
- }
-
- def.nPortIndex = kPortIndexOutput;
-
- err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- return err;
- }
-
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
- video_def->xFramerate = 0;
- video_def->nBitrate = bitrate;
- video_def->eCompressionFormat = compressionFormat;
- video_def->eColorFormat = OMX_COLOR_FormatUnused;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- if (err != OK) {
- ALOGE("[%s] failed to set output port definition parameters.",
- mComponentName.c_str());
-
- return err;
- }
-
- switch (compressionFormat) {
- case OMX_VIDEO_CodingMPEG4:
- err = setupMPEG4EncoderParameters(msg);
- break;
-
- case OMX_VIDEO_CodingH263:
- err = setupH263EncoderParameters(msg);
- break;
-
- case OMX_VIDEO_CodingAVC:
- err = setupAVCEncoderParameters(msg);
- break;
-
- default:
- break;
- }
-
- ALOGI("setupVideoEncoder succeeded");
-
- return err;
-}
-
-static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) {
- if (iFramesInterval < 0) {
- return 0xFFFFFFFF;
- } else if (iFramesInterval == 0) {
- return 0;
- }
- OMX_U32 ret = frameRate * iFramesInterval;
- CHECK(ret > 1);
- return ret;
-}
-
-static OMX_VIDEO_CONTROLRATETYPE getBitrateMode(const sp<AMessage> &msg) {
- int32_t tmp;
- if (!msg->findInt32("bitrate-mode", &tmp)) {
- return OMX_Video_ControlRateVariable;
- }
-
- return static_cast<OMX_VIDEO_CONTROLRATETYPE>(tmp);
-}
-
-status_t DashCodec::setupMPEG4EncoderParameters(const sp<AMessage> &msg) {
- int32_t bitrate, iFrameInterval;
- if (!msg->findInt32("bitrate", &bitrate)
- || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
- return INVALID_OPERATION;
- }
-
- OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
-
- float frameRate;
- if (!msg->findFloat("frame-rate", &frameRate)) {
- int32_t tmp;
- if (!msg->findInt32("frame-rate", &tmp)) {
- return INVALID_OPERATION;
- }
- frameRate = (float)tmp;
- }
-
- OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
- InitOMXParams(&mpeg4type);
- mpeg4type.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
-
- if (err != OK) {
- return err;
- }
-
- mpeg4type.nSliceHeaderSpacing = 0;
- mpeg4type.bSVH = OMX_FALSE;
- mpeg4type.bGov = OMX_FALSE;
-
- mpeg4type.nAllowedPictureTypes =
- OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
- mpeg4type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
- if (mpeg4type.nPFrames == 0) {
- mpeg4type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
- }
- mpeg4type.nBFrames = 0;
- mpeg4type.nIDCVLCThreshold = 0;
- mpeg4type.bACPred = OMX_TRUE;
- mpeg4type.nMaxPacketSize = 256;
- mpeg4type.nTimeIncRes = 1000;
- mpeg4type.nHeaderExtension = 0;
- mpeg4type.bReversibleVLC = OMX_FALSE;
-
- int32_t profile;
- if (msg->findInt32("profile", &profile)) {
- int32_t level;
- if (!msg->findInt32("level", &level)) {
- return INVALID_OPERATION;
- }
-
- err = verifySupportForProfileAndLevel(profile, level);
-
- if (err != OK) {
- return err;
- }
-
- mpeg4type.eProfile = static_cast<OMX_VIDEO_MPEG4PROFILETYPE>(profile);
- mpeg4type.eLevel = static_cast<OMX_VIDEO_MPEG4LEVELTYPE>(level);
- }
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamVideoMpeg4, &mpeg4type, sizeof(mpeg4type));
-
- if (err != OK) {
- return err;
- }
-
- err = configureBitrate(bitrate, bitrateMode);
-
- if (err != OK) {
- return err;
- }
-
- return setupErrorCorrectionParameters();
-}
-
-status_t DashCodec::setupH263EncoderParameters(const sp<AMessage> &msg) {
- int32_t bitrate, iFrameInterval;
- if (!msg->findInt32("bitrate", &bitrate)
- || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
- return INVALID_OPERATION;
- }
-
- OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
-
- float frameRate;
- if (!msg->findFloat("frame-rate", &frameRate)) {
- int32_t tmp;
- if (!msg->findInt32("frame-rate", &tmp)) {
- return INVALID_OPERATION;
- }
- frameRate = (float)tmp;
- }
-
- OMX_VIDEO_PARAM_H263TYPE h263type;
- InitOMXParams(&h263type);
- h263type.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
-
- if (err != OK) {
- return err;
- }
-
- h263type.nAllowedPictureTypes =
- OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
- h263type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
- if (h263type.nPFrames == 0) {
- h263type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
- }
- h263type.nBFrames = 0;
-
- int32_t profile;
- if (msg->findInt32("profile", &profile)) {
- int32_t level;
- if (!msg->findInt32("level", &level)) {
- return INVALID_OPERATION;
- }
-
- err = verifySupportForProfileAndLevel(profile, level);
-
- if (err != OK) {
- return err;
- }
-
- h263type.eProfile = static_cast<OMX_VIDEO_H263PROFILETYPE>(profile);
- h263type.eLevel = static_cast<OMX_VIDEO_H263LEVELTYPE>(level);
- }
-
- h263type.bPLUSPTYPEAllowed = OMX_FALSE;
- h263type.bForceRoundingTypeToZero = OMX_FALSE;
- h263type.nPictureHeaderRepetition = 0;
- h263type.nGOBHeaderInterval = 0;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamVideoH263, &h263type, sizeof(h263type));
-
- if (err != OK) {
- return err;
- }
-
- err = configureBitrate(bitrate, bitrateMode);
-
- if (err != OK) {
- return err;
- }
-
- return setupErrorCorrectionParameters();
-}
-
-status_t DashCodec::setupAVCEncoderParameters(const sp<AMessage> &msg) {
- int32_t bitrate, iFrameInterval;
- if (!msg->findInt32("bitrate", &bitrate)
- || !msg->findInt32("i-frame-interval", &iFrameInterval)) {
- return INVALID_OPERATION;
- }
-
- OMX_VIDEO_CONTROLRATETYPE bitrateMode = getBitrateMode(msg);
-
- float frameRate;
- if (!msg->findFloat("frame-rate", &frameRate)) {
- int32_t tmp;
- if (!msg->findInt32("frame-rate", &tmp)) {
- return INVALID_OPERATION;
- }
- frameRate = (float)tmp;
- }
-
- OMX_VIDEO_PARAM_AVCTYPE h264type;
- InitOMXParams(&h264type);
- h264type.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
-
- if (err != OK) {
- return err;
- }
-
- h264type.nAllowedPictureTypes =
- OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP;
-
- int32_t profile;
- if (msg->findInt32("profile", &profile)) {
- int32_t level;
- if (!msg->findInt32("level", &level)) {
- return INVALID_OPERATION;
- }
-
- err = verifySupportForProfileAndLevel(profile, level);
-
- if (err != OK) {
- return err;
- }
-
- h264type.eProfile = static_cast<OMX_VIDEO_AVCPROFILETYPE>(profile);
- h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
- }
-
- // XXX
- if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
- ALOGW("Use baseline profile instead of %d for AVC recording",
- h264type.eProfile);
- h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
- }
-
- if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- h264type.nSliceHeaderSpacing = 0;
- h264type.bUseHadamard = OMX_TRUE;
- h264type.nRefFrames = 1;
- h264type.nBFrames = 0;
- h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
- if (h264type.nPFrames == 0) {
- h264type.nAllowedPictureTypes = OMX_VIDEO_PictureTypeI;
- }
- h264type.nRefIdx10ActiveMinus1 = 0;
- h264type.nRefIdx11ActiveMinus1 = 0;
- h264type.bEntropyCodingCABAC = OMX_FALSE;
- h264type.bWeightedPPrediction = OMX_FALSE;
- h264type.bconstIpred = OMX_FALSE;
- h264type.bDirect8x8Inference = OMX_FALSE;
- h264type.bDirectSpatialTemporal = OMX_FALSE;
- h264type.nCabacInitIdc = 0;
- }
-
- if (h264type.nBFrames != 0) {
- h264type.nAllowedPictureTypes |= OMX_VIDEO_PictureTypeB;
- }
-
- h264type.bEnableUEP = OMX_FALSE;
- h264type.bEnableFMO = OMX_FALSE;
- h264type.bEnableASO = OMX_FALSE;
- h264type.bEnableRS = OMX_FALSE;
- h264type.bFrameMBsOnly = OMX_TRUE;
- h264type.bMBAFF = OMX_FALSE;
- h264type.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable;
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamVideoAvc, &h264type, sizeof(h264type));
-
- if (err != OK) {
- return err;
- }
-
- return configureBitrate(bitrate, bitrateMode);
-}
-
-status_t DashCodec::verifySupportForProfileAndLevel(
- int32_t profile, int32_t level) {
- OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
- InitOMXParams(&params);
- params.nPortIndex = kPortIndexOutput;
-
- for (params.nProfileIndex = 0;; ++params.nProfileIndex) {
- status_t err = mOMX->getParameter(
- mNode,
- OMX_IndexParamVideoProfileLevelQuerySupported,
- &params,
- sizeof(params));
-
- if (err != OK) {
- return err;
- }
-
- int32_t supportedProfile = static_cast<int32_t>(params.eProfile);
- int32_t supportedLevel = static_cast<int32_t>(params.eLevel);
-
- if (profile == supportedProfile && level <= supportedLevel) {
- return OK;
- }
- }
-}
-
-status_t DashCodec::configureBitrate(
- int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode) {
- OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
- InitOMXParams(&bitrateType);
- bitrateType.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoBitrate,
- &bitrateType, sizeof(bitrateType));
-
- if (err != OK) {
- return err;
- }
-
- bitrateType.eControlRate = bitrateMode;
- bitrateType.nTargetBitrate = bitrate;
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamVideoBitrate,
- &bitrateType, sizeof(bitrateType));
-}
-
-status_t DashCodec::setupErrorCorrectionParameters() {
- OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrectionType;
- InitOMXParams(&errorCorrectionType);
- errorCorrectionType.nPortIndex = kPortIndexOutput;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamVideoErrorCorrection,
- &errorCorrectionType, sizeof(errorCorrectionType));
-
- if (err != OK) {
- return OK; // Optional feature. Ignore this failure
- }
-
- errorCorrectionType.bEnableHEC = OMX_FALSE;
- errorCorrectionType.bEnableResync = OMX_TRUE;
- errorCorrectionType.nResynchMarkerSpacing = 256;
- errorCorrectionType.bEnableDataPartitioning = OMX_FALSE;
- errorCorrectionType.bEnableRVLC = OMX_FALSE;
-
- return mOMX->setParameter(
- mNode, OMX_IndexParamVideoErrorCorrection,
- &errorCorrectionType, sizeof(errorCorrectionType));
-}
-
-status_t DashCodec::setVideoFormatOnPort(
- OMX_U32 portIndex,
- int32_t width, int32_t height, OMX_VIDEO_CODINGTYPE compressionFormat) {
- OMX_PARAM_PORTDEFINITIONTYPE def;
- InitOMXParams(&def);
- def.nPortIndex = portIndex;
-
- OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
- status_t err = mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- CHECK_EQ(err, (status_t)OK);
-
- if (portIndex == kPortIndexInput) {
- // XXX Need a (much) better heuristic to compute input buffer sizes.
- const size_t X = 64 * 1024;
- if (def.nBufferSize < X) {
- def.nBufferSize = X;
- }
- }
-
- CHECK_EQ((int)def.eDomain, (int)OMX_PortDomainVideo);
-
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
-
- if (portIndex == kPortIndexInput) {
- video_def->eCompressionFormat = compressionFormat;
- video_def->eColorFormat = OMX_COLOR_FormatUnused;
- }
-
- err = mOMX->setParameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-
- return err;
-}
-
-status_t DashCodec::initNativeWindow() {
- if (mNativeWindow != NULL) {
- return mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_TRUE);
- }
-
- mOMX->enableGraphicBuffers(mNode, kPortIndexOutput, OMX_FALSE);
- return OK;
-}
-
-size_t DashCodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
- size_t n = 0;
-
- for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- const BufferInfo &info = mBuffers[portIndex].itemAt(i);
-
- if (info.mStatus == BufferInfo::OWNED_BY_COMPONENT) {
- ++n;
- }
- }
-
- return n;
-}
-
-size_t DashCodec::countBuffersOwnedByNativeWindow() const {
- size_t n = 0;
-
- for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
- const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
-
- if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- ++n;
- }
- }
-
- return n;
-}
-
-void DashCodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
- if (mNativeWindow == NULL) {
- return;
- }
-
- int minUndequeuedBufs = 0;
- status_t err = mNativeWindow->query(
- mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBufs);
-
- if (err != OK) {
- ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
- mComponentName.c_str(), strerror(-err), -err);
-
- minUndequeuedBufs = 0;
- }
-
- while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
- && dequeueBufferFromNativeWindow() != NULL) {
- // these buffers will be submitted as regular buffers; account for this
- if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
- --mMetaDataBuffersToSubmit;
- }
- }
-}
-
-bool DashCodec::allYourBuffersAreBelongToUs(
- OMX_U32 portIndex) {
- for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
- BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
-
- if (info->mStatus != BufferInfo::OWNED_BY_US
- && info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- ALOGV("[%s] Buffer %p on port %ld still has status %d",
- mComponentName.c_str(),
- info->mBufferID, portIndex, info->mStatus);
- return false;
- }
- }
-
- return true;
-}
-
-bool DashCodec::allYourBuffersAreBelongToUs() {
- return allYourBuffersAreBelongToUs(kPortIndexInput)
- && allYourBuffersAreBelongToUs(kPortIndexOutput);
-}
-
-void DashCodec::deferMessage(const sp<AMessage> &msg) {
- bool wasEmptyBefore = mDeferredQueue.empty();
- mDeferredQueue.push_back(msg);
-}
-
-void DashCodec::processDeferredMessages() {
- List<sp<AMessage> > queue = mDeferredQueue;
- mDeferredQueue.clear();
-
- List<sp<AMessage> >::iterator it = queue.begin();
- while (it != queue.end()) {
- onMessageReceived(*it++);
- }
-}
-
-void DashCodec::queueNextFormat() {
- OMX_PARAM_PORTDEFINITIONTYPE* def = new OMX_PARAM_PORTDEFINITIONTYPE();
- InitOMXParams(def);
- def->nPortIndex = kPortIndexOutput;
-
- CHECK_EQ(mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, def, sizeof(*def)),
- (status_t)OK);
-
- CHECK_EQ((int)def->eDir, (int)OMX_DirOutput);
- mFormats.push_back(def);
-
- OMX_CONFIG_RECTTYPE* rect = new OMX_CONFIG_RECTTYPE();
- InitOMXParams(rect);
- rect->nPortIndex = kPortIndexOutput;
- if (mOMX->getConfig(mNode, OMX_IndexConfigCommonOutputCrop, rect, sizeof(*rect)) != OK) {
- mOutputCrops.push_back(NULL);
- } else {
- mOutputCrops.push_back(rect);
- }
-}
-
-void DashCodec::clearCachedFormats() {
- for (size_t i = 0 ; i < mOutputCrops.size(); i++)
- {
- if (mOutputCrops[i])
- {
- delete mOutputCrops[i];
- }
- }
- for (size_t i = 0 ; i < mFormats.size(); i++)
- {
- if (mFormats[i])
- {
- delete mFormats[i];
- }
- }
- mOutputCrops.clear();
- mFormats.clear();
-}
-
-void DashCodec::sendFormatChange() {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatOutputFormatChanged);
- bool useCachedConfig = false;
- OMX_PARAM_PORTDEFINITIONTYPE* def;
- if (mFormats.size() > 0) {
- useCachedConfig = true;
- def = mFormats[0];
- mFormats.removeAt(0);
- } else {
- def = new OMX_PARAM_PORTDEFINITIONTYPE();
- InitOMXParams(def);
- def->nPortIndex = kPortIndexOutput;
-
- CHECK_EQ(mOMX->getParameter(
- mNode, OMX_IndexParamPortDefinition, def, sizeof(*def)),
- (status_t)OK);
-
- CHECK_EQ((int)def->eDir, (int)OMX_DirOutput);
- }
- switch (def->eDomain) {
- case OMX_PortDomainVideo:
- {
- OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def->format.video;
-
- notify->setString("mime", MEDIA_MIMETYPE_VIDEO_RAW);
- notify->setInt32("width", videoDef->nFrameWidth);
- notify->setInt32("height", videoDef->nFrameHeight);
- notify->setInt32("stride", videoDef->nStride);
- notify->setInt32("slice-height", videoDef->nSliceHeight);
- notify->setInt32("color-format", videoDef->eColorFormat);
- ALOGV("sendformatchange: %lu %lu", videoDef->nFrameWidth, videoDef->nFrameHeight);
-
- //If dynamic buffering mode cache the latest width and height. Will be used for VENUS macors to calculate filledLen in fbd's.
- if(mStoreMetaDataInOutputBuffers)
- {
- mCurrentWidth = videoDef->nFrameWidth;
- mCurrentHeight = videoDef->nFrameHeight;
- }
-
- OMX_CONFIG_RECTTYPE* rect;
- bool hasValidCrop = true;
- if (useCachedConfig) {
- rect = mOutputCrops[0];
- mOutputCrops.removeAt(0);
- if (rect == NULL) {
- rect = new OMX_CONFIG_RECTTYPE();
- hasValidCrop = false;
- }
- } else {
- rect = new OMX_CONFIG_RECTTYPE();
- InitOMXParams(rect);
- rect->nPortIndex = kPortIndexOutput;
- hasValidCrop = (mOMX->getConfig(
- mNode, OMX_IndexConfigCommonOutputCrop,
- rect, sizeof(*rect)) == OK);
- }
-
- if (!hasValidCrop) {
- rect->nLeft = 0;
- rect->nTop = 0;
- rect->nWidth = videoDef->nFrameWidth;
- rect->nHeight = videoDef->nFrameHeight;
- }
-
- CHECK_GE(rect->nLeft, 0);
- CHECK_GE(rect->nTop, 0);
- CHECK_GE(rect->nWidth, 0u);
- CHECK_GE(rect->nHeight, 0u);
- CHECK_LE(rect->nLeft + rect->nWidth - 1, videoDef->nFrameWidth);
- CHECK_LE(rect->nTop + rect->nHeight - 1, videoDef->nFrameHeight);
-
- notify->setRect(
- "crop",
- rect->nLeft,
- rect->nTop,
- rect->nLeft + rect->nWidth - 1,
- rect->nTop + rect->nHeight - 1);
-
- if (mNativeWindow != NULL) {
- android_native_rect_t crop;
- crop.left = rect->nLeft;
- crop.top = rect->nTop;
- crop.right = rect->nLeft + rect->nWidth;
- crop.bottom = rect->nTop + rect->nHeight;
-
- CHECK_EQ(0, native_window_set_crop(
- mNativeWindow.get(), &crop));
- }
- delete rect;
- break;
- }
-
- case OMX_PortDomainAudio:
- {
- OMX_AUDIO_PORTDEFINITIONTYPE *audioDef = &def->format.audio;
- CHECK_EQ((int)audioDef->eEncoding, (int)OMX_AUDIO_CodingPCM);
-
- OMX_AUDIO_PARAM_PCMMODETYPE params;
- InitOMXParams(&params);
- params.nPortIndex = kPortIndexOutput;
-
- CHECK_EQ(mOMX->getParameter(
- mNode, OMX_IndexParamAudioPcm,
- &params, sizeof(params)),
- (status_t)OK);
-
- CHECK(params.nChannels == 1 || params.bInterleaved);
- CHECK_EQ(params.nBitPerSample, 16u);
- CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned);
- CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear);
-
- notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
- notify->setInt32("channel-count", params.nChannels);
- notify->setInt32("sample-rate", params.nSamplingRate);
- if (mEncoderDelay + mEncoderPadding) {
- size_t frameSize = params.nChannels * sizeof(int16_t);
- if (mSkipCutBuffer != NULL) {
- size_t prevbufsize = mSkipCutBuffer->size();
- if (prevbufsize != 0) {
- ALOGW("Replacing SkipCutBuffer holding %d bytes", prevbufsize);
- }
- }
- mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
- mEncoderPadding * frameSize);
- }
-
- if (mChannelMaskPresent) {
- notify->setInt32("channel-mask", mChannelMask);
- }
-
- break;
- }
-
- default:
- TRESPASS();
- }
-
- notify->post();
- delete def;
- mSentFormat = true;
-}
-
-void DashCodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatError);
- notify->setInt32("omx-error", error);
- notify->setInt32("err", internalError);
- notify->post();
-}
-
-status_t DashCodec::PushBlankBuffersToNativeWindow(sp<ANativeWindow> nativeWindow) {
- status_t err = NO_ERROR;
- ANativeWindowBuffer* anb = NULL;
- int numBufs = 0;
- int minUndequeuedBufs = 0;
-
- // We need to reconnect to the ANativeWindow as a CPU client to ensure that
- // no frames get dropped by SurfaceFlinger assuming that these are video
- // frames.
- err = native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_set_buffers_dimensions(
- nativeWindow.get(),
- 1,
- 1);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: native_window_set_buffers_dimensions failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
- err = native_window_set_buffers_format(
- nativeWindow.get(),
- HAL_PIXEL_FORMAT_RGBX_8888);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: native_window_set_buffers_format failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_set_scaling_mode(nativeWindow.get(),
- NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = native_window_set_usage(nativeWindow.get(),
- GRALLOC_USAGE_SW_WRITE_OFTEN);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = nativeWindow->query(nativeWindow.get(),
- NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
- "failed: %s (%d)", strerror(-err), -err);
- goto error;
- }
-
- numBufs = minUndequeuedBufs + 1;
- err = native_window_set_buffer_count(nativeWindow.get(), numBufs);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- // We push numBufs + 1 buffers to ensure that we've drawn into the same
- // buffer twice. This should guarantee that the buffer has been displayed
- // on the screen and then been replaced, so an previous video frames are
- // guaranteed NOT to be currently displayed.
- for (int i = 0; i < numBufs + 1; i++) {
- int fenceFd = -1;
- err = native_window_dequeue_buffer_and_wait(nativeWindow.get(), &anb);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
- // Fill the buffer with the a 1x1 checkerboard pattern ;)
- uint32_t* img = NULL;
- err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: lock failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- *img = 0;
-
- err = buf->unlock();
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: unlock failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = nativeWindow->queueBuffer(nativeWindow.get(),
- buf->getNativeBuffer(), -1);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- anb = NULL;
- }
-
-error:
-
- if (err != NO_ERROR) {
- // Clean up after an error.
- if (anb != NULL) {
- nativeWindow->cancelBuffer(nativeWindow.get(), anb, -1);
- }
-
- native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
-
- return err;
- } else {
- // Clean up after success.
- err = native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- return NO_ERROR;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::PortDescription::PortDescription() {
-}
-
-status_t DashCodec::requestIDRFrame() {
- if (!mIsEncoder) {
- return ERROR_UNSUPPORTED;
- }
-
- OMX_CONFIG_INTRAREFRESHVOPTYPE params;
- InitOMXParams(&params);
-
- params.nPortIndex = kPortIndexOutput;
- params.IntraRefreshVOP = OMX_TRUE;
-
- return mOMX->setConfig(
- mNode,
- OMX_IndexConfigVideoIntraVOPRefresh,
- &params,
- sizeof(params));
-}
-
-void DashCodec::PortDescription::addBuffer(
- IOMX::buffer_id id, const sp<ABuffer> &buffer) {
- mBufferIDs.push_back(id);
- mBuffers.push_back(buffer);
-}
-
-size_t DashCodec::PortDescription::countBuffers() {
- return mBufferIDs.size();
-}
-
-IOMX::buffer_id DashCodec::PortDescription::bufferIDAt(size_t index) const {
- return mBufferIDs.itemAt(index);
-}
-
-sp<ABuffer> DashCodec::PortDescription::bufferAt(size_t index) const {
- return mBuffers.itemAt(index);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::BaseState::BaseState(DashCodec *codec, const sp<AState> &parentState)
- : AState(parentState),
- mCodec(codec) {
-}
-
-DashCodec::BaseState::PortMode DashCodec::BaseState::getPortMode(OMX_U32 /*portIndex*/) {
- return KEEP_BUFFERS;
-}
-
-bool DashCodec::BaseState::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatInputBufferFilled:
- {
- onInputBufferFilled(msg);
- break;
- }
-
- case kWhatOutputBufferDrained:
- {
- onOutputBufferDrained(msg);
- break;
- }
-
- case DashCodec::kWhatOMXMessage:
- {
- return onOMXMessage(msg);
- }
-
- case DashCodec::kWhatFlush:
- {
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatFlushCompleted);
- notify->post();
- return true;
- }
-
- default:
- return false;
- }
-
- return true;
-}
-
-bool DashCodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
- int32_t type;
- CHECK(msg->findInt32("type", &type));
-
- IOMX::node_id nodeID;
- CHECK(msg->findInt32("node", (int32_t*)&nodeID));
- CHECK_EQ(nodeID, mCodec->mNode);
-
- switch (type) {
- case omx_message::EVENT:
- {
- int32_t event, data1, data2;
- CHECK(msg->findInt32("event", &event));
- CHECK(msg->findInt32("data1", &data1));
- CHECK(msg->findInt32("data2", &data2));
-
- if (event == OMX_EventCmdComplete
- && data1 == OMX_CommandFlush
- && data2 == (int32_t)OMX_ALL) {
- // Use of this notification is not consistent across
- // implementations. We'll drop this notification and rely
- // on flush-complete notifications on the individual port
- // indices instead.
-
- return true;
- }
-
- return onOMXEvent(
- static_cast<OMX_EVENTTYPE>(event),
- static_cast<OMX_U32>(data1),
- static_cast<OMX_U32>(data2));
- }
-
- case omx_message::EMPTY_BUFFER_DONE:
- {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
-
- return onOMXEmptyBufferDone(bufferID);
- }
-
- case omx_message::FILL_BUFFER_DONE:
- {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
-
- int32_t rangeOffset, rangeLength, flags;
- int64_t timeUs;
- void *platformPrivate = NULL;
- void *dataPtr = NULL;
-
- CHECK(msg->findInt32("range_offset", &rangeOffset));
- CHECK(msg->findInt32("range_length", &rangeLength));
- CHECK(msg->findInt32("flags", &flags));
- CHECK(msg->findInt64("timestamp", &timeUs));
- //CHECK(msg->findPointer("platform_private", (void **)&platformPrivate));
- //CHECK(msg->findPointer("data_ptr", (void **)&dataPtr));
-
- return onOMXFillBufferDone(
- bufferID,
- (size_t)rangeOffset, (size_t)rangeLength,
- (OMX_U32)flags,
- timeUs,
- platformPrivate,
- dataPtr);
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-bool DashCodec::BaseState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- if (event != OMX_EventError) {
- ALOGV("[%s] EVENT(%d, 0x%08lx, 0x%08lx)",
- mCodec->mComponentName.c_str(), event, data1, data2);
-
- return false;
- }
-
- ALOGE("[%s] ERROR(0x%08lx)", mCodec->mComponentName.c_str(), data1);
-
- mCodec->signalError((OMX_ERRORTYPE)data1);
-
- return true;
-}
-
-bool DashCodec::BaseState::onOMXEmptyBufferDone(IOMX::buffer_id bufferID) {
- ALOGV("[%s] onOMXEmptyBufferDone %p",
- mCodec->mComponentName.c_str(), bufferID);
-
- BufferInfo *info =
- mCodec->findBufferByID(kPortIndexInput, bufferID);
-
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
- info->mStatus = BufferInfo::OWNED_BY_US;
-
- const sp<AMessage> &bufferMeta = info->mData->meta();
- void *mediaBuffer;
- if (bufferMeta->findPointer("mediaBuffer", &mediaBuffer)
- && mediaBuffer != NULL) {
- // We're in "store-metadata-in-buffers" mode, the underlying
- // OMX component had access to data that's implicitly refcounted
- // by this "mediaBuffer" object. Now that the OMX component has
- // told us that it's done with the input buffer, we can decrement
- // the mediaBuffer's reference count.
-
- ALOGV("releasing mbuf %p", mediaBuffer);
-
- ((MediaBuffer *)mediaBuffer)->release();
- mediaBuffer = NULL;
-
- bufferMeta->setPointer("mediaBuffer", NULL);
- }
-
- PortMode mode = getPortMode(kPortIndexInput);
-
- switch (mode) {
- case KEEP_BUFFERS:
- break;
-
- case RESUBMIT_BUFFERS:
- postFillThisBuffer(info);
- break;
-
- default:
- {
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
- TRESPASS(); // Not currently used
- break;
- }
- }
-
- return true;
-}
-
-void DashCodec::BaseState::postFillThisBuffer(BufferInfo *info) {
- if (mCodec->mPortEOS[kPortIndexInput]) {
- return;
- }
-
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
- notify->setInt32("buffer-id", info->mBufferID);
-
- info->mData->meta()->clear();
- notify->setBuffer("buffer", info->mData);
-
- sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
- reply->setInt32("buffer-id", info->mBufferID);
-
- notify->setMessage("reply", reply);
-
- notify->post();
-
- info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
-}
-
-void DashCodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
-
- sp<ABuffer> buffer;
- int32_t err = OK;
- bool eos = false;
-
- if (!msg->findBuffer("buffer", &buffer)) {
- CHECK(msg->findInt32("err", &err));
-
- ALOGV("[%s] saw error %d instead of an input buffer",
- mCodec->mComponentName.c_str(), err);
-
- buffer.clear();
-
- eos = true;
- }
-
- int32_t tmp;
- if (buffer != NULL && buffer->meta()->findInt32("eos", &tmp) && tmp) {
- eos = true;
- err = ERROR_END_OF_STREAM;
- }
-
- BufferInfo *info = mCodec->findBufferByID(kPortIndexInput, bufferID);
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_UPSTREAM);
-
- info->mStatus = BufferInfo::OWNED_BY_US;
-
- PortMode mode = getPortMode(kPortIndexInput);
-
- switch (mode) {
- case KEEP_BUFFERS:
- {
- if (eos) {
- if (!mCodec->mPortEOS[kPortIndexInput]) {
- mCodec->mPortEOS[kPortIndexInput] = true;
- mCodec->mInputEOSResult = err;
- }
- }
- break;
- }
-
- case RESUBMIT_BUFFERS:
- {
- if (buffer != NULL && !mCodec->mPortEOS[kPortIndexInput]) {
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
- OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
-
- int32_t isCSD;
- if (buffer->meta()->findInt32("csd", &isCSD) && isCSD != 0) {
- flags |= OMX_BUFFERFLAG_CODECCONFIG;
- }
-
- if (eos) {
- flags |= OMX_BUFFERFLAG_EOS;
- }
-
- if (buffer != info->mData) {
- ALOGV("[%s] Needs to copy input data for buffer %p. (%p != %p)",
- mCodec->mComponentName.c_str(),
- bufferID,
- buffer.get(), info->mData.get());
-
- CHECK_LE(buffer->size(), info->mData->capacity());
- memcpy(info->mData->data(), buffer->data(), buffer->size());
- }
-
- if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
- ALOGV("[%s] calling emptyBuffer %p w/ codec specific data",
- mCodec->mComponentName.c_str(), bufferID);
- } else if (flags & OMX_BUFFERFLAG_EOS) {
- ALOGV("[%s] calling emptyBuffer %p w/ EOS",
- mCodec->mComponentName.c_str(), bufferID);
- } else {
-#if TRACK_BUFFER_TIMING
- ALOGI("[%s] calling emptyBuffer %p w/ time %lld us",
- mCodec->mComponentName.c_str(), bufferID, timeUs);
-#else
- ALOGV("[%s] calling emptyBuffer %p w/ time %lld us",
- mCodec->mComponentName.c_str(), bufferID, timeUs);
-#endif
- }
-
-#if TRACK_BUFFER_TIMING
- DashCodec::BufferStats stats;
- stats.mEmptyBufferTimeUs = ALooper::GetNowUs();
- stats.mFillBufferDoneTimeUs = -1ll;
- mCodec->mBufferStats.add(timeUs, stats);
-#endif
-
- if (mCodec->mStoreMetaDataInOutputBuffers) {
- // try to submit an output buffer for each input buffer
- PortMode outputMode = getPortMode(kPortIndexOutput);
-
- ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
- mCodec->mMetaDataBuffersToSubmit,
- (outputMode == FREE_BUFFERS ? "FREE" :
- outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
- if (outputMode == RESUBMIT_BUFFERS) {
- CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
- (status_t)OK);
- }
- }
-
- CHECK_EQ(mCodec->mOMX->emptyBuffer(
- mCodec->mNode,
- bufferID,
- 0,
- buffer->size(),
- flags,
- timeUs),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
-
- if (!eos) {
- getMoreInputDataIfPossible();
- } else {
- ALOGV("[%s] Signalled EOS on the input port",
- mCodec->mComponentName.c_str());
-
- mCodec->mPortEOS[kPortIndexInput] = true;
- mCodec->mInputEOSResult = err;
- }
- } else if (!mCodec->mPortEOS[kPortIndexInput]) {
- if (err != ERROR_END_OF_STREAM) {
- ALOGV("[%s] Signalling EOS on the input port "
- "due to error %d",
- mCodec->mComponentName.c_str(), err);
- } else {
- ALOGV("[%s] Signalling EOS on the input port",
- mCodec->mComponentName.c_str());
- }
-
- if (mCodec->mStoreMetaDataInOutputBuffers) {
- // try to submit an output buffer for each input buffer
- PortMode outputMode = getPortMode(kPortIndexOutput);
-
- ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
- mCodec->mMetaDataBuffersToSubmit,
- (outputMode == FREE_BUFFERS ? "FREE" :
- outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
- if (outputMode == RESUBMIT_BUFFERS) {
- CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
- (status_t)OK);
- }
- }
-
- ALOGV("[%s] calling emptyBuffer %p signalling EOS",
- mCodec->mComponentName.c_str(), bufferID);
-
- CHECK_EQ(mCodec->mOMX->emptyBuffer(
- mCodec->mNode,
- bufferID,
- 0,
- 0,
- OMX_BUFFERFLAG_EOS,
- 0),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
-
- mCodec->mPortEOS[kPortIndexInput] = true;
- mCodec->mInputEOSResult = err;
- }
- break;
-
- default:
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
- break;
- }
- }
-}
-
-void DashCodec::BaseState::getMoreInputDataIfPossible() {
- if (mCodec->mPortEOS[kPortIndexInput]) {
- return;
- }
-
- BufferInfo *eligible = NULL;
-
- for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
-
-#if 0
- if (info->mStatus == BufferInfo::OWNED_BY_UPSTREAM) {
- // There's already a "read" pending.
- return;
- }
-#endif
-
- if (info->mStatus == BufferInfo::OWNED_BY_US) {
- eligible = info;
- }
- }
-
- if (eligible == NULL) {
- return;
- }
-
- postFillThisBuffer(eligible);
-}
-
-bool DashCodec::BaseState::onOMXFillBufferDone(
- IOMX::buffer_id bufferID,
- size_t rangeOffset, size_t rangeLength,
- OMX_U32 flags,
- int64_t timeUs,
- void * /*platformPrivate*/,
- void * /*dataPtr*/) {
- ALOGV("[%s] onOMXFillBufferDone %p time %lld us, flags = 0x%08lx",
- mCodec->mComponentName.c_str(), bufferID, timeUs, flags);
-
- ssize_t index;
-
-#if TRACK_BUFFER_TIMING
- index = mCodec->mBufferStats.indexOfKey(timeUs);
- if (index >= 0) {
- DashCodec::BufferStats *stats = &mCodec->mBufferStats.editValueAt(index);
- stats->mFillBufferDoneTimeUs = ALooper::GetNowUs();
-
- ALOGI("frame PTS %lld: %lld",
- timeUs,
- stats->mFillBufferDoneTimeUs - stats->mEmptyBufferTimeUs);
-
- mCodec->mBufferStats.removeItemsAt(index);
- stats = NULL;
- }
-#endif
-
- BufferInfo *info =
- mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
-
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
-
- info->mDequeuedAt = ++mCodec->mDequeueCounter;
- info->mStatus = BufferInfo::OWNED_BY_US;
-
- PortMode mode = getPortMode(kPortIndexOutput);
-
- switch (mode) {
- case KEEP_BUFFERS:
- break;
-
- case RESUBMIT_BUFFERS:
- {
- if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
- ALOGV("[%s] calling fillBuffer %p",
- mCodec->mComponentName.c_str(), info->mBufferID);
-
- CHECK_EQ(mCodec->mOMX->fillBuffer(
- mCodec->mNode, info->mBufferID),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- break;
- }
-
- if (flags & OMX_BUFFERFLAG_EOS) {
- ALOGE("[%s] saw output EOS", mCodec->mComponentName.c_str());
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatEOS);
- notify->setInt32("err", mCodec->mInputEOSResult);
- notify->post();
-
- mCodec->mPortEOS[kPortIndexOutput] = true;
- break;
- }
- if (!mCodec->mIsEncoder && !mCodec->mSentFormat && !mCodec->mAdaptivePlayback) {
- mCodec->sendFormatChange();
- }
-
- if (mCodec->mNativeWindow == NULL) {
- info->mData->setRange(rangeOffset, rangeLength);
-
-#if 0
- if (IsIDR(info->mData)) {
- ALOGI("IDR frame");
- }
-#endif
- }
-
- if (mCodec->mSkipCutBuffer != NULL) {
- mCodec->mSkipCutBuffer->submit(info->mData);
- }
- info->mData->meta()->setInt64("timeUs", timeUs);
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
- notify->setInt32("buffer-id", info->mBufferID);
- notify->setBuffer("buffer", info->mData);
- notify->setInt32("flags", flags);
-
- if (flags & OMX_BUFFERFLAG_EXTRADATA)
- {
- OMX_U8* bufferHandle = NULL;
- int64_t nFilledLen = 0;
- int64_t nAllocLen = 0;
- int64_t nStartOffset = 0;
-
- OMX_BUFFERHEADERTYPE *pBufHdr = (OMX_BUFFERHEADERTYPE *)bufferID;
-
- nStartOffset = pBufHdr->nOffset;
-
- if(mCodec->mStoreMetaDataInOutputBuffers)
- {
- VideoDecoderOutputMetaData *metaData =
- reinterpret_cast<VideoDecoderOutputMetaData *>(
- pBufHdr->pBuffer);
-
- bufferHandle = const_cast<OMX_U8*>(
- reinterpret_cast<const OMX_U8*>(metaData->pHandle));
-
-#ifdef BFAMILY_TARGET /* Venus macros and dynamic mode support present only for B-family targets.*/
- nFilledLen = (VENUS_Y_STRIDE(COLOR_FMT_NV12, mCodec->mCurrentWidth)
- * VENUS_Y_SCANLINES(COLOR_FMT_NV12, mCodec->mCurrentHeight))
- + (VENUS_UV_STRIDE(COLOR_FMT_NV12, mCodec->mCurrentWidth)
- * VENUS_UV_SCANLINES(COLOR_FMT_NV12, mCodec->mCurrentHeight));
-
- nAllocLen = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mCodec->mCurrentWidth, mCodec->mCurrentHeight);
-#endif
- }
- else
- {
- bufferHandle = const_cast<OMX_U8*>(
- reinterpret_cast<const OMX_U8*>(pBufHdr->pBuffer));
-
- nFilledLen = pBufHdr->nFilledLen;
- nAllocLen = pBufHdr->nAllocLen;
- }
-
- ALOGV("[%s] Extradata present in decoded buffer."
- "gralloc handle = %p, filled length = %llu, allocated length = %llu, start offset = %llu",
- mCodec->mComponentName.c_str(), bufferHandle, nFilledLen, nAllocLen, nStartOffset);
-
- notify->setPointer("gralloc-handle", bufferHandle);
- notify->setInt64("filled-length", nFilledLen);
- notify->setInt64("alloc-length", nAllocLen);
- notify->setInt64("start-offset", nStartOffset);
- }
-
- sp<AMessage> reply =
- new AMessage(kWhatOutputBufferDrained, mCodec->id());
-
- if (!mCodec->mPostFormat && mCodec->mAdaptivePlayback){
- ALOGV("Resolution will change from this buffer, set a flag");
- reply->setInt32("resChange", 1);
- mCodec->mPostFormat = true;
- }
-
- reply->setInt32("buffer-id", info->mBufferID);
-
- notify->setMessage("reply", reply);
-
- notify->post();
-
- info->mStatus = BufferInfo::OWNED_BY_DOWNSTREAM;
-
- break;
- }
-
- default:
- {
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
-
- CHECK_EQ((status_t)OK,
- mCodec->freeBuffer(kPortIndexOutput, index));
- break;
- }
- }
-
- return true;
-}
-
-void DashCodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
- IOMX::buffer_id bufferID;
- CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
-
- ssize_t index;
- BufferInfo *info =
- mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
- if (mCodec->mAdaptivePlayback) {
- int32_t resChange = 0;
- if (msg->findInt32("resChange", &resChange) && resChange == 1) {
- ALOGV("Resolution change is sent to native window now ");
- mCodec->sendFormatChange();
- msg->setInt32("resChange", 0);
- }
- }
- int32_t render;
- if (mCodec->mNativeWindow != NULL
- && msg->findInt32("render", &render) && render != 0) {
- // The client wants this buffer to be rendered.
-
- status_t err;
- if ((err = mCodec->mNativeWindow->queueBuffer(
- mCodec->mNativeWindow.get(),
- info->mGraphicBuffer.get(), -1)) == OK) {
- info->mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
- } else {
- mCodec->signalError(OMX_ErrorUndefined, err);
- info->mStatus = BufferInfo::OWNED_BY_US;
- }
- } else {
- info->mStatus = BufferInfo::OWNED_BY_US;
- }
-
- PortMode mode = getPortMode(kPortIndexOutput);
-
- switch (mode) {
- case KEEP_BUFFERS:
- {
- // XXX fishy, revisit!!! What about the FREE_BUFFERS case below?
-
- if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- // We cannot resubmit the buffer we just rendered, dequeue
- // the spare instead.
-
- info = mCodec->dequeueBufferFromNativeWindow();
- }
- break;
- }
-
- case RESUBMIT_BUFFERS:
- {
- if (!mCodec->mPortEOS[kPortIndexOutput]) {
- if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- // We cannot resubmit the buffer we just rendered, dequeue
- // the spare instead.
-
- info = mCodec->dequeueBufferFromNativeWindow();
- }
-
- if (info != NULL) {
- ALOGV("[%s] calling fillBuffer %p",
- mCodec->mComponentName.c_str(), info->mBufferID);
-
- CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- }
- }
- break;
- }
-
- default:
- {
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
-
- CHECK_EQ((status_t)OK,
- mCodec->freeBuffer(kPortIndexOutput, index));
- break;
- }
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::UninitializedState::UninitializedState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-void DashCodec::UninitializedState::stateEntered() {
- ALOGV("Now uninitialized");
-}
-
-bool DashCodec::UninitializedState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case DashCodec::kWhatSetup:
- {
- onSetup(msg);
-
- handled = true;
- break;
- }
-
- case DashCodec::kWhatAllocateComponent:
- {
- onAllocateComponent(msg);
- handled = true;
- break;
- }
-
- case DashCodec::kWhatShutdown:
- {
- int32_t keepComponentAllocated;
- CHECK(msg->findInt32(
- "keepComponentAllocated", &keepComponentAllocated));
- CHECK(!keepComponentAllocated);
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
- notify->post();
-
- handled = true;
- break;
- }
-
- default:
- return BaseState::onMessageReceived(msg);
- }
-
- return handled;
-}
-
-void DashCodec::UninitializedState::onSetup(
- const sp<AMessage> &msg) {
- if (onAllocateComponent(msg)
- && mCodec->mLoadedState->onConfigureComponent(msg)) {
- mCodec->mLoadedState->onStart();
- }
-}
-
-bool DashCodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
- ALOGV("onAllocateComponent");
-
- CHECK(mCodec->mNode == NULL);
-
- OMXClient client;
- CHECK_EQ(client.connect(), (status_t)OK);
-
- sp<IOMX> omx = client.interface();
-
- Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
-
- AString mime;
-
- AString componentName;
- uint32_t quirks = 0;
- if (msg->findString("componentName", &componentName)) {
- ssize_t index = matchingCodecs.add();
- OMXCodec::CodecNameAndQuirks *entry = &matchingCodecs.editItemAt(index);
- entry->mName = String8(componentName.c_str());
-
- if (!OMXCodec::findCodecQuirks(
- componentName.c_str(), &entry->mQuirks)) {
- entry->mQuirks = 0;
- }
- } else {
- CHECK(msg->findString("mime", &mime));
-
- int32_t encoder;
- if (!msg->findInt32("encoder", &encoder)) {
- encoder = false;
- }
-
- OMXCodec::findMatchingCodecs(
- mime.c_str(),
- encoder, // createEncoder
- NULL, // matchComponentName
- 0, // flags
- &matchingCodecs);
- }
-
- sp<CodecObserver> observer = new CodecObserver;
- IOMX::node_id node = NULL;
-
- for (size_t matchIndex = 0; matchIndex < matchingCodecs.size();
- ++matchIndex) {
- componentName = matchingCodecs.itemAt(matchIndex).mName.string();
- if (mime.compare("video/hevc") == 0) {
- // for targets where there is only one decoder component, then dont look
- // for hybrid solution
- if ((matchingCodecs.size() > 1) &&
- (componentName.compare("OMX.qcom.video.decoder.hevchybrid") !=0)) {
- ALOGE("Ignoring Codec Component %s for mimeTye %s",
- componentName.c_str(),mime.c_str());
- continue;
- }
- }
- quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
- ALOGE("using Codec Component %s for mimeTye %s",componentName.c_str(),mime.c_str());
- pid_t tid = androidGetTid();
- int prevPriority = androidGetThreadPriority(tid);
- androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
- status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
- androidSetThreadPriority(tid, prevPriority);
-
- if (err == OK) {
- break;
- }
-
- node = NULL;
- }
-
- if (node == NULL) {
- if (!mime.empty()) {
- ALOGE("Unable to instantiate a decoder for type '%s'.",
- mime.c_str());
- } else {
- ALOGE("Unable to instantiate decoder '%s'.", componentName.c_str());
- }
-
- mCodec->signalError(OMX_ErrorComponentNotFound);
- return false;
- }
-
- sp<AMessage> notify = new AMessage(kWhatOMXMessage, mCodec->id());
- observer->setNotificationMessage(notify);
-
- mCodec->mComponentName = componentName;
- mCodec->mFlags = 0;
-
- if (componentName.endsWith(".secure")) {
- mCodec->mFlags |= kFlagIsSecure;
- mCodec->mFlags |= kFlagPushBlankBuffersToNativeWindowOnShutdown;
- }
-
- mCodec->mQuirks = quirks;
- mCodec->mOMX = omx;
- mCodec->mNode = node;
-
- mCodec->mPortEOS[kPortIndexInput] =
- mCodec->mPortEOS[kPortIndexOutput] = false;
-
- mCodec->mInputEOSResult = OK;
-
- {
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatComponentAllocated);
- notify->setString("componentName", mCodec->mComponentName.c_str());
- notify->post();
- }
-
- mCodec->changeState(mCodec->mLoadedState);
-
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::LoadedState::LoadedState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-void DashCodec::LoadedState::stateEntered() {
- ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
-
-mCodec->mDequeueCounter = 0;
- mCodec->mMetaDataBuffersToSubmit = 0;
-
- if (mCodec->mShutdownInProgress) {
- bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
-
- mCodec->mShutdownInProgress = false;
- mCodec->mKeepComponentAllocated = false;
-
- onShutdown(keepComponentAllocated);
- }
-}
-
-void DashCodec::LoadedState::onShutdown(bool keepComponentAllocated) {
- if (!keepComponentAllocated) {
- CHECK_EQ(mCodec->mOMX->freeNode(mCodec->mNode), (status_t)OK);
-
- mCodec->mNativeWindow.clear();
- mCodec->mNode = NULL;
- mCodec->mOMX.clear();
- mCodec->mQuirks = 0;
- mCodec->mFlags = 0;
- mCodec->mComponentName.clear();
-
- mCodec->changeState(mCodec->mUninitializedState);
- }
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
- notify->post();
-}
-
-bool DashCodec::LoadedState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case DashCodec::kWhatConfigureComponent:
- {
- onConfigureComponent(msg);
- handled = true;
- break;
- }
-
- case DashCodec::kWhatStart:
- {
- onStart();
- handled = true;
- break;
- }
-
- case DashCodec::kWhatShutdown:
- {
- int32_t keepComponentAllocated;
- CHECK(msg->findInt32(
- "keepComponentAllocated", &keepComponentAllocated));
-
- onShutdown(keepComponentAllocated);
-
- handled = true;
- break;
- }
-
- default:
- return BaseState::onMessageReceived(msg);
- }
-
- return handled;
-}
-
-bool DashCodec::LoadedState::onConfigureComponent(
- const sp<AMessage> &msg) {
- ALOGV("onConfigureComponent");
-
- CHECK(mCodec->mNode != NULL);
-
- int32_t value;
-
- if (msg->findInt32("secure-op", &value) && (value == 1)) {
- mCodec->mFlags |= kFlagIsSecureOPOnly;
- }
-
- sp<RefBase> obj;
- if (msg->findObject("native-window", &obj)
- && strncmp("OMX.google.", mCodec->mComponentName.c_str(), 11)) {
- sp<NativeWindowWrapper> nativeWindow(
- static_cast<NativeWindowWrapper *>(obj.get()));
- CHECK(nativeWindow != NULL);
- mCodec->mNativeWindow = nativeWindow->getNativeWindow();
-
- native_window_set_scaling_mode(
- mCodec->mNativeWindow.get(),
- NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- }
- CHECK_EQ((status_t)OK, mCodec->initNativeWindow());
-
- AString mime;
- CHECK(msg->findString("mime", &mime));
-
- status_t err = mCodec->configureCodec(mime.c_str(), msg);
-
- if (err != OK) {
- ALOGE("[%s] configureCodec returning error %d",
- mCodec->mComponentName.c_str(), err);
-
- mCodec->signalError(OMX_ErrorUndefined, err);
- return false;
- }
-
- {
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatComponentConfigured);
- notify->post();
- }
-
- return true;
-}
-
-void DashCodec::LoadedState::onStart() {
- ALOGV("onStart");
-
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
- (status_t)OK);
-
- mCodec->changeState(mCodec->mLoadedToIdleState);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::LoadedToIdleState::LoadedToIdleState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-void DashCodec::LoadedToIdleState::stateEntered() {
- ALOGV("[%s] Now Loaded->Idle", mCodec->mComponentName.c_str());
-
- status_t err;
- if ((err = allocateBuffers()) != OK) {
- ALOGE("Failed to allocate buffers after transitioning to IDLE state "
- "(error 0x%08x)",
- err);
-
- mCodec->signalError(OMX_ErrorUndefined, err);
-
- mCodec->changeState(mCodec->mLoadedState);
- }
-}
-
-status_t DashCodec::LoadedToIdleState::allocateBuffers() {
- status_t err = mCodec->allocateBuffersOnPort(kPortIndexInput);
-
- if (err != OK) {
- return err;
- }
-
- return mCodec->allocateBuffersOnPort(kPortIndexOutput);
-}
-
-bool DashCodec::LoadedToIdleState::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatShutdown:
- {
- mCodec->deferMessage(msg);
- return true;
- }
-
- default:
- return BaseState::onMessageReceived(msg);
- }
-}
-
-bool DashCodec::LoadedToIdleState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
- CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
-
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandStateSet, OMX_StateExecuting),
- (status_t)OK);
-
- mCodec->changeState(mCodec->mIdleToExecutingState);
-
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::IdleToExecutingState::IdleToExecutingState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-void DashCodec::IdleToExecutingState::stateEntered() {
- ALOGV("[%s] Now Idle->Executing", mCodec->mComponentName.c_str());
-}
-
-bool DashCodec::IdleToExecutingState::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatShutdown:
- {
- mCodec->deferMessage(msg);
- return true;
- }
-
- default:
- return BaseState::onMessageReceived(msg);
- }
-}
-
-bool DashCodec::IdleToExecutingState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
- CHECK_EQ(data2, (OMX_U32)OMX_StateExecuting);
-
- mCodec->mExecutingState->resume();
- mCodec->changeState(mCodec->mExecutingState);
-
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::ExecutingState::ExecutingState(DashCodec *codec)
- : BaseState(codec),
- mActive(false) {
-}
-
-DashCodec::BaseState::PortMode DashCodec::ExecutingState::getPortMode(
- OMX_U32 /*portIndex*/) {
- return RESUBMIT_BUFFERS;
-}
-
-void DashCodec::ExecutingState::submitOutputMetaBuffers() {
- // submit as many buffers as there are input buffers with the codec
- // in case we are in port reconfiguring
- for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
-
- if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
- if (mCodec->submitOutputMetaDataBuffer() != OK)
- break;
- }
- }
-}
-
-void DashCodec::ExecutingState::submitRegularOutputBuffers() {
- for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
- BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
-
- if (mCodec->mNativeWindow != NULL) {
- CHECK(info->mStatus == BufferInfo::OWNED_BY_US
- || info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW);
-
- if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- continue;
- }
- } else {
- CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
- }
-
- ALOGV("[%s] calling fillBuffer %p",
- mCodec->mComponentName.c_str(), info->mBufferID);
-
- CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
- (status_t)OK);
-
- info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
- }
-}
-
-void DashCodec::ExecutingState::submitOutputBuffers() {
- submitRegularOutputBuffers();
- if (mCodec->mStoreMetaDataInOutputBuffers) {
- submitOutputMetaBuffers();
- }
-}
-
-void DashCodec::ExecutingState::resume() {
- if (mActive) {
- ALOGV("[%s] We're already active, no need to resume.",
- mCodec->mComponentName.c_str());
-
- return;
- }
-
- submitOutputBuffers();
-
- // Post the first input buffer.
- CHECK_GT(mCodec->mBuffers[kPortIndexInput].size(), 0u);
- BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(0);
-
- postFillThisBuffer(info);
-
- mActive = true;
-}
-
-void DashCodec::ExecutingState::stateEntered() {
- ALOGV("[%s] Now Executing", mCodec->mComponentName.c_str());
-
- mCodec->processDeferredMessages();
-}
-
-bool DashCodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatShutdown:
- {
- int32_t keepComponentAllocated;
- CHECK(msg->findInt32(
- "keepComponentAllocated", &keepComponentAllocated));
-
- mCodec->mShutdownInProgress = true;
- mCodec->mKeepComponentAllocated = keepComponentAllocated;
-
- mActive = false;
-
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandStateSet, OMX_StateIdle),
- (status_t)OK);
-
- mCodec->changeState(mCodec->mExecutingToIdleState);
-
- handled = true;
- break;
- }
-
- case kWhatFlush:
- {
- ALOGV("[%s] ExecutingState flushing now "
- "(codec owns %d/%d input, %d/%d output).",
- mCodec->mComponentName.c_str(),
- mCodec->countBuffersOwnedByComponent(kPortIndexInput),
- mCodec->mBuffers[kPortIndexInput].size(),
- mCodec->countBuffersOwnedByComponent(kPortIndexOutput),
- mCodec->mBuffers[kPortIndexOutput].size());
-
- mActive = false;
-
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandFlush, OMX_ALL),
- (status_t)OK);
-
- mCodec->changeState(mCodec->mFlushingState);
- mCodec->clearCachedFormats();
- handled = true;
- break;
- }
-
- case kWhatResume:
- {
- resume();
-
- handled = true;
- break;
- }
-
- case kWhatRequestIDRFrame:
- {
- status_t err = mCodec->requestIDRFrame();
- if (err != OK) {
- ALOGW("Requesting an IDR frame failed.");
- }
-
- handled = true;
- break;
- }
-
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-bool DashCodec::ExecutingState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventPortSettingsChanged:
- {
- CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
-
- if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
- if (mCodec->mStoreMetaDataInOutputBuffers) {
- ALOGE("[%s] storeMetaDataInBuffers:Rcvd port settings changed event..disabling outputport",
- mCodec->mComponentName.c_str());
-mCodec->mMetaDataBuffersToSubmit = 0;
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode,
- OMX_CommandPortDisable, kPortIndexOutput),
- (status_t)OK);
-
- mCodec->freeOutputBuffersNotOwnedByComponent();
- mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
- }else {
- ALOGV("Flush output port before disable");
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandFlush, kPortIndexOutput),
- (status_t)OK);
-
- mCodec->changeState(mCodec->mFlushingOutputState);
- }
-
- } else if (data2 == OMX_IndexConfigCommonOutputCrop) {
- mCodec->mSentFormat = false;
- mCodec->mPostFormat = false;
- mCodec->queueNextFormat();
- } else {
- ALOGV("[%s] OMX_EventPortSettingsChanged 0x%08lx",
- mCodec->mComponentName.c_str(), data2);
- }
-
- return true;
- }
- case OMX_EventIndexsettingChanged:
- {
- ALOGW("[%s] Received OMX_EventIndexsettingChanged event ", mCodec->mComponentName.c_str());
- mCodec->mSentFormat = false;
- return true;
- }
- case OMX_EventBufferFlag:
- {
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::OutputPortSettingsChangedState::OutputPortSettingsChangedState(
- DashCodec *codec)
- : BaseState(codec) {
-}
-
-DashCodec::BaseState::PortMode DashCodec::OutputPortSettingsChangedState::getPortMode(
- OMX_U32 portIndex) {
- if (portIndex == kPortIndexOutput) {
- return FREE_BUFFERS;
- }
-
- CHECK_EQ(portIndex, (OMX_U32)kPortIndexInput);
-
- return RESUBMIT_BUFFERS;
-}
-
-bool DashCodec::OutputPortSettingsChangedState::onMessageReceived(
- const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatFlush:
- case kWhatShutdown:
- case kWhatResume:
- {
- if (msg->what() == kWhatResume) {
- ALOGV("[%s] Deferring resume", mCodec->mComponentName.c_str());
- }
-
- mCodec->deferMessage(msg);
- handled = true;
- break;
- }
- case kWhatWaitForPortEnable:
- {
- int32_t d1;
- int32_t d2;
- CHECK(msg->findInt32("data1", &d1));
- CHECK(msg->findInt32("data2", &d2));
-
- enableOutputPort((OMX_U32)d1, (OMX_U32)d2);
-
- handled = true;
- break;
- }
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-void DashCodec::OutputPortSettingsChangedState::enableOutputPort(OMX_U32 data1, OMX_U32 data2) {
- if (data1 == (OMX_U32)OMX_CommandPortDisable) {
- CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
-
- ALOGV("[%s] Output port now disabled.",
- mCodec->mComponentName.c_str());
- // All buffers should get freed before sending re-enabling outport after
- // portsetting change. OUT Buffers OWNED_BY_DOWNSTREAM, gets freed
- // only when renderer sends buffer for rendering.
- // Due to timing issue, buffers OWNED_BY_DOWNSTREAM dosent get freed
- // before exectution reaches here. hence wait for all such buffers
- // to get free and then proceed for enabling outport.
- if(!mCodec->mBuffers[kPortIndexOutput].isEmpty())
- {
- ALOGE(" Wait for outport Queue to be empty before re-enable port ");
- sp<AMessage> msg = new AMessage(kWhatWaitForPortEnable, mCodec->id());
- msg->setInt32("data1", data1);
- msg->setInt32("data2", data2);
- msg->post(10000ll); // poll again in a 10 milli second.
- return;
- }
-
- mCodec->mDealer[kPortIndexOutput].clear();
-
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandPortEnable, kPortIndexOutput),
- (status_t)OK);
-
- status_t err;
- if ((err = mCodec->allocateBuffersOnPort(kPortIndexOutput)) != OK) {
- ALOGE("Failed to allocate output port buffers after "
- "port reconfiguration (error 0x%08x)",
- err);
-
- mCodec->signalError(OMX_ErrorUndefined, err);
-
- // This is technically not correct, but appears to be
- // the only way to free the component instance.
- // Controlled transitioning from excecuting->idle
- // and idle->loaded seem impossible probably because
- // the output port never finishes re-enabling.
- mCodec->mShutdownInProgress = true;
- mCodec->mKeepComponentAllocated = false;
- mCodec->changeState(mCodec->mLoadedState);
- }
- }
-
- return;
-}
-
-void DashCodec::OutputPortSettingsChangedState::stateEntered() {
- ALOGV("[%s] Now handling output port settings change",
- mCodec->mComponentName.c_str());
-}
-
-bool DashCodec::OutputPortSettingsChangedState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- if (data1 == (OMX_U32)OMX_CommandPortDisable) {
- enableOutputPort(data1, data2);
- return true;
- } else if (data1 == (OMX_U32)OMX_CommandPortEnable) {
- CHECK_EQ(data2, (OMX_U32)kPortIndexOutput);
-
- mCodec->mSentFormat = false;
-
- ALOGV("[%s] Output port now reenabled.",
- mCodec->mComponentName.c_str());
-
- if (mCodec->mExecutingState->active()) {
- mCodec->mExecutingState->submitOutputBuffers();
- }
-
- mCodec->changeState(mCodec->mExecutingState);
-
- return true;
- }
-
- return false;
- }
-
- default:
- return false;
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::ExecutingToIdleState::ExecutingToIdleState(DashCodec *codec)
- : BaseState(codec),
- mComponentNowIdle(false) {
-}
-
-bool DashCodec::ExecutingToIdleState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatShutdown:
- {
- // We're already doing that...
-
- handled = true;
- break;
- }
-
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-void DashCodec::ExecutingToIdleState::stateEntered() {
- ALOGV("[%s] Now Executing->Idle", mCodec->mComponentName.c_str());
-
- mComponentNowIdle = false;
- mCodec->mSentFormat = false;
-}
-
-bool DashCodec::ExecutingToIdleState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
- CHECK_EQ(data2, (OMX_U32)OMX_StateIdle);
-
- mComponentNowIdle = true;
-
- changeStateIfWeOwnAllBuffers();
-
- return true;
- }
-
- case OMX_EventPortSettingsChanged:
- case OMX_EventBufferFlag:
- {
- // We're shutting down and don't care about this anymore.
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-}
-
-void DashCodec::ExecutingToIdleState::changeStateIfWeOwnAllBuffers() {
- if (mComponentNowIdle && mCodec->allYourBuffersAreBelongToUs()) {
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode, OMX_CommandStateSet, OMX_StateLoaded),
- (status_t)OK);
-
- CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexInput), (status_t)OK);
- CHECK_EQ(mCodec->freeBuffersOnPort(kPortIndexOutput), (status_t)OK);
-
- if (mCodec->mFlags & kFlagPushBlankBuffersToNativeWindowOnShutdown
- && mCodec->mNativeWindow != NULL) {
- // We push enough 1x1 blank buffers to ensure that one of
- // them has made it to the display. This allows the OMX
- // component teardown to zero out any protected buffers
- // without the risk of scanning out one of those buffers.
- PushBlankBuffersToNativeWindow(mCodec->mNativeWindow);
- }
-
- mCodec->changeState(mCodec->mIdleToLoadedState);
- }
-}
-
-void DashCodec::ExecutingToIdleState::onInputBufferFilled(
- const sp<AMessage> &msg) {
- BaseState::onInputBufferFilled(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-void DashCodec::ExecutingToIdleState::onOutputBufferDrained(
- const sp<AMessage> &msg) {
- BaseState::onOutputBufferDrained(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::IdleToLoadedState::IdleToLoadedState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-bool DashCodec::IdleToLoadedState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatShutdown:
- {
- // We're already doing that...
-
- handled = true;
- break;
- }
-
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-void DashCodec::IdleToLoadedState::stateEntered() {
- ALOGV("[%s] Now Idle->Loaded", mCodec->mComponentName.c_str());
-}
-
-bool DashCodec::IdleToLoadedState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandStateSet);
- CHECK_EQ(data2, (OMX_U32)OMX_StateLoaded);
-
- mCodec->changeState(mCodec->mLoadedState);
-
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::FlushingState::FlushingState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-void DashCodec::FlushingState::stateEntered() {
- ALOGV("[%s] Now Flushing", mCodec->mComponentName.c_str());
-
- mFlushComplete[kPortIndexInput] = mFlushComplete[kPortIndexOutput] = false;
-}
-
-bool DashCodec::FlushingState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatShutdown:
- {
- mCodec->deferMessage(msg);
- break;
- }
-
- case kWhatFlush:
- {
- // We're already doing this right now.
- handled = true;
- break;
- }
-
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-bool DashCodec::FlushingState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- ALOGV("[%s] FlushingState onOMXEvent(%d,%ld)",
- mCodec->mComponentName.c_str(), event, data1);
-
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
-
- if (data2 == kPortIndexInput || data2 == kPortIndexOutput) {
- CHECK(!mFlushComplete[data2]);
- mFlushComplete[data2] = true;
-
- if (mFlushComplete[kPortIndexInput]
- && mFlushComplete[kPortIndexOutput]) {
- changeStateIfWeOwnAllBuffers();
- }
- } else {
- CHECK_EQ(data2, OMX_ALL);
- CHECK(mFlushComplete[kPortIndexInput]);
- CHECK(mFlushComplete[kPortIndexOutput]);
-
- changeStateIfWeOwnAllBuffers();
- }
-
- return true;
- }
-
- case OMX_EventPortSettingsChanged:
- {
- sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
- msg->setInt32("type", omx_message::EVENT);
- msg->setInt32("node", mCodec->mNode);
- msg->setInt32("event", event);
- msg->setInt32("data1", data1);
- msg->setInt32("data2", data2);
-
- ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
- mCodec->mComponentName.c_str());
-
- mCodec->deferMessage(msg);
-
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-
- return true;
-}
-
-void DashCodec::FlushingState::onOutputBufferDrained(const sp<AMessage> &msg) {
- BaseState::onOutputBufferDrained(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-void DashCodec::FlushingState::onInputBufferFilled(const sp<AMessage> &msg) {
- BaseState::onInputBufferFilled(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-void DashCodec::FlushingState::changeStateIfWeOwnAllBuffers() {
- if (mFlushComplete[kPortIndexInput]
- && mFlushComplete[kPortIndexOutput]
- && mCodec->allYourBuffersAreBelongToUs()) {
- // We now own all buffers except possibly those still queued with
- // the native window for rendering. Let's get those back as well.
- mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
-
- sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", CodecBase::kWhatFlushCompleted);
- notify->post();
-
- mCodec->mPortEOS[kPortIndexInput] =
- mCodec->mPortEOS[kPortIndexOutput] = false;
-
- mCodec->mInputEOSResult = OK;
-
- mCodec->changeState(mCodec->mExecutingState);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashCodec::FlushingOutputState::FlushingOutputState(DashCodec *codec)
- : BaseState(codec) {
-}
-
-DashCodec::BaseState::PortMode DashCodec::FlushingOutputState::getPortMode(OMX_U32 portIndex) {
- if (portIndex == kPortIndexOutput)
- {
- return KEEP_BUFFERS;
- }
- return RESUBMIT_BUFFERS;
-}
-
-void DashCodec::FlushingOutputState::stateEntered() {
- ALOGV("[%s] Now Flushing Output Port", mCodec->mComponentName.c_str());
-
- mFlushComplete = false;
-}
-
-bool DashCodec::FlushingOutputState::onMessageReceived(const sp<AMessage> &msg) {
- bool handled = false;
-
- switch (msg->what()) {
- case kWhatShutdown:
- {
- mCodec->deferMessage(msg);
- handled = true;
- break;
- }
-
- case kWhatFlush:
- {
- ALOGV("Flush received during port reconfig, deferring it");
- mCodec->deferMessage(msg);
- handled = true;
- break;
- }
-
- case kWhatInputBufferFilled:
- {
- mCodec->deferMessage(msg);
- changeStateIfWeOwnAllBuffers();
- handled = true;
- break;
- }
-
- default:
- handled = BaseState::onMessageReceived(msg);
- break;
- }
-
- return handled;
-}
-
-bool DashCodec::FlushingOutputState::onOMXEvent(
- OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
- switch (event) {
- case OMX_EventCmdComplete:
- {
- CHECK_EQ(data1, (OMX_U32)OMX_CommandFlush);
- CHECK_EQ(data2,(OMX_U32)kPortIndexOutput);
- ALOGV("FlushingOutputState::onOMXEvent Output port flush complete");
- mFlushComplete = true;
- changeStateIfWeOwnAllBuffers();
- return true;
- }
-
- case OMX_EventPortSettingsChanged:
- {
- sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
- msg->setInt32("type", omx_message::EVENT);
- msg->setInt32("node", mCodec->mNode);
- msg->setInt32("event", event);
- msg->setInt32("data1", data1);
- msg->setInt32("data2", data2);
-
- ALOGV("[%s] Deferring OMX_EventPortSettingsChanged",
- mCodec->mComponentName.c_str());
-
- mCodec->deferMessage(msg);
-
- return true;
- }
-
- default:
- return BaseState::onOMXEvent(event, data1, data2);
- }
-
- return true;
-}
-
-void DashCodec::FlushingOutputState::onOutputBufferDrained(const sp<AMessage> &msg) {
- BaseState::onOutputBufferDrained(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-void DashCodec::FlushingOutputState::onInputBufferFilled(const sp<AMessage> &msg) {
- BaseState::onInputBufferFilled(msg);
-
- changeStateIfWeOwnAllBuffers();
-}
-
-void DashCodec::FlushingOutputState::changeStateIfWeOwnAllBuffers() {
- ALOGV("FlushingOutputState::ChangeState %d",mFlushComplete);
-
- if (mFlushComplete && mCodec->allYourBuffersAreBelongToUs( kPortIndexOutput )) {
- ALOGV("FlushingOutputState Sending port disable ");
- CHECK_EQ(mCodec->mOMX->sendCommand(
- mCodec->mNode,
- OMX_CommandPortDisable, kPortIndexOutput),
- (status_t)OK);
-
- mCodec->mPortEOS[kPortIndexInput] = false;
- mCodec->mPortEOS[kPortIndexOutput] = false;
-
- ALOGV("FlushingOutputState Calling freeOutputBuffersNotOwnedByComponent");
- mCodec->freeOutputBuffersNotOwnedByComponent();
-
- ALOGV("FlushingOutputState Change state to port settings changed");
- mCodec->changeState(mCodec->mOutputPortSettingsChangedState);
- }
-}
-
-} // namespace android
diff --git a/dashplayer/DashCodec.h b/dashplayer/DashCodec.h
deleted file mode 100644
index 7ff5abb9..00000000
--- a/dashplayer/DashCodec.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- * Not a Contribution, Apache license notifications and license are retained
- * for attribution purposes only.
- *
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASH_CODEC_H_
-#define DASH_CODEC_H_
-
-#include <stdint.h>
-#include <android/native_window.h>
-#include <media/IOMX.h>
-#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
-#include <media/stagefright/CodecBase.h>
-#include <media/stagefright/SkipCutBuffer.h>
-#include <OMX_Audio.h>
-#include <OMX_Component.h>
-#include <OMX_IVCommon.h>
-
-#define TRACK_BUFFER_TIMING 0
-
-namespace android {
-
-struct ABuffer;
-struct MemoryDealer;
-
-struct DashCodec : public AHierarchicalStateMachine, public CodecBase {
- DashCodec();
-
- virtual void setNotificationMessage(const sp<AMessage> &msg);
-
- void initiateSetup(const sp<AMessage> &msg);
-
- virtual void initiateAllocateComponent(const sp<AMessage> &msg);
- virtual void initiateConfigureComponent(const sp<AMessage> &msg);
- virtual void initiateCreateInputSurface() {
- return;
- }
- virtual void initiateStart();
- virtual void initiateShutdown(bool keepComponentAllocated = false);
-
- virtual void signalFlush();
- virtual void signalResume();
-
- virtual void signalSetParameters(const sp<AMessage> & /*msg*/) {
- return;
- }
- virtual void signalEndOfInputStream() {
- return;
- }
- virtual void signalRequestIDRFrame();
-
- void queueNextFormat();
- void clearCachedFormats();
-
- static status_t PushBlankBuffersToNativeWindow(sp<ANativeWindow> nativeWindow);
-
- // AHierarchicalStateMachine implements the message handling
- virtual void onMessageReceived(const sp<AMessage> &msg) {
- handleMessage(msg);
- }
-
- struct PortDescription : public CodecBase::PortDescription {
- size_t countBuffers();
- IOMX::buffer_id bufferIDAt(size_t index) const;
- sp<ABuffer> bufferAt(size_t index) const;
-
- private:
- friend struct DashCodec;
-
- Vector<IOMX::buffer_id> mBufferIDs;
- Vector<sp<ABuffer> > mBuffers;
-
- PortDescription();
- void addBuffer(IOMX::buffer_id id, const sp<ABuffer> &buffer);
-
- DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
- };
-
-protected:
- virtual ~DashCodec();
-
-private:
- struct BaseState;
- struct UninitializedState;
- struct LoadedState;
- struct LoadedToIdleState;
- struct IdleToExecutingState;
- struct ExecutingState;
- struct OutputPortSettingsChangedState;
- struct ExecutingToIdleState;
- struct IdleToLoadedState;
- struct FlushingState;
- struct FlushingOutputState;
-
- enum {
- kWhatSetup = 'setu',
- kWhatOMXMessage = 'omx ',
- kWhatInputBufferFilled = 'inpF',
- kWhatOutputBufferDrained = 'outD',
- kWhatShutdown = 'shut',
- kWhatFlush = 'flus',
- kWhatResume = 'resm',
- kWhatDrainDeferredMessages = 'drai',
- kWhatAllocateComponent = 'allo',
- kWhatConfigureComponent = 'conf',
- kWhatStart = 'star',
- kWhatRequestIDRFrame = 'ridr',
- kWhatWaitForPortEnable = 'wfpe',
- };
-
- enum {
- kPortIndexInput = 0,
- kPortIndexOutput = 1
- };
-
- enum {
- kFlagIsSecure = 1,
- kFlagIsSecureOPOnly = 2,
- kFlagPushBlankBuffersToNativeWindowOnShutdown = 4
- };
-
- struct BufferInfo {
- enum Status {
- OWNED_BY_US,
- OWNED_BY_COMPONENT,
- OWNED_BY_UPSTREAM,
- OWNED_BY_DOWNSTREAM,
- OWNED_BY_NATIVE_WINDOW,
- };
-
- IOMX::buffer_id mBufferID;
- Status mStatus;
- unsigned mDequeuedAt;
-
- sp<ABuffer> mData;
- sp<GraphicBuffer> mGraphicBuffer;
- };
-
-#if TRACK_BUFFER_TIMING
- struct BufferStats {
- int64_t mEmptyBufferTimeUs;
- int64_t mFillBufferDoneTimeUs;
- };
-
- KeyedVector<int64_t, BufferStats> mBufferStats;
-#endif
-
- sp<AMessage> mNotify;
-
- sp<UninitializedState> mUninitializedState;
- sp<LoadedState> mLoadedState;
- sp<LoadedToIdleState> mLoadedToIdleState;
- sp<IdleToExecutingState> mIdleToExecutingState;
- sp<ExecutingState> mExecutingState;
- sp<OutputPortSettingsChangedState> mOutputPortSettingsChangedState;
- sp<ExecutingToIdleState> mExecutingToIdleState;
- sp<IdleToLoadedState> mIdleToLoadedState;
- sp<FlushingState> mFlushingState;
- sp<FlushingOutputState> mFlushingOutputState;
- sp<SkipCutBuffer> mSkipCutBuffer;
-
- AString mComponentName;
- uint32_t mFlags;
- uint32_t mQuirks;
- sp<IOMX> mOMX;
- IOMX::node_id mNode;
- sp<MemoryDealer> mDealer[2];
-
- sp<ANativeWindow> mNativeWindow;
-
- Vector<BufferInfo> mBuffers[2];
- bool mPortEOS[2];
- status_t mInputEOSResult;
-
- List<sp<AMessage> > mDeferredQueue;
-
- bool mSentFormat;
- bool mPostFormat;
- bool mIsEncoder;
-
- bool mShutdownInProgress;
-
- // If "mKeepComponentAllocated" we only transition back to Loaded state
- // and do not release the component instance.
- bool mKeepComponentAllocated;
-
- int32_t mEncoderDelay;
- int32_t mEncoderPadding;
-
- bool mChannelMaskPresent;
- int32_t mChannelMask;
- unsigned mDequeueCounter;
- bool mStoreMetaDataInOutputBuffers;
- int32_t mMetaDataBuffersToSubmit;
-
- int32_t mCurrentWidth;
- int32_t mCurrentHeight;
-
- status_t allocateBuffersOnPort(OMX_U32 portIndex);
- status_t freeBuffersOnPort(OMX_U32 portIndex);
- status_t freeBuffer(OMX_U32 portIndex, size_t i);
-
- status_t configureOutputBuffersFromNativeWindow(
- OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
- OMX_U32 *nMinUndequeuedBuffers);
- status_t allocateOutputMetaDataBuffers();
- status_t submitOutputMetaDataBuffer();
- status_t allocateOutputBuffersFromNativeWindow();
- status_t cancelBufferToNativeWindow(BufferInfo *info);
- status_t freeOutputBuffersNotOwnedByComponent();
- BufferInfo *dequeueBufferFromNativeWindow();
-
- BufferInfo *findBufferByID(
- uint32_t portIndex, IOMX::buffer_id bufferID,
- ssize_t *index = NULL);
-
- status_t setComponentRole(bool isEncoder, const char *mime);
- status_t configureCodec(const char *mime, const sp<AMessage> &msg);
-
- status_t setVideoPortFormatType(
- OMX_U32 portIndex,
- OMX_VIDEO_CODINGTYPE compressionFormat,
- OMX_COLOR_FORMATTYPE colorFormat);
-
- status_t setSupportedOutputFormat();
-
- status_t setupVideoDecoder(
- const char *mime, int32_t width, int32_t height);
-
- status_t setupVideoEncoder(
- const char *mime, const sp<AMessage> &msg);
-
- status_t setVideoFormatOnPort(
- OMX_U32 portIndex,
- int32_t width, int32_t height,
- OMX_VIDEO_CODINGTYPE compressionFormat);
-
- status_t setupAACCodec(
- bool encoder,
- int32_t numChannels, int32_t sampleRate, int32_t bitRate,
- int32_t aacProfile, bool isADTS);
-
- status_t selectAudioPortFormat(
- OMX_U32 portIndex, OMX_AUDIO_CODINGTYPE desiredFormat);
-
- status_t setupAMRCodec(bool encoder, bool isWAMR, int32_t bitRate);
- status_t setupG711Codec(bool encoder, int32_t numChannels);
-
- status_t setupFlacCodec(
- bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
-
- status_t setupRawAudioFormat(
- OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
-
- status_t setMinBufferSize(OMX_U32 portIndex, size_t size);
-
- status_t setupMPEG4EncoderParameters(const sp<AMessage> &msg);
- status_t setupH263EncoderParameters(const sp<AMessage> &msg);
- status_t setupAVCEncoderParameters(const sp<AMessage> &msg);
-
- status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
-
- status_t configureBitrate(
- int32_t bitrate, OMX_VIDEO_CONTROLRATETYPE bitrateMode);
-
- status_t setupErrorCorrectionParameters();
-
- status_t initNativeWindow();
-
- // Returns true iff all buffers on the given port have status OWNED_BY_US.
- bool allYourBuffersAreBelongToUs(OMX_U32 portIndex);
-
- bool allYourBuffersAreBelongToUs();
-
- void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
-
- size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
- size_t countBuffersOwnedByNativeWindow() const;
-
- void deferMessage(const sp<AMessage> &msg);
- void processDeferredMessages();
-
- void sendFormatChange();
-
- void signalError(
- OMX_ERRORTYPE error = OMX_ErrorUndefined,
- status_t internalError = UNKNOWN_ERROR);
-
- status_t requestIDRFrame();
- bool mAdaptivePlayback;
- Vector<OMX_PARAM_PORTDEFINITIONTYPE*> mFormats;
- Vector<OMX_CONFIG_RECTTYPE*> mOutputCrops;
- DISALLOW_EVIL_CONSTRUCTORS(DashCodec);
-};
-
-} // namespace android
-
-#endif // DASH_CODEC_H_
diff --git a/dashplayer/DashFactory.cpp b/dashplayer/DashFactory.cpp
deleted file mode 100644
index c77d1e1e..00000000
--- a/dashplayer/DashFactory.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *Not a Contribution, Apache license notifications and license are retained
- *for attribution purposes only.
- *
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DASHFactory"
-#include <media/IMediaPlayer.h>
-#include "DashPlayerDriver.h"
-#include "MediaPlayerFactory.h"
-
-namespace android {
-
-class DashPlayerFactory : public MediaPlayerFactory::IFactory {
- public:
- virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
- const char* url,
- float /*curScore*/) {
- if (!strncasecmp("http://", url, 7)) {
- size_t len = strlen(url);
- if (len >= 5 && !strcasecmp(".mpd", &url[len - 4])) {
- ALOGI("Using DashPlayer for .mpd");
- return 1.0;
- }
- }
- return 0.0;
- }
-
- virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
- const sp<IStreamSource> & /*source*/,
- float /*curScore*/) {
- return 0.0;
- }
-
- virtual sp<MediaPlayerBase> createPlayer(pid_t /*pid*/) {
- return new DashPlayerDriver;
- }
-};
-
-extern "C" MediaPlayerFactory::IFactory* CreateDASHFactory()
-{
- return new DashPlayerFactory();
-}
-
-} // namespace android
diff --git a/dashplayer/DashPacketSource.cpp b/dashplayer/DashPacketSource.cpp
deleted file mode 100644
index 7f31daad..00000000
--- a/dashplayer/DashPacketSource.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- *Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *Not a Contribution, Apache license notifications and license are retained
- *for attribution purposes only.
- *Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#include "DashPacketSource.h"
-#include "DashPlayer.h"
-#include <media/stagefright/MediaBuffer.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/Vector.h>
-#include <cutils/properties.h>
-
-#define DPS_MSG_ERROR(...) ALOGE(__VA_ARGS__)
-#define DPS_MSG_HIGH(...) if(mLogLevel >= 1){ALOGE(__VA_ARGS__);}
-#define DPS_MSG_MEDIUM(...) if(mLogLevel >= 2){ALOGE(__VA_ARGS__);}
-#define DPS_MSG_LOW(...) if(mLogLevel >= 3){ALOGE(__VA_ARGS__);}
-
-namespace android {
-
-DashPacketSource::DashPacketSource(const sp<MetaData> &meta)
- : mIsAudio(false),
- mFormat(meta),
- mEOSResult(OK),
- mLogLevel(0) {
-
- char property_value[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.debug.level", property_value, NULL);
- if(*property_value) {
- mLogLevel = atoi(property_value);
- }
-
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if (!strncasecmp("audio/", mime, 6)) {
- mIsAudio = true;
- }
-}
-
-void DashPacketSource::setFormat(const sp<MetaData> &meta) {
- Mutex::Autolock autoLock(mLock);
- CHECK(mFormat == NULL);
- mFormat = meta;
-}
-
-void DashPacketSource::updateFormat(const sp<MetaData> &meta) {
- Mutex::Autolock autoLock(mLock);
- mFormat = meta;
-}
-
-DashPacketSource::~DashPacketSource() {
-}
-
-status_t DashPacketSource::start(MetaData * /*params*/) {
- return OK;
-}
-
-status_t DashPacketSource::stop() {
- return OK;
-}
-
-sp<MetaData> DashPacketSource::getFormat() {
- Mutex::Autolock autoLock(mLock);
- return mFormat;
-}
-
-status_t DashPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
- buffer->clear();
-
- Mutex::Autolock autoLock(mLock);
- while (mEOSResult == OK && mBuffers.empty()) {
- mCondition.wait(mLock);
- }
-
- if (!mBuffers.empty()) {
- *buffer = *mBuffers.begin();
- mBuffers.erase(mBuffers.begin());
-
- int32_t discontinuity;
- if ((*buffer)->meta()->findInt32("discontinuity", &discontinuity)) {
- if (wasFormatChange(discontinuity)) {
- mFormat.clear();
- }
-
- return INFO_DISCONTINUITY;
- }
-
- return OK;
- }
-
- return mEOSResult;
-}
-
-status_t DashPacketSource::read(
- MediaBuffer **out, const ReadOptions *) {
- *out = NULL;
-
- Mutex::Autolock autoLock(mLock);
- while (mEOSResult == OK && mBuffers.empty()) {
- mCondition.wait(mLock);
- }
-
- if (!mBuffers.empty()) {
- const sp<ABuffer> buffer = *mBuffers.begin();
- mBuffers.erase(mBuffers.begin());
-
- int32_t discontinuity;
- if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
- if (wasFormatChange(discontinuity)) {
- mFormat.clear();
- }
-
- return INFO_DISCONTINUITY;
- } else {
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
-
- mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
-
- *out = mediaBuffer;
- return OK;
- }
- }
-
- return mEOSResult;
-}
-
-bool DashPacketSource::wasFormatChange(
- int32_t discontinuityType) const {
- if (mIsAudio) {
- return (discontinuityType & ATSParser::DISCONTINUITY_AUDIO_FORMAT) != 0;
- }
-
- return (discontinuityType & ATSParser::DISCONTINUITY_VIDEO_FORMAT) != 0;
-}
-
-void DashPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
- int32_t damaged;
- if (buffer->meta()->findInt32("damaged", &damaged) && damaged) {
- // LOG(VERBOSE) << "discarding damaged AU";
- return;
- }
-
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- DPS_MSG_LOW("queueAccessUnit timeUs=%lld us (%.2f secs)", timeUs, (double)timeUs / 1E6);
-
- Mutex::Autolock autoLock(mLock);
- mBuffers.push_back(buffer);
- DPS_MSG_LOW("@@@@:: DashPacketSource --> size is %d ",mBuffers.size() );
- mCondition.signal();
-}
-
-int DashPacketSource::getQueueSize() {
- return (int)mBuffers.size();
-}
-
-void DashPacketSource::queueDiscontinuity(
- ATSParser::DiscontinuityType type,
- const sp<AMessage> &extra) {
- Mutex::Autolock autoLock(mLock);
-
- if (type == ATSParser::DISCONTINUITY_TIME) {
- DPS_MSG_HIGH("Flushing all Access units for seek");
- mBuffers.clear();
- mEOSResult = OK;
- mCondition.signal();
- return;
- }
-
- mEOSResult = OK;
-
- sp<ABuffer> buffer = new ABuffer(0);
- buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
- buffer->meta()->setMessage("extra", extra);
-
- mBuffers.push_back(buffer);
- mCondition.signal();
-}
-
-void DashPacketSource::signalEOS(status_t result) {
- CHECK(result != OK);
-
- Mutex::Autolock autoLock(mLock);
- mEOSResult = result;
- mCondition.signal();
-}
-
-bool DashPacketSource::hasBufferAvailable(status_t *finalResult) {
- Mutex::Autolock autoLock(mLock);
- if (!mBuffers.empty()) {
- return true;
- }
-
- *finalResult = mEOSResult;
- return false;
-}
-
-int64_t DashPacketSource::getBufferedDurationUs(status_t *finalResult) {
- Mutex::Autolock autoLock(mLock);
-
- *finalResult = mEOSResult;
-
- if (mBuffers.empty()) {
- return 0;
- }
-
- int64_t time1 = -1;
- int64_t time2 = -1;
-
- List<sp<ABuffer> >::iterator it = mBuffers.begin();
- while (it != mBuffers.end()) {
- const sp<ABuffer> &buffer = *it;
-
- int64_t timeUs;
- if (buffer->meta()->findInt64("timeUs", &timeUs)) {
- if (time1 < 0) {
- time1 = timeUs;
- }
-
- time2 = timeUs;
- } else {
- // This is a discontinuity, reset everything.
- time1 = time2 = -1;
- }
-
- ++it;
- }
-
- return time2 - time1;
-}
-
-status_t DashPacketSource::nextBufferTime(int64_t *timeUs) {
- *timeUs = 0;
-
- Mutex::Autolock autoLock(mLock);
-
- if (mBuffers.empty()) {
- return mEOSResult != OK ? mEOSResult : -EWOULDBLOCK;
- }
-
- sp<ABuffer> buffer = *mBuffers.begin();
- CHECK(buffer->meta()->findInt64("timeUs", timeUs));
- return OK;
-}
-
-
-} // namespace android
diff --git a/dashplayer/DashPacketSource.h b/dashplayer/DashPacketSource.h
deleted file mode 100644
index dbf3ca99..00000000
--- a/dashplayer/DashPacketSource.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *Not a Contribution, Apache license notifications and license are retained
- *for attribution purposes only.
- *Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASH_PACKET_SOURCE_H_
-
-#define DASH_PACKET_SOURCE_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/MediaSource.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include "ATSParser.h"
-
-namespace android {
-
-struct ABuffer;
-
-struct DashPacketSource : public MediaSource {
- DashPacketSource(const sp<MetaData> &meta);
-
- void setFormat(const sp<MetaData> &meta);
-
- virtual status_t start(MetaData *params = NULL);
- virtual status_t stop();
- virtual sp<MetaData> getFormat();
-
- virtual status_t read(
- MediaBuffer **buffer, const ReadOptions *options = NULL);
-
- bool hasBufferAvailable(status_t *finalResult);
-
- // Returns the difference between the last and the first queued
- // presentation timestamps since the last discontinuity (if any).
- int64_t getBufferedDurationUs(status_t *finalResult);
-
- status_t nextBufferTime(int64_t *timeUs);
-
- void queueAccessUnit(const sp<ABuffer> &buffer);
-
- void queueDiscontinuity(
- ATSParser::DiscontinuityType type, const sp<AMessage> &extra);
-
- void signalEOS(status_t result);
-
- status_t dequeueAccessUnit(sp<ABuffer> *buffer);
- void updateFormat(const sp<MetaData> &meta);
- int getQueueSize();
-
-
-protected:
- virtual ~DashPacketSource();
-
-private:
- Mutex mLock;
- Condition mCondition;
-
- bool mIsAudio;
- sp<MetaData> mFormat;
- List<sp<ABuffer> > mBuffers;
- status_t mEOSResult;
- int mLogLevel;
-
- bool wasFormatChange(int32_t discontinuityType) const;
-
- DISALLOW_EVIL_CONSTRUCTORS(DashPacketSource);
-};
-
-
-} // namespace android
-
-#endif // DASH_PACKET_SOURCE_H_
diff --git a/dashplayer/DashPlayer.cpp b/dashplayer/DashPlayer.cpp
deleted file mode 100644
index 77d57a28..00000000
--- a/dashplayer/DashPlayer.cpp
+++ /dev/null
@@ -1,2523 +0,0 @@
-/*
- *Copyright (c) 2013 - 2014, The Linux Foundation. All rights reserved.
- *Not a Contribution, Apache license notifications and license are retained
- *for attribution purposes only.
- *
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-
-#define LOG_TAG "DashPlayer"
-#define SRMax 30
-#include <utils/Log.h>
-#include <dlfcn.h> // for dlopen/dlclose
-#include "DashPlayer.h"
-#include "DashPlayerDecoder.h"
-#include "DashPlayerDriver.h"
-#include "DashPlayerRenderer.h"
-#include "DashPlayerSource.h"
-#include "ATSParser.h"
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <gui/IGraphicBufferProducer.h>
-#include "avc_utils.h"
-#include "OMX_QCOMExtns.h"
-#include <gralloc_priv.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include <media/msm_media_info.h>
-#include <qcmediaplayer.h>
-
-#define DP_MSG_ERROR(...) ALOGE(__VA_ARGS__)
-#define DP_MSG_HIGH(...) if(mLogLevel >= 1){ALOGE(__VA_ARGS__);}
-#define DP_MSG_MEDIUM(...) if(mLogLevel >= 2){ALOGE(__VA_ARGS__);}
-#define DP_MSG_LOW(...) if(mLogLevel >= 3){ALOGE(__VA_ARGS__);}
-
-namespace android {
-
-struct DashPlayer::Action : public RefBase {
- Action() {}
-
- virtual void execute(DashPlayer *player) = 0;
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(Action);
-};
-
-struct DashPlayer::SetSurfaceAction : public Action {
- SetSurfaceAction(const sp<Surface> &wrapper)
- : mWrapper(wrapper) {
- }
-
- virtual void execute(DashPlayer *player) {
- player->performSetSurface(mWrapper);
- }
-
-private:
- sp<Surface> mWrapper;
-
- DISALLOW_EVIL_CONSTRUCTORS(SetSurfaceAction);
-};
-
-struct DashPlayer::ShutdownDecoderAction : public Action {
- ShutdownDecoderAction(bool audio, bool video)
- : mAudio(audio),
- mVideo(video) {
- }
-
- virtual void execute(DashPlayer *player) {
- player->performDecoderShutdown(mAudio, mVideo);
- }
-
-private:
- bool mAudio;
- bool mVideo;
-
- DISALLOW_EVIL_CONSTRUCTORS(ShutdownDecoderAction);
-};
-
-// Use this if there's no state necessary to save in order to execute
-// the action.
-struct DashPlayer::SimpleAction : public Action {
- typedef void (DashPlayer::*ActionFunc)();
-
- SimpleAction(ActionFunc func)
- : mFunc(func) {
- }
-
- virtual void execute(DashPlayer *player) {
- (player->*mFunc)();
- }
-
-private:
- ActionFunc mFunc;
-
- DISALLOW_EVIL_CONSTRUCTORS(SimpleAction);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-
-DashPlayer::DashPlayer()
- : mUIDValid(false),
- mVideoIsAVC(false),
- mRenderer(NULL),
- mAudioEOS(false),
- mVideoEOS(false),
- mScanSourcesPending(false),
- isSetSurfaceTexturePending(false),
- mScanSourcesGeneration(0),
- mBufferingNotification(false),
- mTimeDiscontinuityPending(false),
- mFlushingAudio(NONE),
- mFlushingVideo(NONE),
- mResetInProgress(false),
- mResetPostponed(false),
- mSetVideoSize(true),
- mSkipRenderingAudioUntilMediaTimeUs(-1ll),
- mSkipRenderingVideoUntilMediaTimeUs(-1ll),
- mVideoLateByUs(0ll),
- mPauseIndication(false),
- mSRid(0),
- mStats(NULL),
- mLogLevel(0),
- mTimedTextCEAPresent(false),
- mTimedTextCEASamplesDisc(false),
- mQCTimedTextListenerPresent(false),
- mCurrentWidth(0),
- mCurrentHeight(0),
- mColorFormat(0){
- mTrackName = new char[6];
-
- char property_value[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.debug.level", property_value, NULL);
-
- if(*property_value) {
- mLogLevel = atoi(property_value);
- }
-
-}
-
-DashPlayer::~DashPlayer() {
- if (mRenderer != NULL) {
- looper()->unregisterHandler(mRenderer->id());
- }
- if (mAudioDecoder != NULL) {
- looper()->unregisterHandler(mAudioDecoder->id());
- }
- if (mVideoDecoder != NULL) {
- looper()->unregisterHandler(mVideoDecoder->id());
- }
- if (mTextDecoder != NULL) {
- looper()->unregisterHandler(mTextDecoder->id());
- }
- if(mStats != NULL) {
- mStats->logFpsSummary();
- mStats = NULL;
- }
- if (mTrackName != NULL) {
- delete[] mTrackName;
- mTrackName = NULL;
- }
-}
-
-void DashPlayer::setUID(uid_t uid) {
- mUIDValid = true;
- mUID = uid;
-}
-
-void DashPlayer::setDriver(const wp<DashPlayerDriver> &driver) {
- mDriver = driver;
-}
-
-void DashPlayer::setDataSource(const sp<IStreamSource> &/*source*/) {
- DP_MSG_ERROR("DashPlayer::setDataSource not Implemented...");
-}
-
-status_t DashPlayer::setDataSource(
- const char *url, const KeyedVector<String8, String8> *headers) {
- sp<AMessage> msg = new AMessage(kWhatSetDataSource, this);
-
- sp<Source> source;
- if (!strncasecmp(url, "http://", 7) &&
- (strlen(url) >= 4 && !strcasecmp(".mpd", &url[strlen(url) - 4]))) {
- /* Load the DASH HTTP Live source librery here */
- DP_MSG_LOW("DashPlayer setDataSource url sting %s",url);
- source = LoadCreateSource(url, headers, mUIDValid, mUID);
- if (source != NULL) {
- msg->setObject("source", source);
- msg->post();
- return OK;
- } else {
- DP_MSG_ERROR("Error creating DASH source");
- return UNKNOWN_ERROR;
- }
- }
- else
- {
- DP_MSG_ERROR("Unsupported URL");
- return UNKNOWN_ERROR;
- }
-}
-
-void DashPlayer::setDataSource(int /*fd*/, int64_t /*offset*/, int64_t /*length*/) {
- DP_MSG_ERROR("DashPlayer::setDataSource not Implemented...");
-}
-
-void DashPlayer::setVideoSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer) {
- sp<AMessage> msg = new AMessage(kWhatSetVideoNativeWindow, this);
-
- if (bufferProducer == NULL) {
- msg->setObject("surface", NULL);
- DP_MSG_ERROR("DashPlayer::setVideoSurfaceTexture bufferproducer = NULL ");
- } else {
- DP_MSG_ERROR("DashPlayer::setVideoSurfaceTexture bufferproducer = %p", bufferProducer.get());
- msg->setObject(
- "surface", new Surface(bufferProducer, true /* controlledByApp */));
- }
-
- msg->post();
-}
-
-void DashPlayer::setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink) {
- sp<AMessage> msg = new AMessage(kWhatSetAudioSink, this);
- msg->setObject("sink", sink);
- msg->post();
-}
-
-void DashPlayer::start() {
- (new AMessage(kWhatStart, this))->post();
-}
-
-void DashPlayer::pause() {
- (new AMessage(kWhatPause, this))->post();
-}
-
-void DashPlayer::resume() {
- (new AMessage(kWhatResume, this))->post();
-}
-
-void DashPlayer::resetAsync() {
- (new AMessage(kWhatReset, this))->post();
-}
-
-void DashPlayer::seekToAsync(int64_t seekTimeUs) {
- sp<AMessage> msg = new AMessage(kWhatSeek, this);
- msg->setInt64("seekTimeUs", seekTimeUs);
- msg->post();
-}
-
-// static
-bool DashPlayer::IsFlushingState(FlushStatus state, bool *needShutdown) {
- switch (state) {
- case FLUSHING_DECODER:
- if (needShutdown != NULL) {
- *needShutdown = false;
- }
- return true;
-
- case FLUSHING_DECODER_SHUTDOWN:
- case SHUTTING_DOWN_DECODER:
- if (needShutdown != NULL) {
- *needShutdown = true;
- }
- return true;
-
- default:
- return false;
- }
-}
-
-void DashPlayer::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatSetDataSource:
- {
- DP_MSG_ERROR("kWhatSetDataSource");
-
- CHECK(mSource == NULL);
-
- sp<RefBase> obj;
- CHECK(msg->findObject("source", &obj));
-
- mSource = static_cast<Source *>(obj.get());
- prepareSource();
-
- break;
- }
-
- case kWhatSetVideoNativeWindow:
- {
- /* if MediaPlayer calls setDisplay(NULL) in the middle of the playback, */
- /* block this call to perform following sequence on video decoder */
- /* flush-->shutdown-->then update nativewindow to NULL */
-
- /* Mediaplayer can also call valid native window to enable video */
- /* playback again dynamically, in such case scan sources will trigger */
- /* reinstantiation of video decoder and video playback continues. */
- /* TODO: Dynamic disible and reenable of video also requies support */
- /* from dash source. */
- DP_MSG_ERROR("kWhatSetVideoNativeWindow");
-
-/*
- if existing instance mNativeWindow=NULL, just set mNativeWindow to the new value passed
- postScanSources() called below to handle use case
- - Initial valid nativewindow
- - first call from app to set nativewindow to null but mVideoDecoder exists. So scansources loop will not be running
- - second call to set nativewindow to valid object. Enters below if() portion. Need to trigger scansources to instatiate mVideoDecoder
- */
- if(mNativeWindow == NULL)
- {
- sp<RefBase> obj;
- CHECK(msg->findObject("surface", &obj));
-
- mNativeWindow = static_cast<Surface *>(obj.get());
- DP_MSG_ERROR("kWhatSetVideoNativeWindow valid nativewindow %p", mNativeWindow.get());
- if (mDriver != NULL) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifySetSurfaceComplete();
- }
- }
-
- DP_MSG_ERROR("kWhatSetVideoNativeWindow nativewindow %d", mScanSourcesPending);
- postScanSources();
- break;
- }
-
- /* Already existing valid mNativeWindow and valid mVideoDecoder
- - Perform shutdown sequence
- - postScanSources() to instantiate mVideoDecoder with the new native window object.
- If no mVideoDecoder existed, and new nativewindow set to NULL push blank buffers to native window (embms audio only switch use case)
- */
-
- sp<RefBase> obj;
- CHECK(msg->findObject("surface", &obj));
-
- if(mVideoDecoder == NULL && obj.get() == NULL)
- {
- ANativeWindow *nativeWindow = mNativeWindow.get();
- PushBlankBuffersToNativeWindow(nativeWindow);
- }
-
- mDeferredActions.push_back(new ShutdownDecoderAction(
- false /* audio */, true /* video */));
-
- DP_MSG_ERROR("kWhatSetVideoNativeWindow old nativewindow %p", mNativeWindow.get());
- DP_MSG_ERROR("kWhatSetVideoNativeWindow new nativewindow %p", obj.get());
-
- mDeferredActions.push_back(
- new SetSurfaceAction(static_cast<Surface *>(obj.get())));
-
- if (obj.get() != NULL) {
- // If there is a new surface texture, instantiate decoders
- // again if possible.
- mDeferredActions.push_back(
- new SimpleAction(&DashPlayer::performScanSources));
- }
-
- isSetSurfaceTexturePending = true;
- processDeferredActions();
- break;
- }
-
- case kWhatSetAudioSink:
- {
- DP_MSG_ERROR("kWhatSetAudioSink");
-
- sp<RefBase> obj;
- CHECK(msg->findObject("sink", &obj));
-
- mAudioSink = static_cast<MediaPlayerBase::AudioSink *>(obj.get());
- break;
- }
-
- case kWhatStart:
- {
- DP_MSG_ERROR("kWhatStart");
-
- mVideoIsAVC = false;
- mAudioEOS = false;
- mVideoEOS = false;
- mSkipRenderingAudioUntilMediaTimeUs = -1;
- mSkipRenderingVideoUntilMediaTimeUs = -1;
- mVideoLateByUs = 0;
- if (mSource != NULL)
- {
- mSource->start();
- }
-
- mRenderer = new Renderer(
- mAudioSink,
- new AMessage(kWhatRendererNotify, this));
- // for qualcomm statistics profiling
- mStats = new DashPlayerStats();
- mRenderer->registerStats(mStats);
- looper()->registerHandler(mRenderer);
-
- postScanSources();
- break;
- }
-
- case kWhatScanSources:
- {
- if (!mPauseIndication) {
- int32_t generation = 0;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mScanSourcesGeneration) {
- // Drop obsolete msg.
- break;
- }
-
- mScanSourcesPending = false;
-
- //Exit scanSources if source was destroyed
- //Later after source gets recreated and started (setDataSource() and start()) scanSources is posted again
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit scanSources\n");
- break;
- }
-
- DP_MSG_LOW("scanning sources haveAudio=%d, haveVideo=%d haveText=%d",
- mAudioDecoder != NULL, mVideoDecoder != NULL, mTextDecoder!= NULL);
-
-
- if(mNativeWindow != NULL) {
- instantiateDecoder(kVideo, &mVideoDecoder);
- }
-
- if (mAudioSink != NULL) {
- instantiateDecoder(kAudio, &mAudioDecoder);
- }
-
- instantiateDecoder(kText, &mTextDecoder);
-
- status_t err;
- if ((err = mSource->feedMoreTSData()) != OK) {
- if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
- // We're not currently decoding anything (no audio or
- // video tracks found) and we just ran out of input data.
-
- if (err == ERROR_END_OF_STREAM) {
- notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
- } else {
- notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
- }
- }
- break;
- }
- if ((mAudioDecoder == NULL && mAudioSink != NULL) ||
- (mVideoDecoder == NULL && mNativeWindow != NULL) ||
- (mTextDecoder == NULL)) {
- msg->post(100000ll);
- mScanSourcesPending = true;
- }
-
- if (mTimeDiscontinuityPending && mRenderer != NULL){
- mRenderer->signalTimeDiscontinuity();
- mTimeDiscontinuityPending = false;
- }
- }
- break;
- }
-
- case kWhatVideoNotify:
- case kWhatAudioNotify:
- case kWhatTextNotify:
- {
- int track = -1;
- if (msg->what() == kWhatAudioNotify)
- track = kAudio;
- else if (msg->what() == kWhatVideoNotify)
- track = kVideo;
- else if (msg->what() == kWhatTextNotify)
- track = kText;
-
- getTrackName(track,mTrackName);
-
- int32_t what;
-
- if(track == kText)
- {
- sp<AMessage> codecRequest;
- CHECK(msg->findMessage("codec-request", &codecRequest));
-
- CHECK(codecRequest->findInt32("what", &what));
- }
- else
- {
- CHECK(msg->findInt32("what", &what));
- }
-
- if (what == Decoder::kWhatFillThisBuffer) {
- DP_MSG_LOW("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++ (%s) kWhatFillThisBuffer",mTrackName);
- if ( (track == kText) && (mTextDecoder == NULL)) {
- break; // no need to proceed further
- }
-
- status_t err = feedDecoderInputData(
- track, msg);
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit Notify\n");
- break;
- }
-
- if (err == -EWOULDBLOCK) {
- status_t nRet = mSource->feedMoreTSData();
- if (nRet == OK) {
- msg->post(10000ll);
- }
- else if(nRet == (status_t)UNKNOWN_ERROR ||
- nRet == (status_t)ERROR_DRM_CANNOT_HANDLE) {
- // reply back to codec if there is an error
- DP_MSG_ERROR("FeedMoreTSData error on track %d ",track);
- if (track == kText) {
- sendTextPacket(NULL, (status_t)UNKNOWN_ERROR);
- } else {
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
- reply->setInt32("err", (status_t)UNKNOWN_ERROR);
- reply->post();
- }
- }
- }
-
- } else if (what == Decoder::kWhatEOS) {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatEOS");
- int32_t err;
- CHECK(msg->findInt32("err", &err));
-
- if (err == ERROR_END_OF_STREAM) {
- DP_MSG_HIGH("got %s decoder EOS", mTrackName);
- } else {
- DP_MSG_ERROR("got %s decoder EOS w/ error %d",
- mTrackName,
- err);
- }
-
- if(track == kVideo && mTimedTextCEAPresent)
- {
- sendTextPacket(NULL, ERROR_END_OF_STREAM, TIMED_TEXT_CEA);
- }
-
- if(mRenderer != NULL)
- {
- if((track == kAudio && !IsFlushingState(mFlushingAudio)) || (track == kVideo && !IsFlushingState(mFlushingVideo))) {
- mRenderer->queueEOS(track, err);
- }
- else{
- DP_MSG_ERROR("FlushingState for %s. Decoder EOS not queued to renderer", mTrackName);
- }
- }
- } else if (what == Decoder::kWhatFlushCompleted) {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatFlushCompleted");
-
- Mutex::Autolock autoLock(mLock);
- bool needShutdown = false;
-
- if (track == kAudio) {
- if(IsFlushingState(mFlushingAudio, &needShutdown)) {
- mFlushingAudio = FLUSHED;
- }
- } else if (track == kVideo){
- if(IsFlushingState(mFlushingVideo, &needShutdown)) {
- mFlushingVideo = FLUSHED;
- }
-
- mVideoLateByUs = 0;
- }
-
- DP_MSG_MEDIUM("decoder %s flush completed", mTrackName);
-
- if (needShutdown) {
- DP_MSG_HIGH("initiating %s decoder shutdown",
- mTrackName);
-
- if (track == kAudio) {
- mAudioDecoder->initiateShutdown();
- mFlushingAudio = SHUTTING_DOWN_DECODER;
- } else if (track == kVideo) {
- mVideoDecoder->initiateShutdown();
- mFlushingVideo = SHUTTING_DOWN_DECODER;
- }
- }
-
- finishFlushIfPossible();
- } else if (what == Decoder::kWhatOutputFormatChanged) {
- sp<AMessage> format;
- CHECK(msg->findMessage("format", &format));
-
- if (track == kAudio) {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatOutputFormatChanged:: audio");
- int32_t numChannels;
- CHECK(format->findInt32("channel-count", &numChannels));
-
- int32_t sampleRate;
- CHECK(format->findInt32("sample-rate", &sampleRate));
-
- DP_MSG_HIGH("Audio output format changed to %d Hz, %d channels",
- sampleRate, numChannels);
- if (mAudioSink != NULL)
- {
- mAudioSink->close();
- }
-
- audio_output_flags_t flags;
- int64_t durationUs;
- // FIXME: we should handle the case where the video decoder is created after
- // we receive the format change indication. Current code will just make that
- // we select deep buffer with video which should not be a problem as it should
- // not prevent from keeping A/V sync.
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit outputFormatChanged\n");
- break;
- }
- if (mVideoDecoder == NULL &&
- mSource->getDuration(&durationUs) == OK &&
- durationUs > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
- flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
- } else {
- flags = AUDIO_OUTPUT_FLAG_NONE;
- }
-
- int32_t channelMask;
- if (!format->findInt32("channel-mask", &channelMask)) {
- channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
- }
-
- CHECK_EQ(mAudioSink->open(
- sampleRate,
- numChannels,
- (audio_channel_mask_t)channelMask,
- AUDIO_FORMAT_PCM_16_BIT,
- 8 /* bufferCount */,
- NULL,
- NULL,
- flags),
- (status_t)OK);
- mAudioSink->start();
-
- if(mRenderer != NULL) {
- mRenderer->signalAudioSinkChanged();
- }
- } else if (track == kVideo) {
- // video
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatOutputFormatChanged:: video");
-
- sp<AMessage> format;
- CHECK(msg->findMessage("format", &format));
- CHECK(format->findInt32("width", &mCurrentWidth));
- CHECK(format->findInt32("height", &mCurrentHeight));
- CHECK(format->findInt32("color-format", &mColorFormat));
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatOutputFormatChanged:: video new height:%d width%d", mCurrentWidth, mCurrentHeight);
- }
- } else if (what == Decoder::kWhatShutdownCompleted) {
- DP_MSG_ERROR("%s shutdown completed", mTrackName);
-
- if((track == kAudio && mFlushingAudio == SHUT_DOWN)
- || (track == kVideo && mFlushingVideo == SHUT_DOWN))
- {
- return;
- }
-
- if (track == kAudio) {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatShutdownCompleted:: audio");
- if (mAudioDecoder != NULL) {
- looper()->unregisterHandler(mAudioDecoder->id());
- }
- mAudioDecoder.clear();
-
- mFlushingAudio = SHUT_DOWN;
- } else if (track == kVideo) {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ kWhatShutdownCompleted:: Video");
- if (mVideoDecoder != NULL) {
- looper()->unregisterHandler(mVideoDecoder->id());
- }
- mVideoDecoder.clear();
-
- mFlushingVideo = SHUT_DOWN;
- }
-
- finishFlushIfPossible();
- } else if (what == Decoder::kWhatError) {
- DP_MSG_ERROR("Received error from %s decoder, aborting playback.",
- mTrackName);
-
- if(track == kVideo && mTimedTextCEAPresent)
- {
- sendTextPacket(NULL, (status_t)UNKNOWN_ERROR, TIMED_TEXT_CEA);
- }
-
- if(mRenderer != NULL)
- {
- if((track == kAudio && !IsFlushingState(mFlushingAudio)) ||
- (track == kVideo && !IsFlushingState(mFlushingVideo)))
- {
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ Codec::kWhatError:: %s",track == kAudio ? "audio" : "video");
- mRenderer->queueEOS(track, (status_t)UNKNOWN_ERROR);
- }
- else{
- DP_MSG_ERROR("EOS not queued for %d track", track);
- }
- }
- } else if (what == Decoder::kWhatDrainThisBuffer) {
- if(track == kAudio || track == kVideo) {
- DP_MSG_LOW("@@@@:: Dashplayer :: MESSAGE FROM CODEC +++++++++++++++++++++++++++++++ Codec::kWhatRenderBuffer:: %s",track == kAudio ? "audio" : "video");
- renderBuffer(track, msg);
- }
- } else {
- DP_MSG_LOW("Unhandled codec notification %d.", what);
- }
-
- break;
- }
-
- case kWhatRendererNotify:
- {
- int32_t what;
- CHECK(msg->findInt32("what", &what));
-
- if (what == Renderer::kWhatEOS) {
- int32_t audio;
- CHECK(msg->findInt32("audio", &audio));
-
- int32_t finalResult;
- CHECK(msg->findInt32("finalResult", &finalResult));
- DP_MSG_LOW("@@@@:: Dashplayer :: MESSAGE FROM RENDERER ***************** kWhatRendererNotify:: %s",audio ? "audio" : "video");
- if (audio) {
- mAudioEOS = true;
- } else {
- mVideoEOS = true;
- }
-
- if (finalResult == ERROR_END_OF_STREAM) {
- DP_MSG_ERROR("reached %s EOS", audio ? "audio" : "video");
- } else {
- DP_MSG_ERROR("%s track encountered an error (%d)",
- audio ? "audio" : "video", finalResult);
-
- notifyListener(
- MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
- }
-
- if ((mAudioEOS || mAudioDecoder == NULL)
- && (mVideoEOS || mVideoDecoder == NULL)) {
- if (finalResult == ERROR_END_OF_STREAM) {
- notifyListener(MEDIA_PLAYBACK_COMPLETE, 0, 0);
- }
- }
- } else if (what == Renderer::kWhatPosition) {
- int64_t positionUs;
- CHECK(msg->findInt64("positionUs", &positionUs));
-
- CHECK(msg->findInt64("videoLateByUs", &mVideoLateByUs));
- DP_MSG_LOW("@@@@:: Dashplayer :: MESSAGE FROM RENDERER ***************** kWhatPosition:: position(%lld) VideoLateBy(%lld)",positionUs,mVideoLateByUs);
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit Notifyposition\n");
- break;
- }
- if (mDriver != NULL) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifyPosition(positionUs);
- mSource->notifyRenderingPosition(positionUs);
- }
- }
- } else if (what == Renderer::kWhatFlushComplete) {
- CHECK_EQ(what, (int32_t)Renderer::kWhatFlushComplete);
-
- int32_t audio;
- CHECK(msg->findInt32("audio", &audio));
- DP_MSG_ERROR("@@@@:: Dashplayer :: MESSAGE FROM RENDERER ***************** kWhatFlushComplete:: %s",audio ? "audio" : "video");
-
- }
- break;
- }
-
- case kWhatReset:
- {
- DP_MSG_ERROR("kWhatReset");
- Mutex::Autolock autoLock(mLock);
-
- if (mRenderer != NULL) {
- // There's an edge case where the renderer owns all output
- // buffers and is paused, therefore the decoder will not read
- // more input data and will never encounter the matching
- // discontinuity. To avoid this, we resume the renderer.
-
- if (mFlushingAudio == AWAITING_DISCONTINUITY
- || mFlushingVideo == AWAITING_DISCONTINUITY) {
- mRenderer->resume();
- }
- }
- if ( (mAudioDecoder != NULL && IsFlushingState(mFlushingAudio)) ||
- (mVideoDecoder != NULL && IsFlushingState(mFlushingVideo)) ) {
-
- // We're currently flushing, postpone the reset until that's
- // completed.
-
- DP_MSG_MEDIUM("postponing reset mFlushingAudio=%d, mFlushingVideo=%d",
- mFlushingAudio, mFlushingVideo);
-
- mResetPostponed = true;
- break;
- }
-
- if (mAudioDecoder == NULL && mVideoDecoder == NULL) {
- finishReset();
- break;
- }
-
- mTimeDiscontinuityPending = true;
-
- if (mAudioDecoder != NULL) {
- flushDecoder(true /* audio */, true /* needShutdown */);
- }
-
- if (mVideoDecoder != NULL) {
- flushDecoder(false /* audio */, true /* needShutdown */);
- }
-
- mResetInProgress = true;
- break;
- }
-
- case kWhatSeek:
- {
- if(mStats != NULL) {
- mStats->notifySeek();
- }
-
- Mutex::Autolock autoLock(mLock);
- int64_t seekTimeUs = -1, newSeekTime = -1;
- status_t nRet = OK;
- CHECK(msg->findInt64("seekTimeUs", &seekTimeUs));
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit Seek\n");
- break;
- }
-
- DP_MSG_ERROR("kWhatSeek seekTimeUs=%lld us (%.2f secs)",
- seekTimeUs, (double)seekTimeUs / 1E6);
- nRet = mSource->seekTo(seekTimeUs);
-
- if (nRet == OK) { // if seek success then flush the audio,video decoder and renderer
- mTimeDiscontinuityPending = true;
- bool audPresence = false;
- bool vidPresence = false;
- bool textPresence = false;
- mSource->getMediaPresence(audPresence,vidPresence,textPresence);
- mRenderer->setMediaPresence(true,audPresence); // audio
- mRenderer->setMediaPresence(false,vidPresence); // video
- if( (mVideoDecoder != NULL) &&
- (mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY) ) {
- flushDecoder( false, true ); // flush video, shutdown
- }
-
- if( (mAudioDecoder != NULL) &&
- (mFlushingAudio == NONE|| mFlushingAudio == AWAITING_DISCONTINUITY) )
- {
- flushDecoder( true, true ); // flush audio, shutdown
- }
- if( mAudioDecoder == NULL ) {
- DP_MSG_LOW("Audio is not there, set it to shutdown");
- mFlushingAudio = SHUT_DOWN;
- }
- if( mVideoDecoder == NULL ) {
- DP_MSG_LOW("Video is not there, set it to shutdown");
- mFlushingVideo = SHUT_DOWN;
- }
- }
- else if (nRet != PERMISSION_DENIED) {
- mTimeDiscontinuityPending = true;
- }
-
- // get the new seeked position
- newSeekTime = seekTimeUs;
- DP_MSG_LOW("newSeekTime %lld", newSeekTime);
- mTimedTextCEASamplesDisc = true;
-
- if(mStats != NULL) {
- mStats->logSeek(seekTimeUs);
- }
-
- if (mDriver != NULL) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- if( newSeekTime >= 0 ) {
- mRenderer->notifySeekPosition(newSeekTime);
- driver->notifyPosition( newSeekTime );
- mSource->notifyRenderingPosition(newSeekTime);
- driver->notifySeekComplete();
- }
- }
- }
-
- break;
- }
-
- case kWhatPause:
- {
- DP_MSG_ERROR("kWhatPause");
- CHECK(mRenderer != NULL);
- mRenderer->pause();
-
- mPauseIndication = true;
-
- Mutex::Autolock autoLock(mLock);
- if (mSource != NULL)
- {
- status_t nRet = mSource->pause();
- }
-
- break;
- }
-
- case kWhatResume:
- {
- DP_MSG_ERROR("kWhatResume");
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit Resume\n");
- break;
- }
- bool disc = mSource->isPlaybackDiscontinued();
- status_t status = OK;
-
- if (disc == true)
- {
- uint64_t nMin = 0, nMax = 0, nMaxDepth = 0;
- status = mSource->getRepositionRange(&nMin, &nMax, &nMaxDepth);
- if (status == OK)
- {
- int64_t seekTimeUs = (int64_t)nMin * 1000ll;
- DP_MSG_ERROR("kWhatSeek seekTimeUs=%lld us (%.2f secs)", seekTimeUs, (double)seekTimeUs / 1E6);
- status = mSource->seekTo(seekTimeUs);
- if (status == OK)
- {
- // if seek success then flush the audio,video decoder and renderer
- mTimeDiscontinuityPending = true;
- bool audPresence = false;
- bool vidPresence = false;
- bool textPresence = false;
- (void)mSource->getMediaPresence(audPresence,vidPresence,textPresence);
- mRenderer->setMediaPresence(true,audPresence); // audio
- mRenderer->setMediaPresence(false,vidPresence); // video
- if( (mVideoDecoder != NULL) &&
- (mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY) ) {
- flushDecoder( false, true ); // flush video, shutdown
- }
-
- if( (mAudioDecoder != NULL) &&
- (mFlushingAudio == NONE|| mFlushingAudio == AWAITING_DISCONTINUITY) )
- {
- flushDecoder( true, true ); // flush audio, shutdown
- }
- if( mAudioDecoder == NULL ) {
- DP_MSG_MEDIUM("Audio is not there, set it to shutdown");
- mFlushingAudio = SHUT_DOWN;
- }
- if( mVideoDecoder == NULL ) {
- DP_MSG_MEDIUM("Video is not there, set it to shutdown");
- mFlushingVideo = SHUT_DOWN;
- }
-
- if (mDriver != NULL)
- {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL)
- {
- if( seekTimeUs >= 0 ) {
- mRenderer->notifySeekPosition(seekTimeUs);
- driver->notifyPosition( seekTimeUs );
- }
- }
- }
-
- mTimedTextCEASamplesDisc = true;
- }
- }
- }
-
- if (status != OK && status != ERROR_END_OF_STREAM)
- {
- //Notify error?
- DP_MSG_ERROR(" Dash Source playback discontinuity check failure");
- notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, status);
- }
-
- Mutex::Autolock autoLock(mLock);
- if (mSource != NULL) {
- status_t nRet = mSource->resume();
- }
-
- if (mAudioDecoder == NULL || mVideoDecoder == NULL || mTextDecoder == NULL) {
- mScanSourcesPending = false;
- postScanSources();
- }
-
- CHECK(mRenderer != NULL);
- mRenderer->resume();
-
- mPauseIndication = false;
-
- break;
- }
-
- case kWhatPrepareAsync:
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null in prepareAsync\n");
- break;
- }
-
- DP_MSG_ERROR("kWhatPrepareAsync");
- mSource->prepareAsync();
- postIsPrepareDone();
- break;
-
- case kWhatIsPrepareDone:
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null when checking for prepare done\n");
- break;
- }
-
- status_t err;
- err = mSource->isPrepareDone();
- if(err == OK) {
- int64_t durationUs;
- if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifyDuration(durationUs);
- }
- }
- DP_MSG_ERROR("PrepareDone complete\n");
- notifyListener(MEDIA_PREPARED, 0, 0);
- } else if(err == -EWOULDBLOCK) {
- msg->post(100000ll);
- } else {
- DP_MSG_ERROR("Prepareasync failed\n");
- notifyListener(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
- }
- break;
- case kWhatSourceNotify:
- {
- Mutex::Autolock autoLock(mLock);
- DP_MSG_ERROR("kWhatSourceNotify");
-
- if(mSource != NULL) {
- int64_t track;
-
- sp<AMessage> sourceRequest;
- DP_MSG_MEDIUM("kWhatSourceNotify - looking for source-request");
-
- // attempt to find message by different names
- bool msgFound = msg->findMessage("source-request", &sourceRequest);
- int32_t handled;
- if (!msgFound){
- DP_MSG_MEDIUM("kWhatSourceNotify source-request not found, trying using sourceRequestID");
- char srName[] = "source-request00";
- (void)snprintf(srName, sizeof(srName), "source-request%d%d", mSRid/10, mSRid%10);
- msgFound = msg->findMessage(srName, &sourceRequest);
- if(msgFound)
- mSRid = (mSRid+1)%SRMax;
- }
-
- if(msgFound)
- {
- int32_t what;
- CHECK(sourceRequest->findInt32("what", &what));
-
- if (what == kWhatBufferingStart) {
- sourceRequest->findInt64("track", &track);
- getTrackName((int)track,mTrackName);
- DP_MSG_ERROR("Source Notified Buffering Start for %s ",mTrackName);
- if (mBufferingNotification == false) {
- if (track == kVideo && mNativeWindow == NULL)
- {
- DP_MSG_ERROR("video decoder not instantiated, no buffering for video(%d)",
- mBufferingNotification);
- }
- else
- {
- mBufferingNotification = true;
- notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_START, 0);
- }
- }
- else {
- DP_MSG_MEDIUM("Buffering Start Event Already Notified mBufferingNotification(%d)",
- mBufferingNotification);
- }
- }
- else if(what == kWhatBufferingEnd) {
- sourceRequest->findInt64("track", &track);
- getTrackName((int)track,mTrackName);
- if (mBufferingNotification) {
- DP_MSG_ERROR("Source Notified Buffering End for %s ",mTrackName);
- mBufferingNotification = false;
- notifyListener(MEDIA_INFO, MEDIA_INFO_BUFFERING_END, 0);
- if(mStats != NULL) {
- mStats->notifyBufferingEvent();
- }
- }
- else {
- DP_MSG_MEDIUM("No need to notify Buffering end as mBufferingNotification is (%d) "
- ,mBufferingNotification);
- }
- }
- }
- }
- else {
- DP_MSG_ERROR("kWhatSourceNotify - Source object does not exist anymore");
- }
- break;
- }
- case kWhatQOE:
- {
- sp<AMessage> dataQOE;
- Parcel notifyDataQOE;
- int64_t timeofday;
- bool msgFound = msg->findMessage("QOEData", &dataQOE);
- if (msgFound)
- {
- int32_t what;
- CHECK(dataQOE->findInt32("what", &what));
- if (what == kWhatQOEPlay)
- {
- dataQOE->findInt64("timeofday",&timeofday);
-
- notifyDataQOE.writeInt64(timeofday);
- }
- else if (what == kWhatQOEStop)
- {
- int32_t bandwidth = 0;
- int32_t reBufCount = 0;
- int32_t stopSize = 0;
- int32_t videoSize = 0;
- AString stopPhrase;
- AString videoUrl;
-
- dataQOE->findInt64("timeofday",&timeofday);
- dataQOE->findInt32("bandwidth",&bandwidth);
- dataQOE->findInt32("rebufct",&reBufCount);
- dataQOE->findInt32("sizestopphrase",&stopSize);
- dataQOE->findString("stopphrase",&stopPhrase);
- dataQOE->findInt32("sizevideo",&videoSize);
- dataQOE->findString("videourl",&videoUrl);
-
- notifyDataQOE.writeInt32(bandwidth);
- notifyDataQOE.writeInt32(reBufCount);
- notifyDataQOE.writeInt64(timeofday);
- notifyDataQOE.writeInt32(stopSize);
- notifyDataQOE.writeInt32(stopSize);
- stopPhrase.append('\0');
- notifyDataQOE.write((const uint8_t *)stopPhrase.c_str(), stopSize+1);
- notifyDataQOE.writeInt32(videoSize);
- notifyDataQOE.writeInt32(videoSize);
- videoUrl.append('\0');
- notifyDataQOE.write((const uint8_t *)videoUrl.c_str(), videoSize+1);
-
- }
- else if (what == kWhatQOESwitch)
- {
- int32_t bandwidth = 0;
- int32_t reBufCount = 0;
-
- dataQOE->findInt64("timeofday",&timeofday);
- dataQOE->findInt32("bandwidth",&bandwidth);
- dataQOE->findInt32("rebufct",&reBufCount);
-
- notifyDataQOE.writeInt32(bandwidth);
- notifyDataQOE.writeInt32(reBufCount);
- notifyDataQOE.writeInt64(timeofday);
- }
- notifyListener(MEDIA_QOE,kWhatQOE,what,&notifyDataQOE);
- }
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void DashPlayer::finishFlushIfPossible() {
-
- /* check if Audio Decoder has been shutdown for handling audio discontinuity
- ,in that case Audio decoder has to be reinstaniated*/
- if (mAudioDecoder == NULL && (mFlushingAudio == SHUT_DOWN) &&
- !mResetInProgress && !mResetPostponed &&
- ((mVideoDecoder != NULL) && (mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY)))
- {
- DP_MSG_LOW("Resuming Audio after Shutdown(Discontinuity)");
- mFlushingAudio = NONE;
- postScanSources();
- return;
- }
- //If reset was postponed after one of the streams is flushed, complete it now
- if (mResetPostponed) {
- DP_MSG_LOW("finishFlushIfPossible Handle reset postpone ");
- if ((mAudioDecoder != NULL) &&
- (mFlushingAudio == NONE || mFlushingAudio == AWAITING_DISCONTINUITY )) {
- flushDecoder( true, true );
- }
- if ((mVideoDecoder != NULL) &&
- (mFlushingVideo == NONE || mFlushingVideo == AWAITING_DISCONTINUITY )) {
- flushDecoder( false, true );
- }
- }
-
- //Check if both audio & video are flushed
- if (mFlushingAudio != FLUSHED && mFlushingAudio != SHUT_DOWN) {
- DP_MSG_LOW("Dont finish flush, audio is in state %d ", mFlushingAudio);
- return;
- }
-
- if (mFlushingVideo != FLUSHED && mFlushingVideo != SHUT_DOWN) {
- DP_MSG_LOW("Dont finish flush, video is in state %d ", mFlushingVideo);
- return;
- }
-
- DP_MSG_HIGH("both audio and video are flushed now.");
-
- if ((mRenderer != NULL) && (mTimeDiscontinuityPending) &&
- !isSetSurfaceTexturePending) {
- mRenderer->signalTimeDiscontinuity();
- mTimeDiscontinuityPending = false;
- }
-
- if (mAudioDecoder != NULL) {
- DP_MSG_LOW("Resume Audio after flush");
- mAudioDecoder->signalResume();
- }
-
- if (mVideoDecoder != NULL) {
- DP_MSG_LOW("Resume Video after flush");
- mVideoDecoder->signalResume();
- }
-
- mFlushingAudio = NONE;
- mFlushingVideo = NONE;
-
- if (mResetInProgress) {
- DP_MSG_ERROR("reset completed");
-
- mResetInProgress = false;
- finishReset();
- } else if (mResetPostponed) {
- (new AMessage(kWhatReset, this))->post();
- mResetPostponed = false;
- DP_MSG_LOW("Handle reset postpone");
- }else if(isSetSurfaceTexturePending){
- processDeferredActions();
- DP_MSG_ERROR("DashPlayer::finishFlushIfPossible() setsurfacetexturepending=true");
- } else if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
- DP_MSG_LOW("Start scanning for sources after shutdown");
- if (mTextDecoder != NULL)
- {
- if (mSource != NULL) {
- DP_MSG_LOW("finishFlushIfPossible calling mSource->stop");
- mSource->stop();
- }
- sp<AMessage> codecRequest;
- mTextNotify->findMessage("codec-request", &codecRequest);
- codecRequest = NULL;
- mTextNotify = NULL;
- looper()->unregisterHandler(mTextDecoder->id());
- mTextDecoder.clear();
- }
- postScanSources();
- }
-}
-
-void DashPlayer::finishReset() {
- CHECK(mAudioDecoder == NULL);
- CHECK(mVideoDecoder == NULL);
-
- ++mScanSourcesGeneration;
- mScanSourcesPending = false;
-
- if (mRenderer != NULL) {
- looper()->unregisterHandler(mRenderer->id());
- mRenderer.clear();
- }
-
- if (mSource != NULL) {
- DP_MSG_ERROR("finishReset calling mSource->stop");
- mSource->stop();
- mSource.clear();
- }
-
- if ( (mTextDecoder != NULL) && (mTextNotify != NULL))
- {
- sp<AMessage> codecRequest;
- mTextNotify->findMessage("codec-request", &codecRequest);
- codecRequest = NULL;
- mTextNotify = NULL;
- looper()->unregisterHandler(mTextDecoder->id());
- mTextDecoder.clear();
- DP_MSG_ERROR("Text Dummy Decoder Deleted");
- }
- if (mSourceNotify != NULL)
- {
- sp<AMessage> sourceRequest;
- mSourceNotify->findMessage("source-request", &sourceRequest);
- sourceRequest = NULL;
- for (int id = 0; id < SRMax; id++){
- char srName[] = "source-request00";
- (void)snprintf(srName, sizeof(srName), "source-request%d%d", id/10, id%10);
- mSourceNotify->findMessage(srName, &sourceRequest);
- sourceRequest = NULL;
- }
- mSourceNotify = NULL;
- }
-
- if (mDriver != NULL) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifyResetComplete();
- }
- }
-}
-
-void DashPlayer::postScanSources() {
- if (mScanSourcesPending) {
- return;
- }
-
- sp<AMessage> msg = new AMessage(kWhatScanSources, this);
- msg->setInt32("generation", mScanSourcesGeneration);
- msg->post();
-
- mScanSourcesPending = true;
-}
-
-status_t DashPlayer::instantiateDecoder(int track, sp<Decoder> *decoder) {
- DP_MSG_LOW("@@@@:: instantiateDecoder Called ");
- if (*decoder != NULL) {
- return OK;
- }
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is null. Exit instantiateDecoder\n");
- return -EWOULDBLOCK;
- }
-
- sp<MetaData> meta = mSource->getFormat(track);
-
- if (meta == NULL) {
- return -EWOULDBLOCK;
- }
-
- if (track == kVideo) {
- const char *mime = NULL;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
- mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime);
- if(mStats != NULL) {
- mStats->setMime(mime);
- }
-
- if (mSetVideoSize) {
- int32_t width = 0;
- meta->findInt32(kKeyWidth, &width);
- int32_t height = 0;
- meta->findInt32(kKeyHeight, &height);
- DP_MSG_HIGH("instantiate video decoder, send wxh = %dx%d",width,height);
- notifyListener(MEDIA_SET_VIDEO_SIZE, width, height);
- mSetVideoSize = false;
- }
- }
-
- sp<AMessage> notify;
- if (track == kAudio) {
- notify = new AMessage(kWhatAudioNotify ,this);
- DP_MSG_HIGH("Creating Audio Decoder ");
- *decoder = new Decoder(notify);
- DP_MSG_LOW("@@@@:: setting Sink/Renderer pointer to decoder");
- if (mRenderer != NULL) {
- mRenderer->setMediaPresence(true,true);
- }
- } else if (track == kVideo) {
- notify = new AMessage(kWhatVideoNotify ,this);
- *decoder = new Decoder(notify, mNativeWindow);
- DP_MSG_HIGH("Creating Video Decoder ");
- if (mRenderer != NULL) {
- mRenderer->setMediaPresence(false,true);
- }
- } else if (track == kText) {
- mTextNotify = new AMessage(kWhatTextNotify ,this);
- *decoder = new Decoder(mTextNotify);
- sp<AMessage> codecRequest = new AMessage;
- codecRequest->setInt32("what", Decoder::kWhatFillThisBuffer);
- mTextNotify->setMessage("codec-request", codecRequest);
- DP_MSG_HIGH("Creating Dummy Text Decoder ");
- if (mSource != NULL) {
- mSource->setupSourceData(mTextNotify, track);
- }
- }
-
- if(track != kAudio && track != kVideo)
- {
- looper()->registerHandler(*decoder);
- }
-
- char value[PROPERTY_VALUE_MAX] = {0};
- //Set flushing state to none
- Mutex::Autolock autoLock(mLock);
- if(track == kAudio) {
- mFlushingAudio = NONE;
- } else if (track == kVideo) {
- mFlushingVideo = NONE;
- }
-
- if( (track == kAudio || track == kVideo) && ((*decoder) != NULL)) {
- (*decoder)->init();
- (*decoder)->configure(meta);
- }
-
- int64_t durationUs;
- if (mDriver != NULL && mSource->getDuration(&durationUs) == OK) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifyDuration(durationUs);
- }
- }
-
- return OK;
-}
-
-status_t DashPlayer::feedDecoderInputData(int track, const sp<AMessage> &msg) {
- sp<AMessage> reply;
-
- if ( (track != kText) && !(msg->findMessage("reply", &reply)))
- {
- CHECK(msg->findMessage("reply", &reply));
- }
-
- {
- Mutex::Autolock autoLock(mLock);
-
- if (reply != NULL && (((track == kAudio) && IsFlushingState(mFlushingAudio))
- || ((track == kVideo) && IsFlushingState(mFlushingVideo))
- || mSource == NULL)) {
- reply->setInt32("err", INFO_DISCONTINUITY);
- reply->post();
- return OK;
- }
- }
-
- getTrackName(track,mTrackName);
-
- sp<ABuffer> accessUnit;
-
- bool dropAccessUnit;
- do {
-
- status_t err = (status_t)UNKNOWN_ERROR;
-
- err = mSource->dequeueAccessUnit(track, &accessUnit);
-
- if (err == -EWOULDBLOCK) {
- return err;
- } else if (err != OK) {
- if (err == INFO_DISCONTINUITY) {
- int32_t type;
- CHECK(accessUnit->meta()->findInt32("discontinuity", &type));
-
- bool formatChange =
- ((track == kAudio) &&
- (type & ATSParser::DISCONTINUITY_AUDIO_FORMAT))
- || ((track == kVideo) &&
- (type & ATSParser::DISCONTINUITY_VIDEO_FORMAT));
-
- bool timeChange = (type & ATSParser::DISCONTINUITY_TIME) != 0;
-
- DP_MSG_HIGH("%s discontinuity (formatChange=%d, time=%d)",
- mTrackName, formatChange, timeChange);
-
- if (track == kAudio) {
- mSkipRenderingAudioUntilMediaTimeUs = -1;
- } else if (track == kVideo) {
- mSkipRenderingVideoUntilMediaTimeUs = -1;
- }
-
- if (timeChange) {
- sp<AMessage> extra;
- if (accessUnit->meta()->findMessage("extra", &extra)
- && extra != NULL) {
- int64_t resumeAtMediaTimeUs;
- if (extra->findInt64(
- "resume-at-mediatimeUs", &resumeAtMediaTimeUs)) {
- DP_MSG_HIGH("suppressing rendering of %s until %lld us",
- mTrackName, resumeAtMediaTimeUs);
-
- if (track == kAudio) {
- mSkipRenderingAudioUntilMediaTimeUs =
- resumeAtMediaTimeUs;
- } else if (track == kVideo) {
- mSkipRenderingVideoUntilMediaTimeUs =
- resumeAtMediaTimeUs;
- }
- }
- }
- }
-
- mTimeDiscontinuityPending =
- mTimeDiscontinuityPending || timeChange;
-
- if (formatChange || timeChange) {
- flushDecoder(track, formatChange);
- } else {
- // This stream is unaffected by the discontinuity
-
- if (track == kAudio) {
- mFlushingAudio = FLUSHED;
- } else if (track == kVideo) {
- mFlushingVideo = FLUSHED;
- }
-
- finishFlushIfPossible();
-
- return -EWOULDBLOCK;
- }
- }
-
- if ( (track == kAudio) ||
- (track == kVideo))
- {
- reply->setInt32("err", err);
- reply->post();
- return OK;
- }
- else if ((track == kText) &&
- (err == ERROR_END_OF_STREAM || err == (status_t)UNKNOWN_ERROR)) {
- DP_MSG_ERROR("Text track has encountered error %d", err );
- sendTextPacket(NULL, err);
- return err;
- }
- }
-
- dropAccessUnit = false;
- if (track == kVideo) {
-
- if(mStats != NULL) {
- mStats->incrementTotalFrames();
- }
-
- if (mVideoLateByUs > 100000ll
- && mVideoIsAVC
- && !IsAVCReferenceFrame(accessUnit)) {
- dropAccessUnit = true;
- if(mStats != NULL) {
- mStats->incrementDroppedFrames();
- }
- }
- }
- } while (dropAccessUnit);
-
- // DP_MSG_LOW("returned a valid buffer of %s data", mTrackName);
-
- if (track == kVideo || track == kAudio) {
- reply->setBuffer("buffer", accessUnit);
- reply->post();
- } else if (track == kText) {
- sendTextPacket(accessUnit,OK);
- if (mSource != NULL) {
- mSource->postNextTextSample(accessUnit,mTextNotify,track);
- }
- }
- return OK;
-}
-
-void DashPlayer::renderBuffer(bool audio, const sp<AMessage> &msg) {
- // DP_MSG_LOW("renderBuffer %s", audio ? "audio" : "video");
-
- sp<AMessage> reply;
- CHECK(msg->findMessage("reply", &reply));
-
- Mutex::Autolock autoLock(mLock);
- if (IsFlushingState(audio ? mFlushingAudio : mFlushingVideo)) {
- // We're currently attempting to flush the decoder, in order
- // to complete this, the decoder wants all its buffers back,
- // so we don't want any output buffers it sent us (from before
- // we initiated the flush) to be stuck in the renderer's queue.
-
- DP_MSG_MEDIUM("we're still flushing the %s decoder, sending its output buffer"
- " right back.", audio ? "audio" : "video");
-
- reply->post();
- return;
- }
-
- sp<ABuffer> buffer;
- CHECK(msg->findBuffer("buffer", &buffer));
-
- int64_t &skipUntilMediaTimeUs =
- audio
- ? mSkipRenderingAudioUntilMediaTimeUs
- : mSkipRenderingVideoUntilMediaTimeUs;
-
- if (skipUntilMediaTimeUs >= 0) {
- int64_t mediaTimeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
- if (mediaTimeUs < skipUntilMediaTimeUs) {
- DP_MSG_HIGH("dropping %s buffer at time %lld as requested.",
- audio ? "audio" : "video",
- mediaTimeUs);
-
- reply->post();
- return;
- }
-
- skipUntilMediaTimeUs = -1;
- }
-
- if(mRenderer != NULL)
- {
- if(!audio)
- {
- int32_t extradata = 0;
-
- if (buffer->meta()->findInt32("extradata", &extradata) && 1 == extradata)
- {
- DP_MSG_HIGH("kwhatdrainthisbuffer: Decoded sample contains SEI. Parse for CEA encoded cc extradata");
-
- sp<RefBase> obj;
-
- if (buffer->meta()->findObject("graphic-buffer", &obj))
- {
- sp<GraphicBuffer> graphicBuffer = static_cast<GraphicBuffer*>(obj.get());
- if (graphicBuffer != NULL)
- {
- DP_MSG_LOW("kwhatdrainthisbuffer: Extradata present",
- "graphicBuffer = %p, width=%d height=%d color-format=%d",
- graphicBuffer.get(), mCurrentWidth, mCurrentHeight, mColorFormat);
-
- if (mColorFormat == 0x7FA30C04 /*OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m*/)
- {
- size_t filledLen = (VENUS_Y_STRIDE(COLOR_FMT_NV12, mCurrentWidth)
- * VENUS_Y_SCANLINES(COLOR_FMT_NV12, mCurrentHeight))
- + (VENUS_UV_STRIDE(COLOR_FMT_NV12, mCurrentWidth)
- * VENUS_UV_SCANLINES(COLOR_FMT_NV12, mCurrentHeight));
- size_t allocLen = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mCurrentWidth, mCurrentHeight);
- size_t offset = buffer->offset();
-
- DP_MSG_LOW("kwhatdrainthisbuffer: decoded buffer ranges "
- "filledLen = %lu, allocLen = %lu, startOffset = %lu",
- filledLen, allocLen, offset);
-
- // 'lock' returns mapped virtual address that can be read from or written into
- // Use GRALLOC_USAGE_SW_READ_MASK / WRITE_MASK to indicate access type
- // 'unlock' will unmap the mapped address
-
- void *yuvData = NULL;
- graphicBuffer->lock(GRALLOC_USAGE_SW_READ_MASK, &yuvData);
-
- if (yuvData)
- {
- OMX_OTHER_EXTRADATATYPE *pExtra;
- pExtra = (OMX_OTHER_EXTRADATATYPE *)((unsigned long)((OMX_U8*)yuvData + offset + filledLen + 3)&(~3));
-
- while (pExtra &&
- ((OMX_U8*)pExtra + pExtra->nSize) <= ((OMX_U8*)yuvData + allocLen) &&
- pExtra->eType != OMX_ExtraDataNone )
- {
- DP_MSG_LOW(
- "============== Extra Data ==============\n"
- " Size: %lu\n"
- " Version: %lu\n"
- " PortIndex: %lu\n"
- " Type: %x\n"
- " DataSize: %lu",
- pExtra->nSize, pExtra->nVersion.nVersion,
- pExtra->nPortIndex, pExtra->eType, pExtra->nDataSize);
-
- if(pExtra->eType == (OMX_EXTRADATATYPE) OMX_ExtraDataMP2UserData)
- {
- OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)pExtra->data;
- OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
- OMX_U32 userdata_size = pExtra->nDataSize - sizeof(userdata->type);
-
- DP_MSG_LOW(
- "-------------- OMX_ExtraDataMP2UserData Userdata -------------\n"
- " Stream userdata type: %lu\n"
- " userdata size: %lu\n"
- " STREAM_USERDATA:",
- userdata->type, userdata_size);
-
- for (uint32_t i = 0; i < userdata_size; i+=4) {
- DP_MSG_LOW(" %x %x %x %x",
- data_ptr[i], data_ptr[i+1],
- data_ptr[i+2], data_ptr[i+3]);
- }
-
- DP_MSG_LOW(
- "-------------- End of OMX_ExtraDataMP2UserData Userdata -----------");
-
- /*
- SEI Syntax
-
- user_data_registered_itu_t_t35 ( ) {
- itu_t_t35_country_code (8 bits)
- itu_t_t35_provider_code (16 bits)
- user_identifier (32 bits)
- user_structure( )
- }
-
- cc_data parsing logic
- 1. itu_t_t35_country_code - A fixed 8-bit field, the value of which shall be 0xB5.3
- itu_t_35_provider_code - A fixed 16-bit field, the value of which shall be 0x0031.
- 2. user_identifier should match 0x47413934 ('GA94') ATSC_user_data( )
-
- ATSC_user_data Syntax
- ATSC_user_data() {
- user_data_type_code (8 bits)
- user_data_type_structure()
- }
-
- 3. user_data_type_code should match 0x03 MPEG_cc_data()
-
- */
-
- if(0xB5 == data_ptr[0] && 0x00 == data_ptr[1] && 0x31 == data_ptr[2]
- && 0x47 == data_ptr[3] && 0x41 == data_ptr[4] && 0x39 == data_ptr[5] && 0x34 == data_ptr[6]
- && 0x03 == data_ptr[7])
- {
- DP_MSG_HIGH("SEI payload user_data_type_code is CEA encoded MPEG_cc_data()");
-
- OMX_U32 cc_data_size = 0;
- for(int i = 8; data_ptr[i] != 0xFF /*each cc_data ends with marker bits*/; i++)
- {
- cc_data_size++;
- }
-
- if(cc_data_size > 0)
- {
- DP_MSG_LOW(
- "-------------- MPEG_cc_data() -------------\n"
- " cc_data ptr: %p cc_data_size: %lu\n",
- &data_ptr[8], cc_data_size);
-
- for (uint32_t i = 8; i < 8 + cc_data_size; i+=4) {
- DP_MSG_LOW(" %x %x %x %x",
- data_ptr[i], data_ptr[i+1],
- data_ptr[i+2], data_ptr[i+3]);
- }
-
- DP_MSG_LOW(
- "-------------- End of MPEG_cc_data() -------------\n");
-
- sp<ABuffer> accessUnit = new ABuffer((OMX_U8*)&data_ptr[8], cc_data_size);
-
- int64_t mediaTimeUs;
-
- sp<ABuffer> buffer;
- CHECK(msg->findBuffer("buffer", &buffer));
- CHECK(buffer->meta()->findInt64("timeUs", &mediaTimeUs));
- accessUnit->meta()->setInt64("timeUs",mediaTimeUs);
-
- //To signal discontinuity in samples during seek and resume-out-of-tsb(internal seek) operations
- if(mTimedTextCEASamplesDisc)
- {
- accessUnit->meta()->setInt32("disc", 1);
- mTimedTextCEASamplesDisc = false;
- }
-
- //Indicate timedtext CEA present in stream. Used to signal EOS in Codec::kWhatEOS
- if(!mTimedTextCEAPresent)
- {
- mTimedTextCEAPresent = true;
- }
-
- sendTextPacket(accessUnit, OK, TIMED_TEXT_CEA);
-
- accessUnit = NULL;
- break;
- }
- }
- }
-
- pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize);
- }
- graphicBuffer->unlock();
- }
- }
- }
- }
- }
- }
-
- mRenderer->queueBuffer(audio, buffer, reply);
- }
-}
-
-void DashPlayer::notifyListener(int msg, int ext1, int ext2, const Parcel *obj) {
- if (mDriver == NULL) {
- return;
- }
-
- sp<DashPlayerDriver> driver = mDriver.promote();
-
- if (driver == NULL) {
- return;
- }
-
- driver->notifyListener(msg, ext1, ext2, obj);
-}
-
-void DashPlayer::flushDecoder(bool audio, bool needShutdown) {
- if ((audio && mAudioDecoder == NULL) || (!audio && mVideoDecoder == NULL)) {
- DP_MSG_HIGH("flushDecoder %s without decoder present",
- audio ? "audio" : "video");
- }
-
- // Make sure we don't continue to scan sources until we finish flushing.
- ++mScanSourcesGeneration;
- mScanSourcesPending = false;
-
- (audio ? mAudioDecoder : mVideoDecoder)->signalFlush();
-
- if(mRenderer != NULL) {
- mRenderer->flush(audio);
- }
-
- FlushStatus newStatus =
- needShutdown ? FLUSHING_DECODER_SHUTDOWN : FLUSHING_DECODER;
-
- if (audio) {
- CHECK(mFlushingAudio == NONE
- || mFlushingAudio == AWAITING_DISCONTINUITY);
-
- mFlushingAudio = newStatus;
-
- if (mFlushingVideo == NONE) {
- mFlushingVideo = (mVideoDecoder != NULL)
- ? AWAITING_DISCONTINUITY
- : FLUSHED;
- }
- } else {
- CHECK(mFlushingVideo == NONE
- || mFlushingVideo == AWAITING_DISCONTINUITY);
-
- mFlushingVideo = newStatus;
-
- if (mFlushingAudio == NONE) {
- mFlushingAudio = (mAudioDecoder != NULL)
- ? AWAITING_DISCONTINUITY
- : FLUSHED;
- }
- }
-}
-
-sp<DashPlayer::Source>
- DashPlayer::LoadCreateSource(const char * uri, const KeyedVector<String8,String8> *headers,
- bool uidValid, uid_t uid)
-{
- const char* STREAMING_SOURCE_LIB = "libmmipstreamaal.so";
- const char* DASH_HTTP_LIVE_CREATE_SOURCE = "CreateDashHttpLiveSource";
- void* pStreamingSourceLib = NULL;
-
- typedef DashPlayer::Source* (*SourceFactory)(const char * uri, const KeyedVector<String8, String8> *headers, bool uidValid, uid_t uid);
-
- /* Open librery */
- pStreamingSourceLib = ::dlopen(STREAMING_SOURCE_LIB, RTLD_LAZY);
-
- if (pStreamingSourceLib == NULL) {
- DP_MSG_ERROR("@@@@:: STREAMING Source Library (libmmipstreamaal.so) Load Failed Error : %s ",::dlerror());
- return NULL;
- }
-
- SourceFactory StreamingSourcePtr = NULL;
-
- StreamingSourcePtr = (SourceFactory) dlsym(pStreamingSourceLib, DASH_HTTP_LIVE_CREATE_SOURCE);
-
- if (StreamingSourcePtr == NULL) {
- DP_MSG_ERROR("@@@@:: CreateDashHttpLiveSource symbol not found in libmmipstreamaal.so, return NULL ");
- return NULL;
- }
-
- /*Get the Streaming (DASH) Source object, which will be used to communicate with Source (DASH) */
- sp<DashPlayer::Source> StreamingSource = StreamingSourcePtr(uri, headers, uidValid, uid);
-
- if(StreamingSource==NULL) {
- DP_MSG_ERROR("@@@@:: StreamingSource failed to instantiate Source ");
- return NULL;
- }
-
- return StreamingSource;
-}
-
-status_t DashPlayer::prepareAsync() // only for DASH
-{
- sp<AMessage> msg = new AMessage(kWhatPrepareAsync, this);
- if (msg == NULL)
- {
- DP_MSG_ERROR("Out of memory, AMessage is null for kWhatPrepareAsync\n");
- return NO_MEMORY;
- }
- msg->post();
- return -EWOULDBLOCK;
-
- return OK;
-}
-
-status_t DashPlayer::getParameter(int key, Parcel *reply)
-{
- void * data_8;
- void * data_16;
- size_t data_8_Size;
- size_t data_16_Size;
-
- status_t err = OK;
-
- if (mSource == NULL)
- {
- DP_MSG_ERROR("Source is NULL in getParameter\n");
- return ((status_t)UNKNOWN_ERROR);
- }
- if (key == KEY_DASH_REPOSITION_RANGE)
- {
- uint64_t nMin = 0, nMax = 0, nMaxDepth = 0;
- err = mSource->getRepositionRange(&nMin, &nMax, &nMaxDepth);
- if(err == OK || err == ERROR_END_OF_STREAM)
- {
- reply->setDataPosition(0);
- reply->writeInt64(nMin);
- reply->writeInt64(nMax);
- reply->writeInt64(nMaxDepth);
- err = OK;
- DP_MSG_LOW("DashPlayer::getParameter KEY_DASH_REPOSITION_RANGE %lld, %lld", nMin, nMax);
- }
- else
- {
- DP_MSG_ERROR("DashPlayer::getParameter KEY_DASH_REPOSITION_RANGE err in NOT OK");
- }
- }
- else if(key == INVOKE_ID_GET_TRACK_INFO)
- {
- size_t numInbandTracks = (mSource != NULL) ? mSource->getTrackCount() : 0;
- DP_MSG_HIGH("DashPlayer::getParameter #InbandTracks %d ", numInbandTracks);
- // total track count
- reply->writeInt32(numInbandTracks);
- // write inband tracks
- for (size_t i = 0; i < numInbandTracks; ++i) {
- writeTrackInfo(reply, mSource->getTrackInfo(i));
- }
- }
- else
- {
- err = mSource->getParameter(key, &data_8, &data_8_Size);
- if (key == KEY_DASH_QOE_PERIODIC_EVENT)
- {
- if (err == OK)
- {
- if(data_8)
- {
- sp<AMessage> dataQOE;
- dataQOE = (AMessage*)(data_8);
- int32_t bandwidth = 0;
- int32_t ipaddSize = 0;
- int32_t videoSize = 0;
- int64_t timeofday = 0;
- AString ipAdd;
- AString videoUrl;
-
- dataQOE->findInt64("timeofday",&timeofday);
- dataQOE->findInt32("bandwidth",&bandwidth);
- dataQOE->findInt32("sizeipadd",&ipaddSize);
- dataQOE->findString("ipaddress",&ipAdd);
- dataQOE->findInt32("sizevideo",&videoSize);
- dataQOE->findString("videourl",&videoUrl);
-
- reply->setDataPosition(0);
- reply->writeInt32(bandwidth);
- reply->writeInt64(timeofday);
- reply->writeInt32(ipaddSize);
- reply->writeInt32(ipaddSize);
- reply->write((const uint8_t *)ipAdd.c_str(), ipaddSize);
- reply->writeInt32(videoSize);
- reply->writeInt32(videoSize);
- videoUrl.append('\0');
- reply->write((const uint8_t *)videoUrl.c_str(), videoSize+1);
- }else
- {
- DP_MSG_ERROR("DashPlayerStats::getParameter : data_8 is null");
- }
- }
- }
- else
- {
- if (err != OK)
- {
- DP_MSG_ERROR("source getParameter returned error: %d\n",err);
- return err;
- }
-
- data_16_Size = data_8_Size * sizeof(char16_t);
- data_16 = malloc(data_16_Size);
- if (data_16 == NULL)
- {
- DP_MSG_ERROR("Out of memory in getParameter\n");
- return NO_MEMORY;
- }
-
- utf8_to_utf16_no_null_terminator((uint8_t *)data_8, data_8_Size, (char16_t *) data_16);
- err = reply->writeString16((char16_t *)data_16, data_8_Size);
- free(data_16);
- }
- }
- return err;
-}
-
-void DashPlayer::writeTrackInfo(
- Parcel* reply, const sp<AMessage> format) const
-{
- int32_t trackType;
- AString lang;
- AString mime;
- CHECK(format->findInt32("type", &trackType));
- CHECK(format->findString("language", &lang));
- CHECK(format->findString("mime", &mime));
- reply->writeInt32(2);
- reply->writeInt32(trackType);
- reply->writeString16(String16(mime.c_str()));
- reply->writeString16(String16(lang.c_str()));
-}
-
-
-
-status_t DashPlayer::setParameter(int key, const Parcel &request)
-{
- status_t err = (status_t)UNKNOWN_ERROR;;
- if (KEY_DASH_ADAPTION_PROPERTIES == key ||
- KEY_DASH_SET_ADAPTION_PROPERTIES == key)
- {
- size_t len = 0;
- const char16_t* str = request.readString16Inplace(&len);
- void * data = malloc(len + 1);
- if (data == NULL)
- {
- DP_MSG_ERROR("Out of memory in setParameter\n");
- return NO_MEMORY;
- }
-
- utf16_to_utf8(str, len, (char*) data);
- if (mSource != NULL)
- {
- err = mSource->setParameter(key, data, len);
- }
- free(data);
- }else if(key == KEY_DASH_QOE_EVENT)
- {
- int value = request.readInt32();
- if (mSource != NULL)
- {
- err = mSource->setParameter(key, &value, sizeof(value));
- }
- }
- return err;
-}
-
-void DashPlayer::postIsPrepareDone()
-{
- sp<AMessage> msg = new AMessage(kWhatIsPrepareDone, this);
- if (msg == NULL)
- {
- DP_MSG_ERROR("Out of memory, AMessage is null for kWhatIsPrepareDone\n");
- return;
- }
- msg->post();
-}
-void DashPlayer::sendTextPacket(sp<ABuffer> accessUnit,status_t err, TimedTextType eTimedTextType)
-{
- if(!mQCTimedTextListenerPresent)
- {
- return;
- }
-
- Parcel parcel;
- int mFrameType = TIMED_TEXT_FLAG_FRAME;
-
- //Local setting
- parcel.writeInt32(KEY_LOCAL_SETTING);
-
- parcel.writeInt32(KEY_TEXT_FORMAT);
- // UPDATE TIMEDTEXT SAMPLE TYPE
- //Currently dash only support SMPTE-TT and CEA formats. No support for other timedtext types (like WebVTT, SRT)
- if(eTimedTextType == TIMED_TEXT_SMPTE)
- {
- parcel.writeString16((String16)"smptett");
- }
- else if(eTimedTextType == TIMED_TEXT_CEA)
- {
- parcel.writeString16((String16)"cea");
- }
- else
- {
- parcel.writeString16((String16)"unknown");
- }
-
- // UPDATE TIMEDTEXT SAMPLE FLAGS
- parcel.writeInt32(KEY_TEXT_FLAG_TYPE);
- if (err == ERROR_END_OF_STREAM ||
- err == (status_t)UNKNOWN_ERROR)
- {
- parcel.writeInt32(TIMED_TEXT_FLAG_EOS);
- // write size of sample
- DP_MSG_ERROR("sendTextPacket Error End Of Stream EOS");
- mFrameType = TIMED_TEXT_FLAG_EOS;
- notifyListener(MEDIA_TIMED_TEXT, 0, mFrameType, &parcel);
- return;
- }
-
- int32_t tCodecConfig = 0;
- accessUnit->meta()->findInt32("conf", &tCodecConfig);
- if(tCodecConfig)
- {
- DP_MSG_HIGH("Timed text codec config frame");
- parcel.writeInt32(TIMED_TEXT_FLAG_CODEC_CONFIG);
- mFrameType = TIMED_TEXT_FLAG_CODEC_CONFIG;
- }
- else
- {
- parcel.writeInt32(TIMED_TEXT_FLAG_FRAME);
- mFrameType = TIMED_TEXT_FLAG_FRAME;
- }
-
- int32_t bDisc = 0;
- accessUnit->meta()->findInt32("disc", &bDisc);
- if(bDisc == 1)
- {
- DP_MSG_HIGH("sendTextPacket signal discontinuity");
- parcel.writeInt32(KEY_TEXT_DISCONTINUITY);
- }
-
- // UPDATE TIMEDTEXT SAMPLE TEXT DATA
- parcel.writeInt32(KEY_STRUCT_TEXT);
- // write size of sample
- parcel.writeInt32((int32_t)accessUnit->size());
- parcel.writeInt32((int32_t)accessUnit->size());
- // write sample payload
- parcel.write((const uint8_t *)accessUnit->data(), accessUnit->size());
-
- // UPDATE TIMEDTEXT SAMPLE PROPERTIES
- int64_t mediaTimeUs = 0;
- CHECK(accessUnit->meta()->findInt64("timeUs", &mediaTimeUs));
- parcel.writeInt32(KEY_START_TIME);
- parcel.writeInt32((int32_t)(mediaTimeUs / 1000)); // convert micro sec to milli sec
-
- DP_MSG_HIGH("sendTextPacket Text Track Timestamp (%0.2f) sec",(double)mediaTimeUs / 1E6);
-
- int32_t height = 0;
- if (accessUnit->meta()->findInt32("height", &height)) {
- DP_MSG_LOW("sendTextPacket Height (%d)",height);
- parcel.writeInt32(KEY_HEIGHT);
- parcel.writeInt32(height);
- }
-
- // width
- int32_t width = 0;
- if (accessUnit->meta()->findInt32("width", &width)) {
- DP_MSG_LOW("sendTextPacket width (%d)",width);
- parcel.writeInt32(KEY_WIDTH);
- parcel.writeInt32(width);
- }
-
- // Duration
- int32_t duration = 0;
- if (accessUnit->meta()->findInt32("duration", &duration)) {
- DP_MSG_LOW("sendTextPacket duration (%d)",duration);
- parcel.writeInt32(KEY_DURATION);
- parcel.writeInt32(duration);
- }
-
- // start offset
- int32_t startOffset = 0;
- if (accessUnit->meta()->findInt32("startoffset", &startOffset)) {
- DP_MSG_LOW("sendTextPacket startOffset (%d)",startOffset);
- parcel.writeInt32(KEY_START_OFFSET);
- parcel.writeInt32(startOffset);
- }
-
- // SubInfoSize
- int32_t subInfoSize = 0;
- if (accessUnit->meta()->findInt32("subSz", &subInfoSize)) {
- DP_MSG_LOW("sendTextPacket subInfoSize (%d)",subInfoSize);
- }
-
- // SubInfo
- AString subInfo;
- if (accessUnit->meta()->findString("subSi", &subInfo)) {
- parcel.writeInt32(KEY_SUB_ATOM);
- parcel.writeInt32(subInfoSize);
- parcel.writeInt32(subInfoSize);
- parcel.write((const uint8_t *)subInfo.c_str(), subInfoSize);
- }
-
- notifyListener(MEDIA_TIMED_TEXT, 0, mFrameType, &parcel);
-}
-
-void DashPlayer::getTrackName(int track, char* name)
-{
- if( track == kAudio)
- {
- memset(name,0x00,6);
- strlcpy(name, "audio",6);
- }
- else if( track == kVideo)
- {
- memset(name,0x00,6);
- strlcpy(name, "video",6);
- }
- else if( track == kText)
- {
- memset(name,0x00,6);
- strlcpy(name, "text",5);
- }
- else if (track == kTrackAll)
- {
- memset(name,0x00,6);
- strlcpy(name, "all",4);
- }
-}
-
-void DashPlayer::prepareSource()
-{
- mSourceNotify = new AMessage(kWhatSourceNotify ,this);
- mQOENotify = new AMessage(kWhatQOE,this);
- if (mSource != NULL)
- {
- mSource->setupSourceData(mSourceNotify,kTrackAll);
- mSource->setupSourceData(mQOENotify,-1);
- }
-}
-
-status_t DashPlayer::dump(int fd, const Vector<String16> &/*args*/)
-{
- if(mStats != NULL) {
- mStats->setFileDescAndOutputStream(fd);
- }
-
- return OK;
-}
-
-void DashPlayer::setQCTimedTextListener(const bool val)
-{
- mQCTimedTextListenerPresent = val;
- DP_MSG_HIGH("QCTimedtextlistener turned %s", mQCTimedTextListenerPresent ? "ON" : "OFF");
-}
-
-void DashPlayer::processDeferredActions() {
- while (!mDeferredActions.empty()) {
- // We won't execute any deferred actions until we're no longer in
- // an intermediate state, i.e. one more more decoders are currently
- // flushing or shutting down.
-
- if (mRenderer != NULL) {
- // There's an edge case where the renderer owns all output
- // buffers and is paused, therefore the decoder will not read
- // more input data and will never encounter the matching
- // discontinuity. To avoid this, we resume the renderer.
-
- if (mFlushingAudio == AWAITING_DISCONTINUITY
- || mFlushingVideo == AWAITING_DISCONTINUITY) {
- mRenderer->resume();
- }
- }
-
- if ((mFlushingAudio != NONE && mFlushingAudio != SHUT_DOWN)
- || (mFlushingVideo != NONE && mFlushingVideo != SHUT_DOWN)) {
- // We're currently flushing, postpone the reset until that's
- // completed.
-
- DP_MSG_ERROR("postponing action mFlushingAudio=%d, mFlushingVideo=%d",
- mFlushingAudio, mFlushingVideo);
-
- break;
- }
-
- sp<Action> action = *mDeferredActions.begin();
- mDeferredActions.erase(mDeferredActions.begin());
-
- action->execute(this);
- }
-}
-
-void DashPlayer::performSetSurface(const sp<Surface> &wrapper) {
- DP_MSG_HIGH("performSetSurface");
-
- mNativeWindow = wrapper;
-
- // XXX - ignore error from setVideoScalingMode for now
- //setVideoScalingMode(mVideoScalingMode);
-
- if (mDriver != NULL) {
- sp<DashPlayerDriver> driver = mDriver.promote();
- if (driver != NULL) {
- driver->notifySetSurfaceComplete();
- }
- }
-
- isSetSurfaceTexturePending = false;
-}
-
-void DashPlayer::performScanSources() {
- DP_MSG_ERROR("performScanSources");
-
- //if (!mStarted) {
- // return;
- //}
-
- if (mAudioDecoder == NULL || mVideoDecoder == NULL) {
- postScanSources();
- }
-}
-
-void DashPlayer::performDecoderShutdown(bool audio, bool video) {
- DP_MSG_ERROR("performDecoderShutdown audio=%d, video=%d", audio, video);
-
- if ((!audio || mAudioDecoder == NULL)
- && (!video || mVideoDecoder == NULL)) {
- return;
- }
-
- //mTimeDiscontinuityPending = true;
-
- if (mFlushingAudio == NONE && (!audio || mAudioDecoder == NULL)) {
- mFlushingAudio = FLUSHED;
- }
-
- if (mFlushingVideo == NONE && (!video || mVideoDecoder == NULL)) {
- mFlushingVideo = FLUSHED;
- }
-
- if (audio && mAudioDecoder != NULL) {
- flushDecoder(true /* audio */, true /* needShutdown */);
- }
-
- if (video && mVideoDecoder != NULL) {
- flushDecoder(false /* audio */, true /* needShutdown */);
- }
-}
-
-
-/** @brief: Pushes blank frame to native window
- *
- * @return: NO_ERROR if frame pushed successfully to native window
- *
- */
-status_t DashPlayer::PushBlankBuffersToNativeWindow(sp<ANativeWindow> nativeWindow) {
- status_t err = NO_ERROR;
- ANativeWindowBuffer* anb = NULL;
- int numBufs = 0;
- int minUndequeuedBufs = 0;
-
- // We need to reconnect to the ANativeWindow as a CPU client to ensure that
- // no frames get dropped by SurfaceFlinger assuming that these are video
- // frames.
- err = native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_set_buffers_dimensions(nativeWindow.get(),
- 1, 1);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffers_dimensions failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = native_window_set_buffers_format(nativeWindow.get(),
- HAL_PIXEL_FORMAT_RGBX_8888);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffers_format failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = native_window_set_scaling_mode(nativeWindow.get(),
- NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank_frames: set_scaling_mode failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = native_window_set_usage(nativeWindow.get(),
- GRALLOC_USAGE_SW_WRITE_OFTEN);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_usage failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = nativeWindow->query(nativeWindow.get(),
- NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: MIN_UNDEQUEUED_BUFFERS query "
- "failed: %s (%d)", strerror(-err), -err);
- goto error;
- }
-
- numBufs = minUndequeuedBufs + 1;
- err = native_window_set_buffer_count(nativeWindow.get(), numBufs);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: set_buffer_count failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- // We push numBufs + 1 buffers to ensure that we've drawn into the same
- // buffer twice. This should guarantee that the buffer has been displayed
- // on the screen and then been replaced, so an previous video frames are
- // guaranteed NOT to be currently displayed.
- for (int i = 0; i < numBufs + 1; i++) {
- int fenceFd = -1;
- err = native_window_dequeue_buffer_and_wait(nativeWindow.get(), &anb);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
-
- // Fill the buffer with the a 1x1 checkerboard pattern ;)
- uint32_t* img = NULL;
- err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: lock failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- *img = 0;
-
- err = buf->unlock();
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: unlock failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- err = nativeWindow->queueBuffer(nativeWindow.get(),
- buf->getNativeBuffer(), -1);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
-
- anb = NULL;
- }
-
-error:
-
- if (err != NO_ERROR) {
- // Clean up after an error.
- if (anb != NULL) {
- nativeWindow->cancelBuffer(nativeWindow.get(), anb, -1);
- }
-
- native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
-
- return err;
- } else {
- // Clean up after success.
- err = native_window_api_disconnect(nativeWindow.get(),
- NATIVE_WINDOW_API_CPU);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_disconnect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- err = native_window_api_connect(nativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: api_connect failed: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- return NO_ERROR;
- }
-}
-
-} // namespace android
diff --git a/dashplayer/DashPlayer.h b/dashplayer/DashPlayer.h
deleted file mode 100644
index 28ee1fdd..00000000
--- a/dashplayer/DashPlayer.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASH_PLAYER_H_
-
-#define DASH_PLAYER_H_
-
-#include "DashPlayerStats.h"
-#include <media/MediaPlayerInterface.h>
-#include <media/stagefright/foundation/AHandler.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <gui/Surface.h>
-
-
-#define KEY_QCTIMEDTEXT_LISTENER 6000
-
-//Keys for playback modes
-#define KEY_DASH_SEEK_EVENT 7001
-#define KEY_DASH_PAUSE_EVENT 7002
-#define KEY_DASH_RESUME_EVENT 7003
-
-#define KEY_DASH_ADAPTION_PROPERTIES 8002
-#define KEY_DASH_MPD_QUERY 8003
-#define KEY_DASH_QOE_EVENT 8004
-#define KEY_DASH_QOE_PERIODIC_EVENT 8008
-//Keys to get and set mpd properties xml string
-#define KEY_DASH_GET_ADAPTION_PROPERTIES 8010
-#define KEY_DASH_SET_ADAPTION_PROPERTIES 8011
-
-//Key to query reposition range
-#define KEY_DASH_REPOSITION_RANGE 9000
-
-namespace android {
-
-struct MetaData;
-struct DashPlayerDriver;
-
-enum {
- kWhatQOE,
- kWhatQOEPlay,
- kWhatQOEStop,
- kWhatQOESwitch,
- kWhatQOEPeriodic,
- };
-
-struct DashPlayer : public AHandler {
- DashPlayer();
-
- void setUID(uid_t uid);
-
- void setDriver(const wp<DashPlayerDriver> &driver);
-
- void setDataSource(const sp<IStreamSource> &source);
-
- status_t setDataSource(
- const char *url, const KeyedVector<String8, String8> *headers);
-
- void setDataSource(int fd, int64_t offset, int64_t length);
-
- void setVideoSurfaceTexture(const sp<IGraphicBufferProducer> &bufferProducer);
-
- void setAudioSink(const sp<MediaPlayerBase::AudioSink> &sink);
- void start();
-
- void pause();
- void resume();
-
- // Will notify the driver through "notifyResetComplete" once finished.
- void resetAsync();
-
- // Will notify the driver through "notifySeekComplete" once finished.
- void seekToAsync(int64_t seekTimeUs);
-
- status_t prepareAsync();
- status_t getParameter(int key, Parcel *reply);
- status_t setParameter(int key, const Parcel &request);
- status_t dump(int fd, const Vector<String16> &args);
-
- void setQCTimedTextListener(const bool val);
-
-public:
- struct DASHHTTPLiveSource;
-
-protected:
- virtual ~DashPlayer();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- struct Decoder;
- struct Renderer;
- struct Source;
- struct Action;
- struct SimpleAction;
- struct SetSurfaceAction;
- struct ShutdownDecoderAction;
-
- enum {
- // These keys must be in sync with the keys in QCTimedText.java
- KEY_DISPLAY_FLAGS = 1, // int
- KEY_STYLE_FLAGS = 2, // int
- KEY_BACKGROUND_COLOR_RGBA = 3, // int
- KEY_HIGHLIGHT_COLOR_RGBA = 4, // int
- KEY_SCROLL_DELAY = 5, // int
- KEY_WRAP_TEXT = 6, // int
- KEY_START_TIME = 7, // int
- KEY_STRUCT_BLINKING_TEXT_LIST = 8, // List<CharPos>
- KEY_STRUCT_FONT_LIST = 9, // List<Font>
- KEY_STRUCT_HIGHLIGHT_LIST = 10,// List<CharPos>
- KEY_STRUCT_HYPER_TEXT_LIST = 11,// List<HyperText>
- KEY_STRUCT_KARAOKE_LIST = 12,// List<Karaoke>
- KEY_STRUCT_STYLE_LIST = 13,// List<Style>
- KEY_STRUCT_TEXT_POS = 14,// TextPos
- KEY_STRUCT_JUSTIFICATION = 15,// Justification
- KEY_STRUCT_TEXT = 16,// Text
- KEY_HEIGHT = 17,
- KEY_WIDTH = 18,
- KEY_DURATION = 19,
- KEY_START_OFFSET = 20,
- KEY_SUB_ATOM = 21,
- KEY_TEXT_FORMAT = 22,
- KEY_GLOBAL_SETTING = 101,
- KEY_LOCAL_SETTING = 102,
- KEY_START_CHAR = 103,
- KEY_END_CHAR = 104,
- KEY_FONT_ID = 105,
- KEY_FONT_SIZE = 106,
- KEY_TEXT_COLOR_RGBA = 107,
- KEY_TEXT_EOS = 108,
- KEY_TEXT_FLAG_TYPE = 109,
- KEY_TEXT_DISCONTINUITY = 110,
- };
-
- enum {
- kWhatSetDataSource = '=DaS',
- kWhatSetVideoNativeWindow = '=NaW',
- kWhatSetAudioSink = '=AuS',
- kWhatStart = 'strt',
- kWhatScanSources = 'scan',
- kWhatVideoNotify = 'vidN',
- kWhatAudioNotify = 'audN',
- kWhatTextNotify = 'texN',
- kWhatRendererNotify = 'renN',
- kWhatReset = 'rset',
- kWhatSeek = 'seek',
- kWhatPause = 'paus',
- kWhatResume = 'rsme',
- kWhatPrepareAsync = 'pras',
- kWhatIsPrepareDone = 'prdn',
- kWhatSourceNotify = 'snfy',
- };
-
- enum {
- kWhatBufferingStart = 'bfst',
- kWhatBufferingEnd = 'bfen',
- };
-
- wp<DashPlayerDriver> mDriver;
- bool mUIDValid;
- uid_t mUID;
- sp<Source> mSource;
- sp<Surface> mNativeWindow;
- sp<MediaPlayerBase::AudioSink> mAudioSink;
- sp<Decoder> mVideoDecoder;
- bool mVideoIsAVC;
- sp<Decoder> mAudioDecoder;
- sp<Decoder> mTextDecoder;
- sp<Renderer> mRenderer;
-
- List<sp<Action> > mDeferredActions;
-
- bool mAudioEOS;
- bool mVideoEOS;
-
- bool mScanSourcesPending;
- bool isSetSurfaceTexturePending;
- int32_t mScanSourcesGeneration;
- bool mBufferingNotification;
-
- enum TrackName {
- kVideo = 0,
- kAudio,
- kText,
- kTrackAll,
- };
-
- enum FlushStatus {
- NONE,
- AWAITING_DISCONTINUITY,
- FLUSHING_DECODER,
- FLUSHING_DECODER_SHUTDOWN,
- SHUTTING_DOWN_DECODER,
- FLUSHED,
- SHUT_DOWN,
- };
-
- //Should be in sync with QCTimedText.java
- enum FrameFlags {
- TIMED_TEXT_FLAG_FRAME = 0x00,
- TIMED_TEXT_FLAG_CODEC_CONFIG,
- TIMED_TEXT_FLAG_EOS,
- TIMED_TEXT_FLAG_END = TIMED_TEXT_FLAG_EOS,
- };
-
- //Currently we only support SMPTE and CEA. Today sendTextPacket() has default parameter as SMPTE
- enum TimedTextType {
- TIMED_TEXT_SMPTE,
- TIMED_TEXT_CEA,
- TIMED_TEXT_UNKNOWN,
- };
-
- // Once the current flush is complete this indicates whether the
- // notion of time has changed.
- bool mTimeDiscontinuityPending;
-
- FlushStatus mFlushingAudio;
- FlushStatus mFlushingVideo;
- bool mResetInProgress;
- bool mResetPostponed;
- bool mSetVideoSize;
-
- int64_t mSkipRenderingAudioUntilMediaTimeUs;
- int64_t mSkipRenderingVideoUntilMediaTimeUs;
-
- int64_t mVideoLateByUs;
-
- bool mPauseIndication;
-
- Mutex mLock;
-
- char *mTrackName;
- sp<AMessage> mTextNotify;
- sp<AMessage> mSourceNotify;
- sp<AMessage> mQOENotify;
-
- int32_t mSRid;
-
- status_t instantiateDecoder(int track, sp<Decoder> *decoder);
-
- status_t feedDecoderInputData(int track, const sp<AMessage> &msg);
- void renderBuffer(bool audio, const sp<AMessage> &msg);
-
- void notifyListener(int msg, int ext1, int ext2, const Parcel *obj=NULL);
-
- void finishFlushIfPossible();
-
- void flushDecoder(bool audio, bool needShutdown);
-
- static bool IsFlushingState(FlushStatus state, bool *needShutdown = NULL);
-
- void finishReset();
- void postScanSources();
-
- sp<Source> LoadCreateSource(const char * uri, const KeyedVector<String8,
- String8> *headers, bool uidValid, uid_t uid);
-
- void postIsPrepareDone();
-
- // for qualcomm statistics profiling
- sp<DashPlayerStats> mStats;
-
- void sendTextPacket(sp<ABuffer> accessUnit, status_t err, DashPlayer::TimedTextType eTimedTextType = TIMED_TEXT_SMPTE);
- void getTrackName(int track, char* name);
- void prepareSource();
-
- void processDeferredActions();
-
- void performDecoderShutdown(bool audio, bool video);
- void performScanSources();
- void performSetSurface(const sp<Surface> &wrapper);
- void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
- status_t PushBlankBuffersToNativeWindow(sp<ANativeWindow> nativeWindow);
-
- int mLogLevel;
- bool mTimedTextCEAPresent;
-
- //Set and reset in cases of seek/resume-out-of-tsb to signal discontinuity in CEA timedtextsamples
- bool mTimedTextCEASamplesDisc;
-
- //Tells if app registered for a QCTimedText Listener. If not registered do not send text samples above.
- bool mQCTimedTextListenerPresent;
-
- int32_t mCurrentWidth;
- int32_t mCurrentHeight;
- int32_t mColorFormat;
-
- DISALLOW_EVIL_CONSTRUCTORS(DashPlayer);
-};
-
-} // namespace android
-
-#endif // DASH_PLAYER_H_
diff --git a/dashplayer/DashPlayerDecoder.cpp b/dashplayer/DashPlayerDecoder.cpp
deleted file mode 100644
index ec66c1db..00000000
--- a/dashplayer/DashPlayerDecoder.cpp
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DashPlayerDecoder"
-
-#include "DashPlayerDecoder.h"
-#include <media/ICrypto.h>
-#include "ESDS.h"
-#include "QCMediaDefs.h"
-#include "QCMetaData.h"
-#include <media/stagefright/MediaCodec.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <media/stagefright/Utils.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
-
-//Smooth streaming settings,
-//Max resolution 1080p
-#define MAX_WIDTH 1920
-#define MAX_HEIGHT 1080
-
-#define DPD_MSG_ERROR(...) ALOGE(__VA_ARGS__)
-#define DPD_MSG_HIGH(...) if(mLogLevel >= 1){ALOGE(__VA_ARGS__);}
-#define DPD_MSG_MEDIUM(...) if(mLogLevel >= 2){ALOGE(__VA_ARGS__);}
-#define DPD_MSG_LOW(...) if(mLogLevel >= 3){ALOGE(__VA_ARGS__);}
-
-namespace android {
-
-DashPlayer::Decoder::Decoder(
- const sp<AMessage> &notify,
- const sp<Surface> &nativeWindow)
- : mNotify(notify),
- mNativeWindow(nativeWindow),
- mLogLevel(0),
- mBufferGeneration(0),
- mComponentName("decoder") {
- // Every decoder has its own looper because MediaCodec operations
- // are blocking, but DashPlayer needs asynchronous operations.
- mDecoderLooper = new ALooper;
- mDecoderLooper->setName("DashPlayerDecoder");
- mDecoderLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
-
- mCodecLooper = new ALooper;
- mCodecLooper->setName("DashPlayerDecoder-MC");
- mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
-
- char property_value[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.debug.level", property_value, NULL);
-
- if(*property_value) {
- mLogLevel = atoi(property_value);
- }
-}
-
-DashPlayer::Decoder::~Decoder() {
-}
-
-/** @brief: configure mediacodec
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
- CHECK(mCodec == NULL);
-
- ++mBufferGeneration;
-
- AString mime;
- CHECK(format->findString("mime", &mime));
-
- /*
- sp<Surface> surface = NULL;
- if (mNativeWindow != NULL) {
- surface = mNativeWindow->getSurfaceTextureClient();
- }
- */
-
- mComponentName = mime;
- mComponentName.append(" decoder");
- DPD_MSG_HIGH("[%s] onConfigure (surface=%p)", mComponentName.c_str(), mNativeWindow.get());
-
- mCodec = MediaCodec::CreateByType(mCodecLooper, mime.c_str(), false /* encoder */);
- if (mCodec == NULL) {
- DPD_MSG_ERROR("Failed to create %s decoder", mime.c_str());
- handleError(UNKNOWN_ERROR);
- return;
- }
-
- mCodec->getName(&mComponentName);
-
- status_t err;
- if (mNativeWindow != NULL) {
- // disconnect from surface as MediaCodec will reconnect
- err = native_window_api_disconnect(
- mNativeWindow.get(), NATIVE_WINDOW_API_MEDIA);
- // We treat this as a warning, as this is a preparatory step.
- // Codec will try to connect to the surface, which is where
- // any error signaling will occur.
- ALOGW_IF(err != OK, "failed to disconnect from surface: %d", err);
- }
- err = mCodec->configure(
- format, mNativeWindow, NULL /* crypto */, 0 /* flags */);
- if (err != OK) {
- DPD_MSG_ERROR("Failed to configure %s decoder (err=%d)", mComponentName.c_str(), err);
- handleError(err);
- return;
- }
- // the following should work in configured state
- CHECK_EQ((status_t)OK, mCodec->getOutputFormat(&mOutputFormat));
- CHECK_EQ((status_t)OK, mCodec->getInputFormat(&mInputFormat));
-
- err = mCodec->start();
- if (err != OK) {
- DPD_MSG_ERROR("Failed to start %s decoder (err=%d)", mComponentName.c_str(), err);
- handleError(err);
- return;
- }
-
- // the following should work after start
- CHECK_EQ((status_t)OK, mCodec->getInputBuffers(&mInputBuffers));
- CHECK_EQ((status_t)OK, mCodec->getOutputBuffers(&mOutputBuffers));
- DPD_MSG_HIGH("[%s] got %zu input and %zu output buffers",
- mComponentName.c_str(),
- mInputBuffers.size(),
- mOutputBuffers.size());
-
- requestCodecNotification();
-}
-
-/** @brief: Register activity notification to mediacodec
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::requestCodecNotification() {
- if (mCodec != NULL) {
- sp<AMessage> reply = new AMessage(kWhatCodecNotify, this);
- reply->setInt32("generation", mBufferGeneration);
- mCodec->requestActivityNotification(reply);
- }
- }
-
-bool DashPlayer::Decoder::isStaleReply(const sp<AMessage> &msg) {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- return generation != mBufferGeneration;
- }
-
-void DashPlayer::Decoder::init() {
- mDecoderLooper->registerHandler(this);
-}
-
-/** @brief: configure decoder
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::configure(const sp<MetaData> &meta) {
- sp<AMessage> msg = new AMessage(kWhatConfigure, this);
- sp<AMessage> format = makeFormat(meta);
- msg->setMessage("format", format);
- msg->post();
-}
-
-/** @brief: notify decoder error to dashplayer
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::handleError(int32_t err)
-{
- DPD_MSG_HIGH("[%s] handleError : %d", mComponentName.c_str() , err);
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatError);
- notify->setInt32("err", err);
- notify->post();
-}
-
-/** @brief: send input buffer from codec to dashplayer
- *
- * @return: true if valid buffer found
- *
- */
-bool DashPlayer::Decoder::handleAnInputBuffer() {
- size_t bufferIx = -1;
- status_t res = mCodec->dequeueInputBuffer(&bufferIx);
- DPD_MSG_HIGH("[%s] dequeued input: %d",
- mComponentName.c_str(), res == OK ? (int)bufferIx : res);
- if (res != OK) {
- if (res != -EAGAIN) {
- handleError(res);
- }
- return false;
- }
-
- CHECK_LT(bufferIx, mInputBuffers.size());
-
- sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, this);
- reply->setSize("buffer-ix", bufferIx);
- reply->setInt32("generation", mBufferGeneration);
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatFillThisBuffer);
- notify->setBuffer("buffer", mInputBuffers[bufferIx]);
- notify->setMessage("reply", reply);
- notify->post();
- return true;
-}
-
-/** @brief: Send input buffer to decoder
- *
- * @return: void
- *
- */
-void android::DashPlayer::Decoder::onInputBufferFilled(const sp<AMessage> &msg) {
- size_t bufferIx;
- CHECK(msg->findSize("buffer-ix", &bufferIx));
- CHECK_LT(bufferIx, mInputBuffers.size());
- sp<ABuffer> codecBuffer = mInputBuffers[bufferIx];
-
- sp<ABuffer> buffer;
- bool hasBuffer = msg->findBuffer("buffer", &buffer);
- if (buffer == NULL /* includes !hasBuffer */) {
- int32_t streamErr = ERROR_END_OF_STREAM;
- CHECK(msg->findInt32("err", &streamErr) || !hasBuffer);
-
- if (streamErr == OK) {
- /* buffers are returned to hold on to */
- return;
- }
-
- // attempt to queue EOS
- status_t err = mCodec->queueInputBuffer(
- bufferIx,
- 0,
- 0,
- 0,
- MediaCodec::BUFFER_FLAG_EOS);
- if (streamErr == ERROR_END_OF_STREAM && err != OK) {
- streamErr = err;
- // err will not be ERROR_END_OF_STREAM
- }
-
- if (streamErr != ERROR_END_OF_STREAM) {
- handleError(streamErr);
- }
- } else {
- int64_t timeUs = 0;
- uint32_t flags = 0;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
-
- int32_t eos;
- // we do not expect CODECCONFIG or SYNCFRAME for decoder
- if (buffer->meta()->findInt32("eos", &eos) && eos) {
- flags |= MediaCodec::BUFFER_FLAG_EOS;
- }
-
- DPD_MSG_MEDIUM("Input buffer:[%s]: %p", mComponentName.c_str(), buffer->data());
-
- // copy into codec buffer
- if (buffer != codecBuffer) {
- CHECK_LE(buffer->size(), codecBuffer->capacity());
- codecBuffer->setRange(0, buffer->size());
- memcpy(codecBuffer->data(), buffer->data(), buffer->size());
- }
-
- status_t err = mCodec->queueInputBuffer(
- bufferIx,
- codecBuffer->offset(),
- codecBuffer->size(),
- timeUs,
- flags);
- if (err != OK) {
- DPD_MSG_ERROR("Failed to queue input buffer for %s (err=%d)",
- mComponentName.c_str(), err);
- handleError(err);
- }
- }
-}
-
-/** @brief: dequeue out buffer from mediacodec and send it to renderer
- *
- * @return: void
- *
- */
-bool DashPlayer::Decoder::handleAnOutputBuffer() {
- size_t bufferIx = -1;
- size_t offset;
- size_t size;
- int64_t timeUs;
- uint32_t flags;
- status_t res = mCodec->dequeueOutputBuffer(
- &bufferIx, &offset, &size, &timeUs, &flags);
-
- if (res != OK) {
- DPD_MSG_HIGH("[%s] dequeued output: %d", mComponentName.c_str(), res);
- } else {
- DPD_MSG_HIGH("[%s] dequeued output: %d (time=%lld flags=%u)",
- mComponentName.c_str(), (int)bufferIx, timeUs, flags);
- }
-
- if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
- res = mCodec->getOutputBuffers(&mOutputBuffers);
- if (res != OK) {
- DPD_MSG_ERROR("Failed to get output buffers for %s after INFO event (err=%d)",
- mComponentName.c_str(), res);
- handleError(res);
- return false;
- }
- // DashPlayer ignores this
- return true;
- } else if (res == INFO_FORMAT_CHANGED) {
- sp<AMessage> format = new AMessage();
- res = mCodec->getOutputFormat(&format);
- if (res != OK) {
- DPD_MSG_ERROR("Failed to get output format for %s after INFO event (err=%d)",
- mComponentName.c_str(), res);
- handleError(res);
- return false;
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatOutputFormatChanged);
- notify->setMessage("format", format);
- notify->post();
- return true;
- } else if (res == INFO_DISCONTINUITY) {
- // nothing to do
- return true;
- } else if (res != OK) {
- if (res != -EAGAIN) {
- handleError(res);
- }
- return false;
- }
-
- // FIXME: This should be handled after rendering is complete,
- // but Renderer needs it now
- if (flags & MediaCodec::BUFFER_FLAG_EOS) {
- DPD_MSG_ERROR("queueing eos [%s]", mComponentName.c_str());
-
- status_t err;
- err = mCodec->releaseOutputBuffer(bufferIx);
- if (err != OK) {
- DPD_MSG_ERROR("failed to release output buffer for %s (err=%d)",
- mComponentName.c_str(), err);
- handleError(err);
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatEOS);
- notify->setInt32("err", ERROR_END_OF_STREAM);
- notify->post();
- return true;
- }
-
- CHECK_LT(bufferIx, mOutputBuffers.size());
- sp<ABuffer> buffer = mOutputBuffers[bufferIx];
- buffer->setRange(offset, size);
-
- sp<RefBase> obj;
- sp<GraphicBuffer> graphicBuffer;
- if (buffer->meta()->findObject("graphic-buffer", &obj)) {
- graphicBuffer = static_cast<GraphicBuffer*>(obj.get());
- }
-
- buffer->meta()->clear();
- buffer->meta()->setInt64("timeUs", timeUs);
- if (flags & MediaCodec::BUFFER_FLAG_EOS) {
- buffer->meta()->setInt32("eos", true);
- }
- // we do not expect CODECCONFIG or SYNCFRAME for decoder
-
- sp<AMessage> reply = new AMessage(kWhatRenderBuffer, this);
- reply->setSize("buffer-ix", bufferIx);
- reply->setInt32("generation", mBufferGeneration);
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatDrainThisBuffer);
-
- if(flags & MediaCodec::BUFFER_FLAG_EXTRADATA) {
- buffer->meta()->setInt32("extradata", 1);
- }
-
- buffer->meta()->setObject("graphic-buffer", graphicBuffer);
- notify->setBuffer("buffer", buffer);
- notify->setMessage("reply", reply);
- notify->post();
-
- return true;
-}
-
-/** @brief: Give buffer to mediacodec for rendering
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::onRenderBuffer(const sp<AMessage> &msg) {
- status_t err;
- int32_t render;
- size_t bufferIx;
- CHECK(msg->findSize("buffer-ix", &bufferIx));
- if (msg->findInt32("render", &render) && render) {
- err = mCodec->renderOutputBufferAndRelease(bufferIx);
- } else {
- err = mCodec->releaseOutputBuffer(bufferIx);
- }
- if (err != OK) {
- DPD_MSG_ERROR("failed to release output buffer for %s (err=%d)",
- mComponentName.c_str(), err);
- handleError(err);
- }
- }
-
-/** @brief: notify decoder flush complete to dashplayer
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::onFlush() {
- status_t err = OK;
- if (mCodec != NULL) {
- err = mCodec->flush();
- ++mBufferGeneration;
- }
-
- if (err != OK) {
- DPD_MSG_ERROR("failed to flush %s (err=%d)", mComponentName.c_str(), err);
- handleError(err);
- // finish with posting kWhatFlushCompleted.
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatFlushCompleted);
- notify->post();
-}
-
-/** @brief: notify decoder shutdown complete to dashplayer
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::onShutdown() {
- status_t err = OK;
- if (mCodec != NULL) {
- err = mCodec->release();
- mCodec = NULL;
- ++mBufferGeneration;
-
- if (mNativeWindow != NULL) {
- // reconnect to surface as MediaCodec disconnected from it
- status_t error =
- native_window_api_connect(
- mNativeWindow.get(),
- NATIVE_WINDOW_API_MEDIA);
- ALOGW_IF(error != NO_ERROR,
- "[%s] failed to connect to native window, error=%d",
- mComponentName.c_str(), error);
- }
- mComponentName = "decoder";
- }
-
- if (err != OK) {
- DPD_MSG_ERROR("failed to release %s (err=%d)", mComponentName.c_str(), err);
- handleError(err);
- // finish with posting kWhatShutdownCompleted.
- }
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatShutdownCompleted);
- notify->post();
-}
-
-/** @brief: message handler to handle dashplayer/mediacodec messages
- *
- * @return: void
- *
- */
-void DashPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
- DPD_MSG_HIGH("[%s] onMessage: %s", mComponentName.c_str(), msg->debugString().c_str());
-
- switch (msg->what()) {
- case kWhatConfigure:
- {
- sp<AMessage> format;
- CHECK(msg->findMessage("format", &format));
- onConfigure(format);
- break;
- }
-
- case kWhatCodecNotify:
- {
- if (!isStaleReply(msg)) {
- while (handleAnInputBuffer()) {
- }
-
- while (handleAnOutputBuffer()) {
- }
- }
-
- requestCodecNotification();
- break;
- }
-
- case kWhatInputBufferFilled:
- {
- if (!isStaleReply(msg)) {
- onInputBufferFilled(msg);
- }
- break;
- }
-
- case kWhatRenderBuffer:
- {
- if (!isStaleReply(msg)) {
- onRenderBuffer(msg);
- }
- break;
- }
-
- case kWhatFlush:
- {
- onFlush();
- break;
- }
-
- case kWhatShutdown:
- {
- onShutdown();
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void DashPlayer::Decoder::signalFlush() {
- (new AMessage(kWhatFlush, this))->post();
-}
-
-void DashPlayer::Decoder::signalResume() {
- // nothing to do
-}
-
-void DashPlayer::Decoder::initiateShutdown() {
- (new AMessage(kWhatShutdown, this))->post();
-}
-
-
-/** @brief: convert input metadat into AMessage format
- *
- * @return: input format value in AMessage
- *
- */
-sp<AMessage> DashPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
- sp<AMessage> msg;
- CHECK_EQ(convertMetaDataToMessage(meta, &msg), (status_t)OK);
- const char *mime;
- CHECK(meta->findCString(kKeyMIMEType, &mime));
-
- if(!strncasecmp(mime, "video/", strlen("video/"))){
- msg->setInt32("max-height", MAX_HEIGHT);
- msg->setInt32("max-width", MAX_WIDTH);
- msg->setInt32("enable-extradata-user", 1);
-
- // Below property requie to set to prefer adaptive playback
- // msg->setInt32("prefer-adaptive-playback", 1);
- }
-
- return msg;
-}
-
-} // namespace android
-
diff --git a/dashplayer/DashPlayerDecoder.h b/dashplayer/DashPlayerDecoder.h
deleted file mode 100644
index 9e8167d3..00000000
--- a/dashplayer/DashPlayerDecoder.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASHPLAYER_DECODER_H_
-
-#define DASHPLAYER_DECODER_H_
-
-#include "DashPlayerRenderer.h"
-#include "DashPlayer.h"
-#include <media/stagefright/foundation/AHandler.h>
-
-namespace android {
-
-struct ABuffer;
-struct MediaCodec;
-
-struct DashPlayer::Decoder : public AHandler {
- Decoder(const sp<AMessage> &notify,
- const sp<Surface> &nativeWindow = NULL);
-
- void configure(const sp<MetaData> &meta);
- void init();
-
- void signalFlush();
- void signalResume();
- void initiateShutdown();
-
-
- enum {
- kWhatFillThisBuffer = 'flTB',
- kWhatDrainThisBuffer = 'drTB',
- kWhatOutputFormatChanged = 'fmtC',
- kWhatFlushCompleted = 'flsC',
- kWhatShutdownCompleted = 'shDC',
- kWhatEOS = 'eos ',
- kWhatError = 'err ',
- };
-
-protected:
- virtual ~Decoder();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatCodecNotify = 'cdcN',
- kWhatConfigure = 'conf',
- kWhatInputBufferFilled = 'inpF',
- kWhatRenderBuffer = 'rndr',
- kWhatFlush = 'flus',
- kWhatShutdown = 'shuD',
- };
-
- sp<AMessage> mNotify;
- sp<Surface> mNativeWindow;
-
- sp<AMessage> mInputFormat;
- sp<AMessage> mOutputFormat;
- sp<MediaCodec> mCodec;
- sp<ALooper> mCodecLooper;
- sp<ALooper> mDecoderLooper;
-
- Vector<sp<ABuffer> > mInputBuffers;
- Vector<sp<ABuffer> > mOutputBuffers;
-
- void handleError(int32_t err);
- bool handleAnInputBuffer();
- bool handleAnOutputBuffer();
-
- void requestCodecNotification();
- bool isStaleReply(const sp<AMessage> &msg);
-
- int mLogLevel;
-
- sp<AMessage> makeFormat(const sp<MetaData> &meta);
-
- void onConfigure(const sp<AMessage> &format);
- void onFlush();
- void onInputBufferFilled(const sp<AMessage> &msg);
- void onRenderBuffer(const sp<AMessage> &msg);
- void onShutdown();
-
- int32_t mBufferGeneration;
- AString mComponentName;
-
-
- DISALLOW_EVIL_CONSTRUCTORS(Decoder);
-};
-
-} // namespace android
-
-#endif // DASHPLAYER_DECODER_H_
diff --git a/dashplayer/DashPlayerDriver.cpp b/dashplayer/DashPlayerDriver.cpp
deleted file mode 100644
index 2d8eddfa..00000000
--- a/dashplayer/DashPlayerDriver.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DashPlayerDriver"
-
-#include "DashPlayerDriver.h"
-#include "DashPlayer.h"
-#include <media/stagefright/foundation/ALooper.h>
-#include <cutils/properties.h>
-#include <utils/Log.h>
-
-#define DPD_MSG_ERROR(...) ALOGE(__VA_ARGS__)
-#define DPD_MSG_HIGH(...) if(mLogLevel >= 1){ALOGE(__VA_ARGS__);}
-#define DPD_MSG_MEDIUM(...) if(mLogLevel >= 2){ALOGE(__VA_ARGS__);}
-#define DPD_MSG_LOW(...) if(mLogLevel >= 3){ALOGE(__VA_ARGS__);}
-
-namespace android {
-
-DashPlayerDriver::DashPlayerDriver()
- : mResetInProgress(false),
- mSetSurfaceInProgress(false),
- mDurationUs(-1),
- mPositionUs(-1),
- mLooper(new ALooper),
- mState(UNINITIALIZED),
- mAtEOS(false),
- mStartupSeekTimeUs(-1),
- mLogLevel(0){
- mLooper->setName("DashPlayerDriver Looper");
-
- mLooper->start(
- false, /* runOnCallingThread */
- true, /* canCallJava */
- PRIORITY_AUDIO);
-
- mPlayer = new DashPlayer;
- mLooper->registerHandler(mPlayer);
-
- mPlayer->setDriver(this);
-
- char property_value[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.debug.level", property_value, NULL);
-
- if(*property_value) {
- mLogLevel = atoi(property_value);
- }
-
-}
-
-DashPlayerDriver::~DashPlayerDriver() {
- mLooper->stop();
- mLooper->unregisterHandler(mPlayer->id());
-}
-
-status_t DashPlayerDriver::initCheck() {
- return OK;
-}
-
-status_t DashPlayerDriver::setUID(uid_t uid) {
- mPlayer->setUID(uid);
-
- return OK;
-}
-
-status_t DashPlayerDriver::setDataSource(const sp<IMediaHTTPService> &/*httpService*/,
- const char *url, const KeyedVector<String8, String8> *headers) {
- CHECK_EQ((int)mState, (int)UNINITIALIZED);
-
- status_t ret = mPlayer->setDataSource(url, headers);
-
- mState = STOPPED;
-
- return ret;
-}
-
-status_t DashPlayerDriver::setDataSource(int fd, int64_t offset, int64_t length) {
- CHECK_EQ((int)mState, (int)UNINITIALIZED);
-
- mPlayer->setDataSource(fd, offset, length);
-
- mState = STOPPED;
-
- return OK;
-}
-
-status_t DashPlayerDriver::setDataSource(const sp<IStreamSource> &source) {
- CHECK_EQ((int)mState, (int)UNINITIALIZED);
-
- mPlayer->setDataSource(source);
-
- mState = STOPPED;
-
- return OK;
-}
-
-status_t DashPlayerDriver::setVideoSurfaceTexture(
- const sp<IGraphicBufferProducer> &bufferProducer) {
- Mutex::Autolock autoLock(mLock);
-
- if (mResetInProgress) {
- return INVALID_OPERATION;
- }
-
- DPD_MSG_ERROR("DashPlayerDriver::setVideoSurfaceTexture call and block");
-
- mSetSurfaceInProgress = true;
-
- mPlayer->setVideoSurfaceTexture(bufferProducer);
-
- while (mSetSurfaceInProgress) {
- mCondition.wait(mLock);
- }
-
- return OK;
-}
-
-status_t DashPlayerDriver::prepare() {
- sendEvent(MEDIA_SET_VIDEO_SIZE, 0, 0);
- return OK;
-}
-
-status_t DashPlayerDriver::prepareAsync() {
- status_t err = (status_t)UNKNOWN_ERROR;
- if (mPlayer != NULL) {
- err = mPlayer->prepareAsync();
- }
-
- if (err == OK) {
- err = prepare();
- notifyListener(MEDIA_PREPARED);
- } else if (err == -EWOULDBLOCK) {
- // this case only happens for DASH
- return OK;
- }
- return err;
-}
-
-status_t DashPlayerDriver::start() {
- switch (mState) {
- case UNINITIALIZED:
- return INVALID_OPERATION;
- case STOPPED:
- {
- mAtEOS = false;
- mPlayer->start();
-
- if (mStartupSeekTimeUs >= 0) {
- if (mStartupSeekTimeUs == 0) {
- notifySeekComplete();
- } else {
- mPlayer->seekToAsync(mStartupSeekTimeUs);
- }
-
- mStartupSeekTimeUs = -1;
- }
-
- break;
- }
- case PLAYING:
- return OK;
- default:
- {
- CHECK_EQ((int)mState, (int)PAUSED);
- mPlayer->resume();
- break;
- }
- }
-
- mState = PLAYING;
-
- return OK;
-}
-
-status_t DashPlayerDriver::stop() {
- return pause();
-}
-
-status_t DashPlayerDriver::pause() {
- switch (mState) {
- case UNINITIALIZED:
- return INVALID_OPERATION;
- case STOPPED:
- return OK;
- case PLAYING:
- mPlayer->pause();
- break;
- default:
- {
- CHECK_EQ((int)mState, (int)PAUSED);
- return OK;
- }
- }
-
- mState = PAUSED;
-
- return OK;
-}
-
-bool DashPlayerDriver::isPlaying() {
- return mState == PLAYING && !mAtEOS;
-}
-
-status_t DashPlayerDriver::seekTo(int msec) {
- int64_t seekTimeUs = msec * 1000ll;
-
- switch (mState) {
- case UNINITIALIZED:
- return INVALID_OPERATION;
- case STOPPED:
- {
- mStartupSeekTimeUs = seekTimeUs;
- break;
- }
- case PLAYING:
- case PAUSED:
- {
- mAtEOS = false;
- mPlayer->seekToAsync(seekTimeUs);
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-
- return OK;
-}
-
-status_t DashPlayerDriver::getCurrentPosition(int *msec) {
- Mutex::Autolock autoLock(mLock);
-
- if (mPositionUs < 0) {
- *msec = 0;
- } else {
- *msec = (int)((mPositionUs + 500ll) / 1000);
- }
-
- return OK;
-}
-
-status_t DashPlayerDriver::getDuration(int *msec) {
- Mutex::Autolock autoLock(mLock);
-
- if (mDurationUs < 0) {
- *msec = 0;
- } else {
- *msec = (int)((mDurationUs + 500ll) / 1000);
- }
-
- return OK;
-}
-
-status_t DashPlayerDriver::reset() {
- Mutex::Autolock autoLock(mLock);
- mResetInProgress = true;
-
- mPlayer->resetAsync();
-
- while (mResetInProgress) {
- mCondition.wait(mLock);
- }
-
- mDurationUs = -1;
- mPositionUs = -1;
- mState = UNINITIALIZED;
- mStartupSeekTimeUs = -1;
-
- return OK;
-}
-
-status_t DashPlayerDriver::setLooping(int /*loop*/) {
- return INVALID_OPERATION;
-}
-
-player_type DashPlayerDriver::playerType() {
- return DASH_PLAYER;
-}
-
-void DashPlayerDriver::setQCTimedTextListener(const bool val) {
- mPlayer->setQCTimedTextListener(val);
-}
-
-status_t DashPlayerDriver::invoke(const Parcel &request, Parcel *reply) {
- status_t ret = INVALID_OPERATION;
-
- if (reply == NULL) {
- DPD_MSG_ERROR("reply is a NULL pointer");
- return BAD_VALUE;
- }
-
- int32_t methodId;
- ret = request.readInt32(&methodId);
- if (ret != OK) {
- DPD_MSG_ERROR("Failed to retrieve the requested method to invoke");
- return ret;
- }
-
- switch (methodId) {
- case KEY_DASH_GET_ADAPTION_PROPERTIES:
- {
- DPD_MSG_HIGH("calling KEY_DASH_GET_ADAPTION_PROPERTIES");
- ret = getParameter(methodId,reply);
- break;
- }
- case KEY_DASH_SET_ADAPTION_PROPERTIES:
- {
- DPD_MSG_HIGH("calling KEY_DASH_SET_ADAPTION_PROPERTIES");
- int32_t val = 0;
- ret = setParameter(methodId,request);
- val = (ret == OK)? 1:0;
- reply->setDataPosition(0);
- reply->writeInt32(val);
- break;
- }
- case KEY_DASH_MPD_QUERY:
- {
- DPD_MSG_HIGH("calling KEY_DASH_MPD_QUERY");
- ret = getParameter(methodId,reply);
- break;
- }
-
- case KEY_DASH_QOE_EVENT:
- DPD_MSG_HIGH("calling KEY_DASH_QOE_EVENT");
- ret = setParameter(methodId,request);
- break;
-
- case KEY_DASH_QOE_PERIODIC_EVENT:
- DPD_MSG_HIGH("calling KEY_DASH_QOE_PERIODIC_EVENT");
- ret = getParameter(methodId,reply);
- break;
-
- case KEY_DASH_REPOSITION_RANGE:
- DPD_MSG_HIGH("calling KEY_DASH_REPOSITION_RANGE");
- ret = getParameter(methodId,reply);
- break;
-
- case KEY_DASH_SEEK_EVENT:
- {
- DPD_MSG_HIGH("calling KEY_DASH_SEEK_EVENT seekTo()");
- int32_t msec;
- ret = request.readInt32(&msec);
- if (ret != OK)
- {
- DPD_MSG_ERROR("Invoke: invalid seek value");
- }
- else
- {
- ret = seekTo(msec);
- int32_t val = (ret == OK)? 1:0;
- reply->setDataPosition(0);
- reply->writeInt32(val);
- }
- break;
- }
-
- case KEY_DASH_PAUSE_EVENT:
- {
- DPD_MSG_HIGH("calling KEY_DASH_PAUSE_EVENT pause()");
- ret = pause();
- int32_t val = (ret == OK)? 1:0;
- reply->setDataPosition(0);
- reply->writeInt32(val);
- break;
- }
-
- case KEY_DASH_RESUME_EVENT:
- {
- DPD_MSG_HIGH("calling KEY_DASH_RESUME_EVENT pause()");
- ret = start();
- int32_t val = (ret == OK)? 1:0;
- reply->setDataPosition(0);
- reply->writeInt32(val);
- break;
- }
-
- case KEY_QCTIMEDTEXT_LISTENER:
- {
- DPD_MSG_HIGH("calling KEY_QCTIMEDTEXT_LISTENER");
-
- int32_t val = 0;
- ret = request.readInt32(&val);
- if (ret != OK)
- {
- DPD_MSG_ERROR("Invoke KEY_QCTIMEDTEXT_LISTENER: invalid val");
- }
- else
- {
- bool bVal = (val == 1)? true:false;
- setQCTimedTextListener(bVal);
- reply->setDataPosition(0);
- reply->writeInt32(1);
- }
- break;
- }
-
- case INVOKE_ID_GET_TRACK_INFO:
- {
- // Ignore the invoke call for INVOKE_ID_GET_TRACK_INFO with success return code
- // to avoid mediaplayer java exception
- DPD_MSG_HIGH("Calling INVOKE_ID_GET_TRACK_INFO to invoke");
- ret = getParameter(methodId,reply);
- break;
- }
-
- default:
- {
- DPD_MSG_ERROR("Invoke:unHandled requested method%d",methodId);
- ret = INVALID_OPERATION;
- break;
- }
- }
-
- return ret;
-}
-
-void DashPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
- mPlayer->setAudioSink(audioSink);
-}
-
-status_t DashPlayerDriver::setParameter(int key, const Parcel &request) {
- status_t err = (status_t)UNKNOWN_ERROR;
- if (mPlayer != NULL)
- {
- err = mPlayer->setParameter(key, request);
- }
- return err;
-}
-
-status_t DashPlayerDriver::getParameter(int key, Parcel *reply) {
-
- status_t err = (status_t)UNKNOWN_ERROR;
- if (mPlayer != NULL)
- {
- err = mPlayer->getParameter(key, reply);
- }
- return err;
-}
-
-status_t DashPlayerDriver::getMetadata(
- const media::Metadata::Filter& /*ids*/, Parcel * /*records*/) {
- return INVALID_OPERATION;
-}
-
-void DashPlayerDriver::notifyResetComplete() {
- Mutex::Autolock autoLock(mLock);
- CHECK(mResetInProgress);
- mResetInProgress = false;
- mCondition.broadcast();
-}
-
-void DashPlayerDriver::notifySetSurfaceComplete() {
- Mutex::Autolock autoLock(mLock);
- CHECK(mSetSurfaceInProgress);
- mSetSurfaceInProgress = false;
- DPD_MSG_ERROR("DashPlayerDriver::notifySetSurfaceComplete done");
- mCondition.broadcast();
-}
-
-void DashPlayerDriver::notifyDuration(int64_t durationUs) {
- Mutex::Autolock autoLock(mLock);
- mDurationUs = durationUs;
-}
-
-void DashPlayerDriver::notifyPosition(int64_t positionUs) {
- Mutex::Autolock autoLock(mLock);
- mPositionUs = positionUs;
-}
-
-void DashPlayerDriver::notifySeekComplete() {
- notifyListener(MEDIA_SEEK_COMPLETE);
-}
-
-status_t DashPlayerDriver::dump(int fd, const Vector<String16> &args) const {
- if(mPlayer != NULL) {
- mPlayer->dump(fd, args);
- }
- return OK;
-}
-
-void DashPlayerDriver::notifyListener(int msg, int ext1, int ext2, const Parcel *obj) {
- if (msg == MEDIA_PLAYBACK_COMPLETE || msg == MEDIA_ERROR) {
- mAtEOS = true;
- }
-
- sendEvent(msg, ext1, ext2, obj);
-}
-
-} // namespace android
diff --git a/dashplayer/DashPlayerDriver.h b/dashplayer/DashPlayerDriver.h
deleted file mode 100644
index 3949b682..00000000
--- a/dashplayer/DashPlayerDriver.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#include <media/MediaPlayerInterface.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-struct ALooper;
-struct DashPlayer;
-
-struct DashPlayerDriver : public MediaPlayerInterface {
- DashPlayerDriver();
-
- virtual status_t initCheck();
-
- virtual status_t setUID(uid_t uid);
-
- virtual status_t setDataSource(const sp<IMediaHTTPService> &httpService,
- const char *url, const KeyedVector<String8, String8> *headers);
-
- virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
-
- virtual status_t setDataSource(const sp<IStreamSource> &source);
-
- virtual status_t setVideoSurfaceTexture(
- const sp<IGraphicBufferProducer> &bufferProducer);
-
- virtual status_t prepare();
- virtual status_t prepareAsync();
- virtual status_t start();
- virtual status_t stop();
- virtual status_t pause();
- virtual bool isPlaying();
- virtual status_t seekTo(int msec);
- virtual status_t getCurrentPosition(int *msec);
- virtual status_t getDuration(int *msec);
- virtual status_t reset();
- virtual status_t setLooping(int loop);
- virtual player_type playerType();
- virtual status_t invoke(const Parcel &request, Parcel *reply);
- virtual void setAudioSink(const sp<AudioSink> &audioSink);
- virtual status_t setParameter(int key, const Parcel &request);
- virtual status_t getParameter(int key, Parcel *reply);
-
- virtual status_t getMetadata(
- const media::Metadata::Filter& ids, Parcel *records);
-
- virtual status_t dump(int fd, const Vector<String16> &args) const;
-
- void notifyResetComplete();
- void notifySetSurfaceComplete();
- void notifyDuration(int64_t durationUs);
- void notifyPosition(int64_t positionUs);
- void notifySeekComplete();
- void notifyListener(int msg, int ext1 = 0, int ext2 = 0, const Parcel *obj=NULL);
- void setQCTimedTextListener(const bool val);
-
-protected:
- virtual ~DashPlayerDriver();
-
-private:
- mutable Mutex mLock;
- Condition mCondition;
-
- // The following are protected through "mLock"
- // >>>
- bool mResetInProgress;
- bool mSetSurfaceInProgress;
- int64_t mDurationUs;
- int64_t mPositionUs;
- // <<<
-
- sp<ALooper> mLooper;
- sp<DashPlayer> mPlayer;
-
- enum State {
- UNINITIALIZED,
- STOPPED,
- PLAYING,
- PAUSED
- };
-
- State mState;
- bool mAtEOS;
-
- int64_t mStartupSeekTimeUs;
-
- int mLogLevel;
-
- DISALLOW_EVIL_CONSTRUCTORS(DashPlayerDriver);
-};
-
-} // namespace android
-
-
diff --git a/dashplayer/DashPlayerRenderer.cpp b/dashplayer/DashPlayerRenderer.cpp
deleted file mode 100644
index 6cd5e46b..00000000
--- a/dashplayer/DashPlayerRenderer.cpp
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "DashPlayerRenderer"
-
-#include "DashPlayerRenderer.h"
-#include <cutils/properties.h>
-#include <utils/Log.h>
-
-#define DPR_MSG_ERROR(...) ALOGE(__VA_ARGS__)
-#define DPR_MSG_HIGH(...) if(mLogLevel >= 1){ALOGE(__VA_ARGS__);}
-#define DPR_MSG_MEDIUM(...) if(mLogLevel >= 2){ALOGE(__VA_ARGS__);}
-#define DPR_MSG_LOW(...) if(mLogLevel >= 3){ALOGE(__VA_ARGS__);}
-
-namespace android {
-
-// static
-const int64_t DashPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
-
-DashPlayer::Renderer::Renderer(
- const sp<MediaPlayerBase::AudioSink> &sink,
- const sp<AMessage> &notify)
- : mAudioSink(sink),
- mNotify(notify),
- mNumFramesWritten(0),
- mDrainAudioQueuePending(false),
- mDrainVideoQueuePending(false),
- mAudioQueueGeneration(0),
- mVideoQueueGeneration(0),
- mAnchorTimeMediaUs(-1),
- mAnchorTimeRealUs(-1),
- mSeekTimeUs(0),
- mFlushingAudio(false),
- mFlushingVideo(false),
- mHasAudio(false),
- mHasVideo(false),
- mSyncQueues(false),
- mPaused(false),
- mWasPaused(false),
- mLastPositionUpdateUs(-1ll),
- mVideoLateByUs(0ll),
- mStats(NULL),
- mLogLevel(0) {
-
- mAVSyncDelayWindowUs = 40000;
-
- char avSyncDelayMsec[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.avsync.window.msec", avSyncDelayMsec, NULL);
-
- if(*avSyncDelayMsec) {
- int64_t avSyncDelayWindowUs = atoi(avSyncDelayMsec) * 1000;
-
- if(avSyncDelayWindowUs > 0) {
- mAVSyncDelayWindowUs = avSyncDelayWindowUs;
- }
- }
-
- DPR_MSG_LOW("AVsync window in Us %lld", mAVSyncDelayWindowUs);
-
- char property_value[PROPERTY_VALUE_MAX] = {0};
- property_get("persist.dash.debug.level", property_value, NULL);
-
- if(*property_value) {
- mLogLevel = atoi(property_value);
- }
-}
-
-DashPlayer::Renderer::~Renderer() {
- if(mStats != NULL) {
- mStats->logStatistics();
- mStats->logSyncLoss();
- mStats = NULL;
- }
-}
-
-void DashPlayer::Renderer::queueBuffer(
- bool audio,
- const sp<ABuffer> &buffer,
- const sp<AMessage> &notifyConsumed) {
- sp<AMessage> msg = new AMessage(kWhatQueueBuffer, this);
- msg->setInt32("audio", static_cast<int32_t>(audio));
- msg->setBuffer("buffer", buffer);
- msg->setMessage("notifyConsumed", notifyConsumed);
- msg->post();
-}
-
-void DashPlayer::Renderer::queueEOS(bool audio, status_t finalResult) {
- CHECK_NE(finalResult, (status_t)OK);
-
- if(mSyncQueues)
- syncQueuesDone();
-
- sp<AMessage> msg = new AMessage(kWhatQueueEOS, this);
- msg->setInt32("audio", static_cast<int32_t>(audio));
- msg->setInt32("finalResult", finalResult);
- msg->post();
-}
-
-void DashPlayer::Renderer::flush(bool audio) {
- {
- Mutex::Autolock autoLock(mFlushLock);
- if (audio) {
- CHECK(!mFlushingAudio);
- mFlushingAudio = true;
- } else {
- CHECK(!mFlushingVideo);
- mFlushingVideo = true;
- }
- }
-
- sp<AMessage> msg = new AMessage(kWhatFlush, this);
- msg->setInt32("audio", static_cast<int32_t>(audio));
- msg->post();
-}
-
-void DashPlayer::Renderer::signalTimeDiscontinuity() {
- CHECK(mAudioQueue.empty());
- CHECK(mVideoQueue.empty());
- mAnchorTimeMediaUs = -1;
- mAnchorTimeRealUs = -1;
- mWasPaused = false;
- mSeekTimeUs = 0;
- mSyncQueues = mHasAudio && mHasVideo;
- mIsFirstVideoframeReceived = false;
- mPendingPostAudioDrains = false;
- mHasAudio = false;
- mHasVideo = false;
- DPR_MSG_HIGH("signalTimeDiscontinuity mHasAudio %d mHasVideo %d mSyncQueues %d",mHasAudio,mHasVideo,mSyncQueues);
-}
-
-void DashPlayer::Renderer::pause() {
- (new AMessage(kWhatPause, this))->post();
-}
-
-void DashPlayer::Renderer::resume() {
- (new AMessage(kWhatResume, this))->post();
-}
-
-void DashPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
- switch (msg->what()) {
- case kWhatDrainAudioQueue:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mAudioQueueGeneration) {
- break;
- }
-
- mDrainAudioQueuePending = false;
-
- if (onDrainAudioQueue()) {
- uint32_t numFramesPlayed;
- CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed),
- (status_t)OK);
-
- uint32_t numFramesPendingPlayout =
- mNumFramesWritten - numFramesPlayed;
-
- // This is how long the audio sink will have data to
- // play back.
- int64_t delayUs =
- (int64_t)(mAudioSink->msecsPerFrame()
- * (float)(numFramesPendingPlayout * 1000ll));
-
- // Let's give it more data after about half that time
- // has elapsed.
- postDrainAudioQueue(delayUs / 2);
- }
- break;
- }
-
- case kWhatDrainVideoQueue:
- {
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mVideoQueueGeneration) {
- break;
- }
-
- mDrainVideoQueuePending = false;
-
- onDrainVideoQueue();
-
- postDrainVideoQueue();
- break;
- }
-
- case kWhatQueueBuffer:
- {
- onQueueBuffer(msg);
- break;
- }
-
- case kWhatQueueEOS:
- {
- onQueueEOS(msg);
- break;
- }
-
- case kWhatFlush:
- {
- onFlush(msg);
- break;
- }
-
- case kWhatAudioSinkChanged:
- {
- onAudioSinkChanged();
- break;
- }
-
- case kWhatPause:
- {
- onPause();
- break;
- }
-
- case kWhatResume:
- {
- onResume();
- break;
- }
-
- default:
- TRESPASS();
- break;
- }
-}
-
-void DashPlayer::Renderer::postDrainAudioQueue(int64_t delayUs) {
- if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
- return;
- }
-
- if (mAudioQueue.empty()) {
- return;
- }
-
- mDrainAudioQueuePending = true;
- sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
- msg->setInt32("generation", mAudioQueueGeneration);
- msg->post(delayUs);
-}
-
-void DashPlayer::Renderer::signalAudioSinkChanged() {
- (new AMessage(kWhatAudioSinkChanged,this))->post();
-}
-
-bool DashPlayer::Renderer::onDrainAudioQueue() {
- uint32_t numFramesPlayed;
-
- // Check if first frame is EOS, process EOS and return
- if(1 == mAudioQueue.size())
- {
- QueueEntry *entry = &*mAudioQueue.begin();
- if (entry->mBuffer == NULL) {
- ALOGE("onDrainAudioQueue process EOS");
- notifyEOS(true /* audio */, entry->mFinalResult);
-
- mAudioQueue.erase(mAudioQueue.begin());
- entry = NULL;
- return false;
- }
- }
-
- if (mAudioSink->getPosition(&numFramesPlayed) != OK) {
- return false;
- }
-
- ssize_t numFramesAvailableToWrite =
- mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
-
- size_t numBytesAvailableToWrite =
- numFramesAvailableToWrite * mAudioSink->frameSize();
-
- while (numBytesAvailableToWrite > 0 && !mAudioQueue.empty()) {
- QueueEntry *entry = &*mAudioQueue.begin();
-
- if (entry->mBuffer == NULL) {
- // EOS
-
- notifyEOS(true /* audio */, entry->mFinalResult);
-
- mAudioQueue.erase(mAudioQueue.begin());
- entry = NULL;
- return false;
- }
-
- if (entry->mOffset == 0) {
- int64_t mediaTimeUs;
- CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
- DPR_MSG_HIGH("rendering audio at media time %.2f secs", (double)mediaTimeUs / 1E6);
-
- mAnchorTimeMediaUs = mediaTimeUs;
-
- uint32_t numFramesPlayed;
- CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
-
- uint32_t numFramesPendingPlayout =
- mNumFramesWritten - numFramesPlayed;
-
- int64_t realTimeOffsetUs =
- (int64_t)(((float)mAudioSink->latency() / 2
- + (float)numFramesPendingPlayout
- * mAudioSink->msecsPerFrame()) * 1000ll);
-
- mAnchorTimeRealUs =
- ALooper::GetNowUs() + realTimeOffsetUs;
- }
-
- size_t copy = entry->mBuffer->size() - entry->mOffset;
- if (copy > numBytesAvailableToWrite) {
- copy = numBytesAvailableToWrite;
- }
-
- CHECK_EQ(mAudioSink->write(
- entry->mBuffer->data() + entry->mOffset, copy),
- (ssize_t)copy);
-
- entry->mOffset += copy;
- if (entry->mOffset == entry->mBuffer->size()) {
- entry->mNotifyConsumed->post();
- mAudioQueue.erase(mAudioQueue.begin());
-
- entry = NULL;
- }
-
- numBytesAvailableToWrite -= copy;
- size_t copiedFrames = copy / mAudioSink->frameSize();
- mNumFramesWritten += (uint32_t)copiedFrames;
- }
-
- notifyPosition();
-
- return !mAudioQueue.empty();
-}
-
-void DashPlayer::Renderer::postDrainVideoQueue() {
- if (mDrainVideoQueuePending || mSyncQueues || mPaused) {
- return;
- }
-
- if (mVideoQueue.empty()) {
- return;
- }
-
- QueueEntry &entry = *mVideoQueue.begin();
-
- sp<AMessage> msg = new AMessage(kWhatDrainVideoQueue, this);
- msg->setInt32("generation", mVideoQueueGeneration);
-
- int64_t delayUs;
-
- if (entry.mBuffer == NULL) {
- // EOS doesn't carry a timestamp.
- delayUs = 0;
- } else {
- int64_t mediaTimeUs;
- CHECK(entry.mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
- if (mAnchorTimeMediaUs < 0) {
- delayUs = 0;
-
- if (!mHasAudio) {
- mAnchorTimeMediaUs = mediaTimeUs;
- mAnchorTimeRealUs = ALooper::GetNowUs();
- }
- } else {
- if ( (!mHasAudio && mHasVideo) && (mWasPaused == true))
- {
- mAnchorTimeMediaUs = mediaTimeUs;
- mAnchorTimeRealUs = ALooper::GetNowUs();
- mWasPaused = false;
- }
-
- int64_t realTimeUs =
- (mediaTimeUs - mAnchorTimeMediaUs) + mAnchorTimeRealUs;
-
- delayUs = realTimeUs - ALooper::GetNowUs();
- }
- }
-
- msg->post(delayUs);
-
- mDrainVideoQueuePending = true;
-}
-
-void DashPlayer::Renderer::onDrainVideoQueue() {
- if (mVideoQueue.empty()) {
- return;
- }
-
- QueueEntry *entry = &*mVideoQueue.begin();
-
- if (entry->mBuffer == NULL) {
- // EOS
-
- notifyPosition(true);
-
- notifyEOS(false /* audio */, entry->mFinalResult);
-
- mVideoQueue.erase(mVideoQueue.begin());
- entry = NULL;
-
- mVideoLateByUs = 0ll;
-
- return;
- }
-
- int64_t mediaTimeUs;
- CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
-
- int64_t realTimeUs = mediaTimeUs - mAnchorTimeMediaUs + mAnchorTimeRealUs;
- int64_t nowUs = ALooper::GetNowUs();
- mVideoLateByUs = nowUs - realTimeUs;
-
- bool tooLate = (mVideoLateByUs > mAVSyncDelayWindowUs);
-
- if (tooLate) {
- DPR_MSG_HIGH("video late by %lld us (%.2f secs)",
- mVideoLateByUs, (double)mVideoLateByUs / 1E6);
- if(mStats != NULL) {
- mStats->recordLate(realTimeUs,nowUs,mVideoLateByUs,mAnchorTimeRealUs);
- }
- } else {
- DPR_MSG_HIGH("rendering video at media time %.2f secs", (double)mediaTimeUs / 1E6);
- if(mStats != NULL) {
- mStats->recordOnTime(realTimeUs,nowUs,mVideoLateByUs);
- mStats->incrementTotalRenderingFrames();
- mStats->logFps();
- }
- }
-
- entry->mNotifyConsumed->setInt32("render", !tooLate);
- entry->mNotifyConsumed->post();
- mVideoQueue.erase(mVideoQueue.begin());
- entry = NULL;
-
- notifyPosition();
-}
-
-void DashPlayer::Renderer::notifyEOS(bool audio, status_t finalResult) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatEOS);
- notify->setInt32("audio", static_cast<int32_t>(audio));
- notify->setInt32("finalResult", finalResult);
- notify->post();
-}
-
-void DashPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
- int32_t audio;
- CHECK(msg->findInt32("audio", &audio));
-
- if (audio) {
- mHasAudio = true;
- } else {
- mHasVideo = true;
- }
-
- if (dropBufferWhileFlushing(audio, msg)) {
- return;
- }
-
- sp<ABuffer> buffer;
- CHECK(msg->findBuffer("buffer", &buffer));
-
- sp<AMessage> notifyConsumed;
- CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
-
- QueueEntry entry;
- entry.mBuffer = buffer;
- entry.mNotifyConsumed = notifyConsumed;
- entry.mOffset = 0;
- entry.mFinalResult = OK;
-
- if (audio) {
- mAudioQueue.push_back(entry);
- int64_t audioTimeUs;
- (buffer->meta())->findInt64("timeUs", &audioTimeUs);
- if ((mHasVideo && mIsFirstVideoframeReceived)
- || !mHasVideo){
- postDrainAudioQueue();
- return;
- }
- else
- {
- mPendingPostAudioDrains = true;
- DPR_MSG_HIGH("Not rendering Audio Sample with TS: %lld as Video frame is not decoded", audioTimeUs);
- }
- } else {
- mVideoQueue.push_back(entry);
- int64_t videoTimeUs;
- (buffer->meta())->findInt64("timeUs", &videoTimeUs);
- if (!mIsFirstVideoframeReceived) {
- mIsFirstVideoframeReceived = true;
- DPR_MSG_HIGH("Received first video Sample with TS: %lld", videoTimeUs);
- if (mPendingPostAudioDrains) {
- mPendingPostAudioDrains = false;
- postDrainAudioQueue();
- }
- }
- postDrainVideoQueue();
- }
-
- if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {
- return;
- }
-
- sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer;
- sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer;
-
- if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) {
- // EOS signalled on either queue.
- syncQueuesDone();
- return;
- }
-
- int64_t firstAudioTimeUs;
- int64_t firstVideoTimeUs;
- CHECK(firstAudioBuffer->meta()
- ->findInt64("timeUs", &firstAudioTimeUs));
- CHECK(firstVideoBuffer->meta()
- ->findInt64("timeUs", &firstVideoTimeUs));
-
- int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
-
- DPR_MSG_LOW("queueDiff = %.2f secs", (double)diff / 1E6);
-
- if (diff > 100000ll) {
- // Audio data starts More than 0.1 secs before video.
- // Drop some audio.
-
- (*mAudioQueue.begin()).mNotifyConsumed->post();
- mAudioQueue.erase(mAudioQueue.begin());
- return;
- }
-
- syncQueuesDone();
-}
-
-void DashPlayer::Renderer::syncQueuesDone() {
- if (!mSyncQueues) {
- return;
- }
-
- mSyncQueues = false;
-
- if (!mAudioQueue.empty()) {
- postDrainAudioQueue();
- }
-
- if (!mVideoQueue.empty()) {
- postDrainVideoQueue();
- }
-}
-
-void DashPlayer::Renderer::onQueueEOS(const sp<AMessage> &msg) {
- int32_t audio;
- CHECK(msg->findInt32("audio", &audio));
-
- if (dropBufferWhileFlushing(audio, msg)) {
- return;
- }
-
- int32_t finalResult;
- CHECK(msg->findInt32("finalResult", &finalResult));
-
- QueueEntry entry;
- entry.mOffset = 0;
- entry.mFinalResult = finalResult;
-
- if (audio) {
- mAudioQueue.push_back(entry);
- postDrainAudioQueue();
- } else {
- mVideoQueue.push_back(entry);
- postDrainVideoQueue();
- }
-}
-
-void DashPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
- int32_t audio;
- CHECK(msg->findInt32("audio", &audio));
-
- // If we're currently syncing the queues, i.e. dropping audio while
- // aligning the first audio/video buffer times and only one of the
- // two queues has data, we may starve that queue by not requesting
- // more buffers from the decoder. If the other source then encounters
- // a discontinuity that leads to flushing, we'll never find the
- // corresponding discontinuity on the other queue.
- // Therefore we'll stop syncing the queues if at least one of them
- // is flushed.
- syncQueuesDone();
-
- if (audio) {
- flushQueue(&mAudioQueue);
-
- Mutex::Autolock autoLock(mFlushLock);
- mFlushingAudio = false;
-
- mDrainAudioQueuePending = false;
- ++mAudioQueueGeneration;
- } else {
- flushQueue(&mVideoQueue);
-
- Mutex::Autolock autoLock(mFlushLock);
- mFlushingVideo = false;
-
- mDrainVideoQueuePending = false;
- ++mVideoQueueGeneration;
- if(mStats != NULL) {
- mStats->setVeryFirstFrame(true);
- }
- }
-
- notifyFlushComplete(audio);
-}
-
-void DashPlayer::Renderer::flushQueue(List<QueueEntry> *queue) {
- while (!queue->empty()) {
- QueueEntry *entry = &*queue->begin();
-
- if (entry->mBuffer != NULL) {
- entry->mNotifyConsumed->post();
- }
-
- queue->erase(queue->begin());
- entry = NULL;
- }
-}
-
-void DashPlayer::Renderer::notifyFlushComplete(bool audio) {
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatFlushComplete);
- notify->setInt32("audio", static_cast<int32_t>(audio));
- notify->post();
-}
-
-bool DashPlayer::Renderer::dropBufferWhileFlushing(
- bool audio, const sp<AMessage> &msg) {
- bool flushing = false;
-
- {
- Mutex::Autolock autoLock(mFlushLock);
- if (audio) {
- flushing = mFlushingAudio;
- } else {
- flushing = mFlushingVideo;
- }
- }
-
- if (!flushing) {
- return false;
- }
-
- sp<AMessage> notifyConsumed;
- if (msg->findMessage("notifyConsumed", &notifyConsumed)) {
- notifyConsumed->post();
- }
-
- return true;
-}
-
-void DashPlayer::Renderer::onAudioSinkChanged() {
- CHECK(!mDrainAudioQueuePending);
- mNumFramesWritten = 0;
- uint32_t written;
- if (mAudioSink->getFramesWritten(&written) == OK) {
- mNumFramesWritten = written;
- }
-}
-
-void DashPlayer::Renderer::notifyPosition(bool isEOS) {
- if (mAnchorTimeRealUs < 0 || mAnchorTimeMediaUs < 0) {
- return;
- }
-
- int64_t nowUs = ALooper::GetNowUs();
-
- if ((!isEOS) && (mLastPositionUpdateUs >= 0
- && nowUs < mLastPositionUpdateUs + kMinPositionUpdateDelayUs)) {
- return;
- }
- mLastPositionUpdateUs = nowUs;
-
- int64_t positionUs = (mSeekTimeUs != 0) ? mSeekTimeUs : ((nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs);
-
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatPosition);
- notify->setInt64("positionUs", positionUs);
- notify->setInt64("videoLateByUs", mVideoLateByUs);
- notify->post();
-}
-
-void DashPlayer::Renderer::notifySeekPosition(int64_t seekTime){
- mSeekTimeUs = seekTime;
- int64_t nowUs = ALooper::GetNowUs();
- mLastPositionUpdateUs = nowUs;
- sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", kWhatPosition);
- notify->setInt64("positionUs", seekTime);
- notify->setInt64("videoLateByUs", mVideoLateByUs);
- notify->post();
-
-}
-
-
-void DashPlayer::Renderer::onPause() {
- CHECK(!mPaused);
-
- mDrainAudioQueuePending = false;
- ++mAudioQueueGeneration;
-
- mDrainVideoQueuePending = false;
- ++mVideoQueueGeneration;
-
- if (mHasAudio) {
- mAudioSink->pause();
- }
-
- DPR_MSG_LOW("now paused audio queue has %d entries, video has %d entries",
- mAudioQueue.size(), mVideoQueue.size());
-
- mPaused = true;
- mWasPaused = true;
-
- if(mStats != NULL) {
- int64_t positionUs;
- if(mAnchorTimeRealUs < 0 || mAnchorTimeMediaUs < 0) {
- positionUs = -1000;
- } else {
- int64_t nowUs = ALooper::GetNowUs();
- positionUs = (nowUs - mAnchorTimeRealUs) + mAnchorTimeMediaUs;
- }
-
- mStats->logPause(positionUs);
- }
-}
-
-void DashPlayer::Renderer::onResume() {
- if (!mPaused) {
- return;
- }
-
- if (mHasAudio) {
- mAudioSink->start();
- }
-
- mPaused = false;
-
- if (!mAudioQueue.empty()) {
- postDrainAudioQueue();
- }
-
- if (!mVideoQueue.empty()) {
- postDrainVideoQueue();
- }
-}
-
-void DashPlayer::Renderer::registerStats(sp<DashPlayerStats> stats) {
- if(mStats != NULL) {
- mStats = NULL;
- }
- mStats = stats;
-}
-
-status_t DashPlayer::Renderer::setMediaPresence(bool audio, bool bValue)
-{
- if (audio)
- {
- DPR_MSG_LOW("mHasAudio set to %d from %d",bValue,mHasAudio);
- mHasAudio = bValue;
- }
- else
- {
- DPR_MSG_LOW("mHasVideo set to %d from %d",bValue,mHasVideo);
- mHasVideo = bValue;
- }
- return OK;
-}
-
-} // namespace android
-
diff --git a/dashplayer/DashPlayerRenderer.h b/dashplayer/DashPlayerRenderer.h
deleted file mode 100644
index 89404147..00000000
--- a/dashplayer/DashPlayerRenderer.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASHPLAYER_RENDERER_H_
-
-#define DASHPLAYER_RENDERER_H_
-
-#include "DashPlayer.h"
-
-namespace android {
-
-struct ABuffer;
-
-struct DashPlayer::Renderer : public AHandler {
- Renderer(const sp<MediaPlayerBase::AudioSink> &sink,
- const sp<AMessage> &notify);
-
- void queueBuffer(
- bool audio,
- const sp<ABuffer> &buffer,
- const sp<AMessage> &notifyConsumed);
-
- void queueEOS(bool audio, status_t finalResult);
-
- void flush(bool audio);
-
- void signalTimeDiscontinuity();
-
- void signalAudioSinkChanged();
-
- void pause();
- void resume();
- void notifySeekPosition(int64_t seekTime);
-
- enum {
- kWhatEOS = 'eos ',
- kWhatFlushComplete = 'fluC',
- kWhatPosition = 'posi',
- };
-
-protected:
- virtual ~Renderer();
-
- virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
- enum {
- kWhatDrainAudioQueue = 'draA',
- kWhatDrainVideoQueue = 'draV',
- kWhatQueueBuffer = 'queB',
- kWhatQueueEOS = 'qEOS',
- kWhatFlush = 'flus',
- kWhatAudioSinkChanged = 'auSC',
- kWhatPause = 'paus',
- kWhatResume = 'resm',
- };
-
- struct QueueEntry {
- sp<ABuffer> mBuffer;
- sp<AMessage> mNotifyConsumed;
- size_t mOffset;
- status_t mFinalResult;
- };
-
- static const int64_t kMinPositionUpdateDelayUs;
-
- sp<MediaPlayerBase::AudioSink> mAudioSink;
- sp<AMessage> mNotify;
- List<QueueEntry> mAudioQueue;
- List<QueueEntry> mVideoQueue;
- uint32_t mNumFramesWritten;
-
- bool mDrainAudioQueuePending;
- bool mDrainVideoQueuePending;
- int32_t mAudioQueueGeneration;
- int32_t mVideoQueueGeneration;
-
- int64_t mAnchorTimeMediaUs;
- int64_t mAnchorTimeRealUs;
- int64_t mSeekTimeUs;
-
- Mutex mFlushLock; // protects the following 2 member vars.
- bool mFlushingAudio;
- bool mFlushingVideo;
-
- bool mHasAudio;
- bool mHasVideo;
- bool mSyncQueues;
-
- bool mIsFirstVideoframeReceived;
- bool mPendingPostAudioDrains;
-
- bool mPaused;
- bool mWasPaused; // if paused then store the info
-
- int64_t mLastPositionUpdateUs;
- int64_t mVideoLateByUs;
- int64_t mAVSyncDelayWindowUs;
-
- bool onDrainAudioQueue();
- void postDrainAudioQueue(int64_t delayUs = 0);
-
- void onDrainVideoQueue();
- void postDrainVideoQueue();
-
- void onQueueBuffer(const sp<AMessage> &msg);
-
- void onQueueEOS(const sp<AMessage> &msg);
- void onFlush(const sp<AMessage> &msg);
- void onAudioSinkChanged();
- void onPause();
- void onResume();
-
- void notifyEOS(bool audio, status_t finalResult);
- void notifyFlushComplete(bool audio);
- void notifyPosition(bool isEOS = false);
- void notifyVideoLateBy(int64_t lateByUs);
-
- void flushQueue(List<QueueEntry> *queue);
- bool dropBufferWhileFlushing(bool audio, const sp<AMessage> &msg);
- void syncQueuesDone();
-
- // for qualcomm statistics profiling
- public:
-
- void registerStats(sp<DashPlayerStats> stats);
- status_t setMediaPresence(bool audio, bool bValue);
-
- private:
- sp<DashPlayerStats> mStats;
- int mLogLevel;
-
- DISALLOW_EVIL_CONSTRUCTORS(Renderer);
-};
-
-} // namespace android
-
-#endif // DASHPLAYER_RENDERER_H_
diff --git a/dashplayer/DashPlayerSource.h b/dashplayer/DashPlayerSource.h
deleted file mode 100644
index 3246aa96..00000000
--- a/dashplayer/DashPlayerSource.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * 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.
- */
-
-#ifndef DASHPLAYER_SOURCE_H_
-
-#define DASHPLAYER_SOURCE_H_
-
-#include "DashPlayer.h"
-
-namespace android {
-
-struct ABuffer;
-
-struct DashPlayer::Source : public RefBase {
- Source() {}
-
- virtual void start() = 0;
- virtual void stop() {}
-
- // Returns OK iff more data was available,
- // an error or ERROR_END_OF_STREAM if not.
- virtual status_t feedMoreTSData() = 0;
-
- virtual sp<MetaData> getFormat(int audio) = 0;
-
- virtual status_t dequeueAccessUnit(
- int track, sp<ABuffer> *accessUnit) = 0;
-
- virtual status_t getDuration(int64_t * /*durationUs*/) {
- return INVALID_OPERATION;
- }
-
- virtual status_t seekTo(int64_t /*seekTimeUs*/) {
- return INVALID_OPERATION;
- }
-
- virtual bool isSeekable() {
- return false;
- }
-
- virtual status_t getNewSeekTime(int64_t* /*newSeek*/) {
- return INVALID_OPERATION;
- }
-
- virtual status_t prepareAsync() {
- return INVALID_OPERATION;
- }
-
- virtual status_t isPrepareDone() {
- return INVALID_OPERATION;
- }
-
- virtual status_t getParameter(int /*key*/, void ** /*data*/, size_t * /*size*/) {
- return INVALID_OPERATION;
- }
-
- virtual status_t setParameter(int /*key*/, void * /*data*/, size_t /*size*/) {
- return INVALID_OPERATION;
- }
- virtual void notifyRenderingPosition(int64_t /*nRenderingTS*/){}
-
- virtual status_t setupSourceData(const sp<AMessage> & /*msg*/, int /*iTrack*/){
- return INVALID_OPERATION;
- }
- virtual status_t postNextTextSample(sp<ABuffer> /*accessUnit*/,const sp<AMessage> &/*msg*/,int /*iTrack*/) {
- return INVALID_OPERATION;
- }
-
- virtual status_t getMediaPresence(bool &/*audio*/, bool &/*video*/, bool &/*text*/) {
- return INVALID_OPERATION;
- }
-
- virtual status_t pause() {
- ALOGE("Pause called on Wrong DataSource.. Please check !!!");
- return INVALID_OPERATION;
- }
-
- virtual status_t resume() {
- ALOGE("Resume called on Wrong DataSource.. Please check !!!");
- return INVALID_OPERATION;
- }
-
- virtual status_t getRepositionRange(uint64_t* /*pMin*/, uint64_t* /*pMax*/, uint64_t* /*pMaxDepth*/) {
- return INVALID_OPERATION;
- }
-
- virtual sp<AMessage> getTrackInfo(size_t /*index*/) {
- return NULL;
- }
-
- virtual status_t getTrackCount()
- {
- return INVALID_OPERATION;
- }
-
- virtual bool isPlaybackDiscontinued() {
- return false;
- }
-
-protected:
- virtual ~Source() {}
-
-private:
- DISALLOW_EVIL_CONSTRUCTORS(Source);
-};
-
-} // namespace android
-
-#endif // DASHPLAYER_SOURCE_H_
-
diff --git a/dashplayer/DashPlayerStats.cpp b/dashplayer/DashPlayerStats.cpp
deleted file mode 100644
index bab014e0..00000000
--- a/dashplayer/DashPlayerStats.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "DashPlayerStats.h"
-
-#define NO_MIMETYPE_AVAILABLE "N/A"
-
-namespace android {
-
-DashPlayerStats::DashPlayerStats() {
- Mutex::Autolock autoLock(mStatsLock);
- mMIME = new char[strlen(NO_MIMETYPE_AVAILABLE)+1];
- strlcpy(mMIME,NO_MIMETYPE_AVAILABLE, strlen(NO_MIMETYPE_AVAILABLE)+1);
- mNumVideoFramesDecoded = 0;
- mNumVideoFramesDropped = 0;
- mConsecutiveFramesDropped = 0;
- mCatchupTimeStart = 0;
- mNumTimesSyncLoss = 0;
- mMaxEarlyDelta = 0;
- mMaxLateDelta = 0;
- mMaxTimeSyncLoss = 0;
- mTotalFrames = 0;
- mFirstFrameLatencyStartUs = getTimeOfDayUs();
- mLastFrame = 0;
- mLastFrameUs = 0;
- mStatisticsFrames = 0;
- mFPSSumUs = 0;
- mVeryFirstFrame = true;
- mSeekPerformed = false;
- mTotalTime = 0;
- mFirstFrameTime = 0;
- mTotalRenderingFrames = 0;
- mBufferingEvent = false;
- mFd = -1;
- mFileOut = NULL;
-}
-
-DashPlayerStats::~DashPlayerStats() {
- Mutex::Autolock autoLock(mStatsLock);
- if(mFileOut){
- fclose(mFileOut);
- mFileOut = NULL;
- }
- if(mMIME) {
- delete[] mMIME;
- mMIME = NULL;
- }
-}
-
-void DashPlayerStats::setFileDescAndOutputStream(int fd) {
- Mutex::Autolock autoLock(mStatsLock);
- mFd = fd;
- if(mFileOut){
- fclose(mFileOut);
- mFileOut = NULL;
- }
- mFileOut = fdopen(dup(fd), "w");
-}
-
-void DashPlayerStats::setMime(const char* mime) {
- Mutex::Autolock autoLock(mStatsLock);
- if(mime != NULL) {
- int mimeLen = (int)strlen(mime);
- if(mMIME) {
- delete[] mMIME;
- mMIME = NULL;
- }
-
- mMIME = new char[mimeLen+1];
- strlcpy(mMIME,mime,mimeLen+1);
- }
-}
-
-void DashPlayerStats::setVeryFirstFrame(bool /*vff*/) {
- Mutex::Autolock autoLock(mStatsLock);
- mVeryFirstFrame = true;
-}
-
-void DashPlayerStats::notifySeek() {
- Mutex::Autolock autoLock(mStatsLock);
- mFirstFrameLatencyStartUs = getTimeOfDayUs();
- mSeekPerformed = true;
-}
-
-void DashPlayerStats::notifyBufferingEvent() {
- Mutex::Autolock autoLock(mStatsLock);
- mBufferingEvent = true;
-}
-
-void DashPlayerStats::incrementTotalFrames() {
- Mutex::Autolock autoLock(mStatsLock);
- mTotalFrames++;
-}
-
-void DashPlayerStats::incrementTotalRenderingFrames() {
- Mutex::Autolock autoLock(mStatsLock);
- mTotalRenderingFrames++;
-}
-
-void DashPlayerStats::incrementDroppedFrames() {
- Mutex::Autolock autoLock(mStatsLock);
- mNumVideoFramesDropped++;
-}
-
-void DashPlayerStats::logStatistics() {
- if(mFileOut) {
- Mutex::Autolock autoLock(mStatsLock);
- fprintf(mFileOut, "=====================================================\n");
- fprintf(mFileOut, "Mime Type: %s\n",mMIME);
- fprintf(mFileOut, "Number of total frames: %llu\n",(unsigned long long)mTotalFrames);
- fprintf(mFileOut, "Number of frames dropped: %lld\n",(signed long long)mNumVideoFramesDropped);
- fprintf(mFileOut, "Number of frames rendered: %llu\n",(unsigned long long)mTotalRenderingFrames);
- fprintf(mFileOut, "Percentage dropped: %.2f\n",
- mTotalFrames == 0 ? 0.0 : (double)mNumVideoFramesDropped / (double)mTotalFrames);
- fprintf(mFileOut, "=====================================================\n");
- }
-}
-
-void DashPlayerStats::logPause(int64_t positionUs) {
- if(mFileOut) {
- fprintf(mFileOut, "=====================================================\n");
- fprintf(mFileOut, "Pause position: %lld ms\n",(signed long long)positionUs/1000);
- fprintf(mFileOut, "=====================================================\n");
- }
-}
-
-void DashPlayerStats::logSeek(int64_t seekTimeUs) {
- if(mFileOut) {
- Mutex::Autolock autoLock(mStatsLock);
- fprintf(mFileOut, "=====================================================\n");
- fprintf(mFileOut, "Seek position: %lld ms\n",(signed long long)seekTimeUs/1000);
- fprintf(mFileOut, "Seek latency: %lld ms\n",(signed long long)(getTimeOfDayUs() - mFirstFrameLatencyStartUs)/1000);
- fprintf(mFileOut, "=====================================================\n");
- }
-}
-
-void DashPlayerStats::recordLate(int64_t ts, int64_t clock, int64_t delta, int64_t anchorTime) {
- Mutex::Autolock autoLock(mStatsLock);
- mNumVideoFramesDropped++;
- mConsecutiveFramesDropped++;
- if (mConsecutiveFramesDropped == 1){
- mCatchupTimeStart = (uint32_t)anchorTime;
- }
-
- logLate(ts,clock,delta);
-}
-
-void DashPlayerStats::recordOnTime(int64_t ts, int64_t clock, int64_t delta) {
- Mutex::Autolock autoLock(mStatsLock);
- mNumVideoFramesDecoded++;
- mConsecutiveFramesDropped = 0;
- logOnTime(ts,clock,delta);
-}
-
-void DashPlayerStats::logSyncLoss() {
- if(mFileOut) {
- Mutex::Autolock autoLock(mStatsLock);
- fprintf(mFileOut, "=====================================================\n");
- fprintf(mFileOut, "Number of times AV Sync Losses = %u\n", mNumTimesSyncLoss);
- fprintf(mFileOut, "Max Video Ahead time delta = %lld\n", (signed long long)-mMaxEarlyDelta/1000);
- fprintf(mFileOut, "Max Video Behind time delta = %lld\n", (signed long long)mMaxLateDelta/1000);
- fprintf(mFileOut, "Max Time sync loss = %lld\n",(signed long long)mMaxTimeSyncLoss/1000);
- fprintf(mFileOut, "=====================================================\n");
- }
-}
-
-void DashPlayerStats::logFps() {
- if (mFileOut) {
- Mutex::Autolock autoLock(mStatsLock);
- int64_t now = getTimeOfDayUs();
-
- if(mTotalRenderingFrames < 2){
- mLastFrameUs = now;
- mFirstFrameTime = now;
- }
-
- mTotalTime = now - mFirstFrameTime;
- int64_t diff = now - mLastFrameUs;
- if (diff > 250000 && !mVeryFirstFrame && !mBufferingEvent) {
- double fps =((double)(mTotalRenderingFrames - mLastFrame) * 1E6)/(double)diff;
- if (mStatisticsFrames == 0) {
- fps =((double)(mTotalRenderingFrames - mLastFrame - 1) * 1E6)/(double)diff;
- }
- fprintf(mFileOut, "Frames per second: %.4f, Duration of measurement: %lld\n", fps,(signed long long)diff);
- mFPSSumUs += fps;
- ++mStatisticsFrames;
- mLastFrameUs = now;
- mLastFrame = mTotalRenderingFrames;
- }
-
- if(mSeekPerformed) {
- mVeryFirstFrame = false;
- mSeekPerformed = false;
- } else if(mVeryFirstFrame) {
- logFirstFrame();
- fprintf(mFileOut, "setting first frame time\n");
- mLastFrameUs = now;
- } else if(mBufferingEvent) {
- mLastFrameUs = now;
- mLastFrame = mTotalRenderingFrames;
- }
- mBufferingEvent = false;
- }
-}
-
-void DashPlayerStats::logFpsSummary() {
- if (mFileOut) {
- logStatistics();
- logSyncLoss();
- {
- Mutex::Autolock autoLock(mStatsLock);
- fprintf(mFileOut, "=========================================================\n");
- fprintf(mFileOut, "Average Frames Per Second: %.4f\n", mFPSSumUs/((double)mStatisticsFrames));
- fprintf(mFileOut, "Total Frames (rendered) / Total Time: %.4f\n", ((double)(mTotalRenderingFrames-1)*1E6)/((double)mTotalTime));
- fprintf(mFileOut, "========================================================\n");
- }
- }
-}
-
-int64_t DashPlayerStats::getTimeOfDayUs() {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
-// WARNING: Most private functions are only thread-safe within mStatsLock
-inline void DashPlayerStats::logFirstFrame() {
- fprintf(mFileOut, "=====================================================\n");
- fprintf(mFileOut, "First frame latency: %lld ms\n",(signed long long)(getTimeOfDayUs()-mFirstFrameLatencyStartUs)/1000);
- fprintf(mFileOut, "=====================================================\n");
- mVeryFirstFrame = false;
-}
-
-inline void DashPlayerStats::logCatchUp(int64_t ts, int64_t clock, int64_t /*delta*/) {
- if (mConsecutiveFramesDropped > 0) {
- mNumTimesSyncLoss++;
- if (mMaxTimeSyncLoss < (clock - mCatchupTimeStart) && clock > 0 && ts > 0) {
- mMaxTimeSyncLoss = clock - mCatchupTimeStart;
- }
- }
-}
-
-inline void DashPlayerStats::logLate(int64_t ts, int64_t clock, int64_t delta) {
- if (mMaxLateDelta < delta && clock > 0 && ts > 0) {
- mMaxLateDelta = delta;
- }
-}
-
-inline void DashPlayerStats::logOnTime(int64_t ts, int64_t clock, int64_t delta) {
- bool needLogLate = false;
- logCatchUp(ts, clock, delta);
- if (delta <= 0) {
- if ((-delta) > (-mMaxEarlyDelta) && clock > 0 && ts > 0) {
- mMaxEarlyDelta = delta;
- }
- }
- else {
- needLogLate = true;
- }
-
- if(needLogLate) logLate(ts, clock, delta);
-}
-
-} // namespace android
diff --git a/dashplayer/DashPlayerStats.h b/dashplayer/DashPlayerStats.h
deleted file mode 100644
index 198cb05e..00000000
--- a/dashplayer/DashPlayerStats.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DASHPLAYER_STATS_H_
-
-#define DASHPLAYER_STATS_H_
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-namespace android {
-
-class DashPlayerStats : public RefBase {
- public:
- DashPlayerStats();
- ~DashPlayerStats();
-
- void setMime(const char* mime);
- void setVeryFirstFrame(bool vff);
- void notifySeek();
- void incrementTotalFrames();
- void incrementDroppedFrames();
- void logStatistics();
- void logPause(int64_t positionUs);
- void logSeek(int64_t seekTimeUs);
- void recordLate(int64_t ts, int64_t clock, int64_t delta, int64_t anchorTime);
- void recordOnTime(int64_t ts, int64_t clock, int64_t delta);
- void logSyncLoss();
- void logFps();
- void logFpsSummary();
- static int64_t getTimeOfDayUs();
- void incrementTotalRenderingFrames();
- void notifyBufferingEvent();
- void setFileDescAndOutputStream(int fd);
-
- private:
- void logFirstFrame();
- void logCatchUp(int64_t ts, int64_t clock, int64_t delta);
- void logLate(int64_t ts, int64_t clock, int64_t delta);
- void logOnTime(int64_t ts, int64_t clock, int64_t delta);
-
- mutable Mutex mStatsLock;
- bool mStatistics;
- char* mMIME;
- int64_t mNumVideoFramesDecoded;
- int64_t mNumVideoFramesDropped;
- int64_t mConsecutiveFramesDropped;
- int64_t mCatchupTimeStart;
- uint32_t mNumTimesSyncLoss;
- int64_t mMaxEarlyDelta;
- int64_t mMaxLateDelta;
- int64_t mMaxTimeSyncLoss;
- uint64_t mTotalFrames;
- int64_t mFirstFrameLatencyStartUs;
- int64_t mLastFrame;
- int64_t mLastFrameUs;
- double mFPSSumUs;
- int64_t mStatisticsFrames;
- bool mVeryFirstFrame;
- bool mSeekPerformed;
- int64_t mTotalTime;
- int64_t mFirstFrameTime;
- uint64_t mTotalRenderingFrames;
- bool mBufferingEvent;
- int mFd;
- FILE *mFileOut;
-};
-
-} // namespace android
-
-#endif // DASHPLAYER_STATS_H_
diff --git a/dashplayer/jni/Android.mk b/dashplayer/jni/Android.mk
deleted file mode 100644
index 0e127c49..00000000
--- a/dashplayer/jni/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- android_media_ExtMediaPlayer.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
- libandroid_runtime \
- libnativehelper \
- libutils \
- libbinder \
- liblog \
- libstagefright \
- libstagefright_foundation \
- libdl \
-
-LOCAL_C_INCLUDES += \
- $(TOP)/frameworks/base/core/jni \
- $(TOP)/frameworks/av/media/libstagefright \
- $(LOCAL_PATH)/../../QCMediaPlayer/native \
-
-LOCAL_MODULE:= libextmedia_jni
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/dashplayer/jni/android_media_ExtMediaPlayer.cpp b/dashplayer/jni/android_media_ExtMediaPlayer.cpp
deleted file mode 100755
index 764e02c9..00000000
--- a/dashplayer/jni/android_media_ExtMediaPlayer.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*Copyright (c) 2013, 2015, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define LOG_TAG "ExtMediaPlayer-JNI"
-
-#include "android_media_ExtMediaPlayer.h"
-#include <dlfcn.h>
-
-using namespace android;
-
-
-extern "C" MediaPlayerListener*
-CreateJNIExtMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz,const sp<MediaPlayerListener>& listener) {
- return (new JNIExtMediaPlayerListener(env, thiz, weak_thiz, listener));
-}
-
-extern "C" bool
-checkExtMedia(JNIEnv *env, jobject thiz){
- jclass clazz = NULL;
- bool nRet = false;
- clazz = env->FindClass("com/qualcomm/qcmedia/QCMediaPlayer");
- if (clazz != NULL) {
- if (env->IsInstanceOf(thiz,clazz)) {
- nRet = true;
- ALOGD("QCMediaPlayer mediaplayer present");
- } else {
- ALOGE("env->IsInstanceOf fails");
- }
- } else {
- //Clear the exception as QCMediaPlayer is optional
- env->ExceptionClear();
- ALOGE("QCMediaPlayer could not be located....");
- }
- return nRet;
-}
-
-JNIExtMediaPlayerListener::JNIExtMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz,const sp<MediaPlayerListener>& listener) {
- jclass clazz = env->GetObjectClass(thiz);
- if (clazz == NULL) {
- ALOGE("Can't find android/media/MediaPlayer");
- jniThrowException(env, "java/lang/Exception", NULL);
- return;
- }
- mpListener = listener;
- extfields.ext_post_event = env->GetStaticMethodID(clazz, "QCMediaPlayerNativeEventHandler",
- "(Ljava/lang/Object;IIILjava/lang/Object;)V");
- mClass = (jclass)env->NewGlobalRef(clazz);
-
- // We use a weak reference so the MediaPlayer object can be garbage collected.
- // The reference is only used as a proxy for callbacks.
- mObject = env->NewGlobalRef(weak_thiz);
-}
-
-JNIExtMediaPlayerListener::~JNIExtMediaPlayerListener() {
- // remove global references
- JNIEnv *env = AndroidRuntime::getJNIEnv();
- env->DeleteGlobalRef(mObject);
- env->DeleteGlobalRef(mClass);
-}
-
-
-void JNIExtMediaPlayerListener::notify(int msg, int ext1, int ext2, const Parcel *obj) {
- JNIEnv *env = AndroidRuntime::getJNIEnv();
- if (env && obj && obj->dataSize() > 0) {
- jobject jParcel = createJavaParcelObject(env);
- if (jParcel != NULL) {
- if((extfields.ext_post_event != NULL) &&
- ((msg == MEDIA_PREPARED) || (msg == MEDIA_TIMED_TEXT) || (msg == MEDIA_QOE))) {
- ALOGE("JNIExtMediaPlayerListener::notify calling ext_post_event");
- Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
- if(nativeParcel != NULL) {
- nativeParcel->setData(obj->data(), obj->dataSize());
- env->CallStaticVoidMethod(mClass, extfields.ext_post_event, mObject,
- msg, ext1, ext2, jParcel);
- env->DeleteLocalRef(jParcel);
- ALOGD("JNIExtMediaPlayerListener::notify ext_post_event done");
- }
- } else {
- ALOGD("JNIExtMediaPlayerListener::notify calling for generic event");
- mpListener->notify(msg, ext1, ext2, obj);
- }
- }
- } else {
- if((extfields.ext_post_event != NULL) &&
- ((msg == MEDIA_PREPARED) || (msg == MEDIA_TIMED_TEXT) ||(msg == MEDIA_QOE)))
- {
- ALOGD("JNIExtMediaPlayerListener::notify calling ext_post_events");
- env->CallStaticVoidMethod(mClass, extfields.ext_post_event, mObject, msg, ext1, ext2, NULL);
- } else {
- ALOGD("JNIExtMediaPlayerListener::notify for generic events");
- mpListener->notify(msg, ext1, ext2, obj);
- }
- }
- return;
-}
-
-
-extern "C" MediaPlayer *CreateNativeQCMediaPlayer()
-{
- const char* QCMEDIAPLAYER_LIB = "libqcmediaplayer.so";
- const char* QCMEDIAPLAYER_CREATE_FN = "CreateQCMediaPlayer";
- void* pQCMediaPlayerLib = NULL;
-
- typedef MediaPlayer* (*CreateQCMediaPlayerFn)();
-
- /* Open library */
- ALOGI("calling dlopen on QCMEDIAPLAYER_LIB");
- pQCMediaPlayerLib = ::dlopen(QCMEDIAPLAYER_LIB, RTLD_LAZY);
-
- if (pQCMediaPlayerLib == NULL) {
- ALOGE("Failed to open QCMEDIAPLAYER_LIB Error : %s ",::dlerror());
- return NULL;
- }
-
- CreateQCMediaPlayerFn pCreateFnPtr = NULL;
- ALOGI("calling dlsym on pQCMediaPlayerLib for QCMEDIAPLAYER_CREATE_FN ");
- pCreateFnPtr = (CreateQCMediaPlayerFn) dlsym(pQCMediaPlayerLib, QCMEDIAPLAYER_CREATE_FN);
-
- if (pCreateFnPtr == NULL) {
- ALOGE("Could not locate CreateQCMediaPlayerFn pCreateFnPtr");
- return NULL;
- }
-
- MediaPlayer* pQCMediaPlayer = pCreateFnPtr();
-
- if(pQCMediaPlayer==NULL) {
- ALOGE("Failed to invoke CreateQCMediaPlayerFn...");
- return NULL;
- }
-
- return pQCMediaPlayer;
-}
-
diff --git a/dashplayer/jni/android_media_ExtMediaPlayer.h b/dashplayer/jni/android_media_ExtMediaPlayer.h
deleted file mode 100644
index b5cc3001..00000000
--- a/dashplayer/jni/android_media_ExtMediaPlayer.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*Copyright (c) 2013, 2015, The Linux Foundation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- * * Neither the name of The Linux Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _ANDROID_MEDIA_EXTMEDIAPLAYER_H_
-#define _ANDROID_MEDIA_EXTMEDIAPLAYER_H_
-
-//#define LOG_NDEBUG 0
-#include <qcmediaplayer.h>
-#include "JNIHelp.h"
-#include "android_runtime/AndroidRuntime.h"
-#include "android_runtime/Log.h"
-#include "android_os_Parcel.h"
-#include <binder/Parcel.h>
-
-using namespace android;
-
-struct extfields_t {
- jmethodID ext_post_event;
-};
-static extfields_t extfields;
-
-class JNIExtMediaPlayerListener: public MediaPlayerListener {
- public:
- JNIExtMediaPlayerListener(JNIEnv* env, jobject thiz, jobject weak_thiz, const sp<MediaPlayerListener>& listener);
- ~JNIExtMediaPlayerListener();
- virtual void notify(int msg, int ext1, int ext2, const Parcel *obj = NULL);
- private:
- JNIExtMediaPlayerListener();
- JNIExtMediaPlayerListener( const JNIExtMediaPlayerListener &);
- JNIExtMediaPlayerListener& operator=(const JNIExtMediaPlayerListener&);
- jclass mClass; // Reference to MediaPlayer class
- jobject mObject; // Weak ref to MediaPlayer Java object to call on
- sp<MediaPlayerListener> mpListener;
-};
-#endif //_ANDROID_MEDIA_EXTMEDIAPLAYER_H_