Loading media/libstagefright/httplive/LiveSession.cpp +63 −34 Original line number Diff line number Diff line Loading @@ -507,15 +507,36 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { return info.mFetcher; } /* * Illustration of parameters: * * 0 `range_offset` * +------------+-------------------------------------------------------+--+--+ * | | | next block to fetch | | | * | | `source` handle => `out` buffer | | | | * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | * | |<----------- `range_length` / buffer capacity ----------->| | * |<------------------------------ file_size ------------------------------->| * * Special parameter values: * - range_length == -1 means entire file * - block_size == 0 means entire range * */ status_t LiveSession::fetchFile( const char *url, sp<ABuffer> *out, int64_t range_offset, int64_t range_length) { *out = NULL; sp<DataSource> source; int64_t range_offset, int64_t range_length, uint32_t block_size, /* download block size */ sp<DataSource> *source /* to return and reuse source */) { off64_t size; sp<DataSource> temp_source; if (source == NULL) { source = &temp_source; } if (*source == NULL) { if (!strncasecmp(url, "file://", 7)) { source = new FileSource(url + 7); *source = new FileSource(url + 7); } else if (strncasecmp(url, "http://", 7) && strncasecmp(url, "https://", 8)) { return ERROR_UNSUPPORTED; Loading @@ -529,7 +550,8 @@ status_t LiveSession::fetchFile( "bytes=%lld-%s", range_offset, range_length < 0 ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str())); ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str())); } status_t err = mHTTPDataSource->connect(url, &headers); Loading @@ -537,23 +559,28 @@ status_t LiveSession::fetchFile( return err; } source = mHTTPDataSource; *source = mHTTPDataSource; } } off64_t size; status_t err = source->getSize(&size); if (err != OK) { status_t getSizeErr = (*source)->getSize(&size); if (getSizeErr != OK) { size = 65536; } sp<ABuffer> buffer = new ABuffer(size); sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); if (*out == NULL) { buffer->setRange(0, 0); } // adjust range_length if only reading partial block if (block_size > 0 && (range_length == -1 || buffer->size() + block_size < range_length)) { range_length = buffer->size() + block_size; } for (;;) { // Only resize when we don't know the size. size_t bufferRemaining = buffer->capacity() - buffer->size(); if (bufferRemaining == 0) { if (bufferRemaining == 0 && getSizeErr != OK) { bufferRemaining = 32768; ALOGV("increasing download buffer to %d bytes", Loading @@ -578,7 +605,9 @@ status_t LiveSession::fetchFile( } } ssize_t n = source->readAt( // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) // to help us break out of the loop. ssize_t n = (*source)->readAt( buffer->size(), buffer->data() + buffer->size(), maxBytesToRead); Loading media/libstagefright/httplive/LiveSession.h +17 −1 Original line number Diff line number Diff line Loading @@ -146,9 +146,25 @@ private: status_t onSeek(const sp<AMessage> &msg); void onFinishDisconnect2(); // If given a non-zero block_size (default 0), it is used to cap the number of // bytes read in from the DataSource. If given a non-NULL buffer, new content // is read into the end. // // The DataSource we read from is responsible for signaling error or EOF to help us // break out of the read loop. The DataSource can be returned to the caller, so // that the caller can reuse it for subsequent fetches (within the initially // requested range). // // For reused HTTP sources, the caller must download a file sequentially without // any overlaps or gaps to prevent reconnection. status_t fetchFile( const char *url, sp<ABuffer> *out, int64_t range_offset = 0, int64_t range_length = -1); /* request/open a file starting at range_offset for range_length bytes */ int64_t range_offset = 0, int64_t range_length = -1, /* download block size */ uint32_t block_size = 0, /* reuse DataSource if doing partial fetch */ sp<DataSource> *source = NULL); sp<M3UParser> fetchPlaylist( const char *url, uint8_t *curPlaylistHash, bool *unchanged); Loading Loading
media/libstagefright/httplive/LiveSession.cpp +63 −34 Original line number Diff line number Diff line Loading @@ -507,15 +507,36 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) { return info.mFetcher; } /* * Illustration of parameters: * * 0 `range_offset` * +------------+-------------------------------------------------------+--+--+ * | | | next block to fetch | | | * | | `source` handle => `out` buffer | | | | * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | | * | |<----------- `range_length` / buffer capacity ----------->| | * |<------------------------------ file_size ------------------------------->| * * Special parameter values: * - range_length == -1 means entire file * - block_size == 0 means entire range * */ status_t LiveSession::fetchFile( const char *url, sp<ABuffer> *out, int64_t range_offset, int64_t range_length) { *out = NULL; sp<DataSource> source; int64_t range_offset, int64_t range_length, uint32_t block_size, /* download block size */ sp<DataSource> *source /* to return and reuse source */) { off64_t size; sp<DataSource> temp_source; if (source == NULL) { source = &temp_source; } if (*source == NULL) { if (!strncasecmp(url, "file://", 7)) { source = new FileSource(url + 7); *source = new FileSource(url + 7); } else if (strncasecmp(url, "http://", 7) && strncasecmp(url, "https://", 8)) { return ERROR_UNSUPPORTED; Loading @@ -529,7 +550,8 @@ status_t LiveSession::fetchFile( "bytes=%lld-%s", range_offset, range_length < 0 ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str())); ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str())); } status_t err = mHTTPDataSource->connect(url, &headers); Loading @@ -537,23 +559,28 @@ status_t LiveSession::fetchFile( return err; } source = mHTTPDataSource; *source = mHTTPDataSource; } } off64_t size; status_t err = source->getSize(&size); if (err != OK) { status_t getSizeErr = (*source)->getSize(&size); if (getSizeErr != OK) { size = 65536; } sp<ABuffer> buffer = new ABuffer(size); sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size); if (*out == NULL) { buffer->setRange(0, 0); } // adjust range_length if only reading partial block if (block_size > 0 && (range_length == -1 || buffer->size() + block_size < range_length)) { range_length = buffer->size() + block_size; } for (;;) { // Only resize when we don't know the size. size_t bufferRemaining = buffer->capacity() - buffer->size(); if (bufferRemaining == 0) { if (bufferRemaining == 0 && getSizeErr != OK) { bufferRemaining = 32768; ALOGV("increasing download buffer to %d bytes", Loading @@ -578,7 +605,9 @@ status_t LiveSession::fetchFile( } } ssize_t n = source->readAt( // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0) // to help us break out of the loop. ssize_t n = (*source)->readAt( buffer->size(), buffer->data() + buffer->size(), maxBytesToRead); Loading
media/libstagefright/httplive/LiveSession.h +17 −1 Original line number Diff line number Diff line Loading @@ -146,9 +146,25 @@ private: status_t onSeek(const sp<AMessage> &msg); void onFinishDisconnect2(); // If given a non-zero block_size (default 0), it is used to cap the number of // bytes read in from the DataSource. If given a non-NULL buffer, new content // is read into the end. // // The DataSource we read from is responsible for signaling error or EOF to help us // break out of the read loop. The DataSource can be returned to the caller, so // that the caller can reuse it for subsequent fetches (within the initially // requested range). // // For reused HTTP sources, the caller must download a file sequentially without // any overlaps or gaps to prevent reconnection. status_t fetchFile( const char *url, sp<ABuffer> *out, int64_t range_offset = 0, int64_t range_length = -1); /* request/open a file starting at range_offset for range_length bytes */ int64_t range_offset = 0, int64_t range_length = -1, /* download block size */ uint32_t block_size = 0, /* reuse DataSource if doing partial fetch */ sp<DataSource> *source = NULL); sp<M3UParser> fetchPlaylist( const char *url, uint8_t *curPlaylistHash, bool *unchanged); Loading