This basic article is for System Developer for Android TV, provides background on what and how to develop so that a TV application(which is based on Android TV framework) can render video from a HDMI input(like Nexus Player or HDMI Media Player etc.) plugged in TV.
We can further divide this task in 2 sub-task -
Also this development is done in a SOC vendor side, i.e.
Before this following Android Developer pages should be gone through
And obviously one must have installed a TV application(like "Live Channels" by Google) which can detect and interact to our HDMI input implementation.
Now let's start 1st part,
Android TV framework base classes/APIs can be found in following path
/platform/frameworks/base/media/java/android/media/tv/
A TV input Service should be extended from TvInputService and hence implements all the abstract methods of it and it's inner class Session, also overrides some of methods.
We can further divide this task in 2 sub-task -
[1]Develop TvInputService for HDMI Input
[2]Implement TvInput HAL for HDMI Input
Also this development is done in a SOC vendor side, i.e.
- First sub-task will be part of System-Apps, it uses System APIs,
- and second HAL implementation sub-task is a typical Android HAL implementation which relies on lower layer HDMI layer.
Before this following Android Developer pages should be gone through
- For Android TV Architecture
- Developing a TV input service
- A sample tv input which streams some HLS/DASH streams and local file
And obviously one must have installed a TV application(like "Live Channels" by Google) which can detect and interact to our HDMI input implementation.
Now let's start 1st part,
Develop TvInputService for HDMI Input
Android TV framework base classes/APIs can be found in following path
/platform/frameworks/base/media/java/android/media/tv/
A TV input Service should be extended from TvInputService and hence implements all the abstract methods of it and it's inner class Session, also overrides some of methods.
public class HDMIInputService extends TvInputService
{
private int HDMI_HW_ID = 1;
private TvInputInfo mTvInputInfo;
@Override
public Session onCreateSession(String inputId)
{
return new HDMISession(this, inputId);
}
@Override
public TvInputInfo onHardwareAdded(TvInputHardwareInfo hardwareInfo)
{
Context context = getApplicationContext();
ResolveInfo ri = context.getPackageManager().resolveService(new Intent("android.media.tv.TvInputService"), PackageManager.GET_INTENT_FILTERS | PackageManager.GET_META_DATA);
mTvInputInfo = TvInputInfo.createTvInputInfo(context, ri, hardwareInfo, null, TvContract.buildChannelUriForPassthroughInput(Id));
return mTvInputInfo;
}
@Override
public String onHardwareRemoved(TvInputHardwareInfo hardwareInfo)
{
return null;
}
private class HDMISession extends Session
{
private final Context mContext;
private final String mInputId;
private Surface mSurface;
private float mVolume;
private boolean mCaptionEnabled;
private TvInputManager mTvInputManager;
private TvInputManager.Hardware mHardware;
private TvStreamConfig[] mTvStreamConfig;
private final TvInputManager.HardwareCallback mHardwareCallback = new TvInputManager.HardwareCallback() {
@Override
public void onReleased() { }
@Override
public void onStreamConfigChanged(TvStreamConfig[] configs)
{
mTvStreamConfig = configs;
}
};
HDMISession (Context context, String inputId)
{
super(context);
mContext = context;
mInputId = inputId;
mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
mHardware = mTvInputManager.acquireTvInputHardware(HDMI_HW_ID, mHardwareCallback, mTvInputInfo);
}
@Override
public void onRelease() {
mTvInputManager.releaseTvInputHardware(HDMI_HW_ID, mHardware);
}
@Override
public boolean onSetSurface(Surface surface)
{
mSurface = surface;
mHardware.setSurface(mSurface, mTvStreamConfig[0]);
return true;
}
@Override
public void onSetStreamVolume(float volume)
{
mVolume = volume;
}
@Override
public boolean onTune(Uri channeluri)
{
notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING);
notifyVideoAvailable();
return true;
}
@Override
public void onSetCaptionEnabled(boolean enabled)
{
mCaptionEnabled = enabled;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return false; //if not handling, otherwise return true
}
}
}
To keep things simple, only minimal code is written here. This can be build as independent apk and installed. Reference can be taken from SampleTvInput here.
This comment has been removed by a blog administrator.
ReplyDelete