use of java.io.FileDescriptor in project android_frameworks_base by ResurrectionRemix.
the class MediaPlayer method addTimedTextSource.
/* TODO: Limit the total number of external timed text source to a reasonable number.
*/
/**
* Adds an external timed text source file.
*
* Currently supported format is SubRip with the file extension .srt, case insensitive.
* Note that a single external timed text source may contain multiple tracks in it.
* One can find the total number of available tracks using {@link #getTrackInfo()} to see what
* additional tracks become available after this method call.
*
* @param path The file path of external timed text source file.
* @param mimeType The mime type of the file. Must be one of the mime types listed above.
* @throws IOException if the file cannot be accessed or is corrupted.
* @throws IllegalArgumentException if the mimeType is not supported.
* @throws IllegalStateException if called in an invalid state.
*/
public void addTimedTextSource(String path, String mimeType) throws IOException, IllegalArgumentException, IllegalStateException {
if (!availableMimeTypeForExternalSource(mimeType)) {
final String msg = "Illegal mimeType for timed text source: " + mimeType;
throw new IllegalArgumentException(msg);
}
File file = new File(path);
if (file.exists()) {
FileInputStream is = new FileInputStream(file);
FileDescriptor fd = is.getFD();
addTimedTextSource(fd, mimeType);
is.close();
} else {
// We do not support the case where the path is not a file.
throw new IOException(path);
}
}
use of java.io.FileDescriptor in project android_frameworks_base by ResurrectionRemix.
the class MediaPlayer method addTimedTextSource.
/**
* Adds an external timed text file (FileDescriptor).
*
* It is the caller's responsibility to close the file descriptor.
* It is safe to do so as soon as this call returns.
*
* Currently supported format is SubRip. Note that a single external timed text source may
* contain multiple tracks in it. One can find the total number of available tracks
* using {@link #getTrackInfo()} to see what additional tracks become available
* after this method call.
*
* @param fd the FileDescriptor for the file you want to play
* @param offset the offset into the file where the data to be played starts, in bytes
* @param length the length in bytes of the data to be played
* @param mime The mime type of the file. Must be one of the mime types listed above.
* @throws IllegalArgumentException if the mimeType is not supported.
* @throws IllegalStateException if called in an invalid state.
*/
public void addTimedTextSource(FileDescriptor fd, long offset, long length, String mime) throws IllegalArgumentException, IllegalStateException {
if (!availableMimeTypeForExternalSource(mime)) {
throw new IllegalArgumentException("Illegal mimeType for timed text source: " + mime);
}
final FileDescriptor dupedFd;
try {
dupedFd = Libcore.os.dup(fd);
} catch (ErrnoException ex) {
Log.e(TAG, ex.getMessage(), ex);
throw new RuntimeException(ex);
}
final MediaFormat fFormat = new MediaFormat();
fFormat.setString(MediaFormat.KEY_MIME, mime);
fFormat.setInteger(MediaFormat.KEY_IS_TIMED_TEXT, 1);
// A MediaPlayer created by a VideoView should already have its mSubtitleController set.
if (mSubtitleController == null) {
setSubtitleAnchor();
}
if (!mSubtitleController.hasRendererFor(fFormat)) {
// test and add not atomic
Context context = ActivityThread.currentApplication();
mSubtitleController.registerRenderer(new SRTRenderer(context, mEventHandler));
}
final SubtitleTrack track = mSubtitleController.addTrack(fFormat);
synchronized (mIndexTrackPairs) {
mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
}
getMediaTimeProvider();
final long offset2 = offset;
final long length2 = length;
final HandlerThread thread = new HandlerThread("TimedTextReadThread", Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
thread.start();
Handler handler = new Handler(thread.getLooper());
handler.post(new Runnable() {
private int addTrack() {
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
Libcore.os.lseek(dupedFd, offset2, OsConstants.SEEK_SET);
byte[] buffer = new byte[4096];
for (long total = 0; total < length2; ) {
int bytesToRead = (int) Math.min(buffer.length, length2 - total);
int bytes = IoBridge.read(dupedFd, buffer, 0, bytesToRead);
if (bytes < 0) {
break;
} else {
bos.write(buffer, 0, bytes);
total += bytes;
}
}
Handler h = mTimeProvider.mEventHandler;
int what = TimeProvider.NOTIFY;
int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
Message m = h.obtainMessage(what, arg1, 0, trackData);
h.sendMessage(m);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
return MEDIA_INFO_TIMED_TEXT_ERROR;
} finally {
try {
Libcore.os.close(dupedFd);
} catch (ErrnoException e) {
Log.e(TAG, e.getMessage(), e);
}
}
}
public void run() {
int res = addTrack();
if (mEventHandler != null) {
Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
mEventHandler.sendMessage(m);
}
thread.getLooper().quitSafely();
}
});
}
use of java.io.FileDescriptor in project android_frameworks_base by ResurrectionRemix.
the class ThumbnailUtils method makeBitmap.
/**
* Make a bitmap from a given Uri, minimal side length, and maximum number of pixels.
* The image data will be read from specified pfd if it's not null, otherwise
* a new input stream will be created using specified ContentResolver.
*
* Clients are allowed to pass their own BitmapFactory.Options used for bitmap decoding. A
* new BitmapFactory.Options will be created if options is null.
*/
private static Bitmap makeBitmap(int minSideLength, int maxNumOfPixels, Uri uri, ContentResolver cr, ParcelFileDescriptor pfd, BitmapFactory.Options options) {
Bitmap b = null;
try {
if (pfd == null)
pfd = makeInputStream(uri, cr);
if (pfd == null)
return null;
if (options == null)
options = new BitmapFactory.Options();
FileDescriptor fd = pfd.getFileDescriptor();
options.inSampleSize = 1;
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fd, null, options);
if (options.mCancel || options.outWidth == -1 || options.outHeight == -1) {
return null;
}
options.inSampleSize = computeSampleSize(options, minSideLength, maxNumOfPixels);
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
b = BitmapFactory.decodeFileDescriptor(fd, null, options);
} catch (OutOfMemoryError ex) {
Log.e(TAG, "Got oom exception ", ex);
return null;
} finally {
closeSilently(pfd);
}
return b;
}
use of java.io.FileDescriptor in project android_frameworks_base by ResurrectionRemix.
the class MediaPlayer method setDataSource.
private void setDataSource(String path, String[] keys, String[] values) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
final Uri uri = Uri.parse(path);
final String scheme = uri.getScheme();
if ("file".equals(scheme)) {
path = uri.getPath();
} else if (scheme != null) {
// handle non-file sources
nativeSetDataSource(MediaHTTPService.createHttpServiceBinderIfNecessary(path), path, keys, values);
return;
}
final File file = new File(path);
if (file.exists()) {
FileInputStream is = new FileInputStream(file);
FileDescriptor fd = is.getFD();
setDataSource(fd);
is.close();
} else {
throw new IOException("setDataSource failed.");
}
}
use of java.io.FileDescriptor in project android_frameworks_base by ResurrectionRemix.
the class NativeDaemonConnector method listenToSocket.
private void listenToSocket() throws IOException {
LocalSocket socket = null;
try {
socket = new LocalSocket();
LocalSocketAddress address = determineSocketAddress();
socket.connect(address);
InputStream inputStream = socket.getInputStream();
synchronized (mDaemonLock) {
mOutputStream = socket.getOutputStream();
}
mCallbacks.onDaemonConnected();
FileDescriptor[] fdList = null;
byte[] buffer = new byte[BUFFER_SIZE];
int start = 0;
while (true) {
int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
if (count < 0) {
loge("got " + count + " reading with start = " + start);
break;
}
fdList = socket.getAncillaryFileDescriptors();
// Add our starting point to the count and reset the start.
count += start;
start = 0;
for (int i = 0; i < count; i++) {
if (buffer[i] == 0) {
// Note - do not log this raw message since it may contain
// sensitive data
final String rawEvent = new String(buffer, start, i - start, StandardCharsets.UTF_8);
boolean releaseWl = false;
try {
final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(rawEvent, fdList);
log("RCV <- {" + event + "}");
if (event.isClassUnsolicited()) {
// TODO: migrate to sending NativeDaemonEvent instances
if (mCallbacks.onCheckHoldWakeLock(event.getCode()) && mWakeLock != null) {
mWakeLock.acquire();
releaseWl = true;
}
Message msg = mCallbackHandler.obtainMessage(event.getCode(), uptimeMillisInt(), 0, event.getRawEvent());
if (mCallbackHandler.sendMessage(msg)) {
releaseWl = false;
}
} else {
mResponseQueue.add(event.getCmdNumber(), event);
}
} catch (IllegalArgumentException e) {
log("Problem parsing message " + e);
} finally {
if (releaseWl) {
mWakeLock.release();
}
}
start = i + 1;
}
}
if (start == 0) {
log("RCV incomplete");
}
// buffer and read again.
if (start != count) {
final int remaining = BUFFER_SIZE - start;
System.arraycopy(buffer, start, buffer, 0, remaining);
start = remaining;
} else {
start = 0;
}
}
} catch (IOException ex) {
loge("Communications error: " + ex);
throw ex;
} finally {
synchronized (mDaemonLock) {
if (mOutputStream != null) {
try {
loge("closing stream for " + mSocket);
mOutputStream.close();
} catch (IOException e) {
loge("Failed closing output stream: " + e);
}
mOutputStream = null;
}
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException ex) {
loge("Failed closing socket: " + ex);
}
}
}
Aggregations