mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
for #738, use reader and seeker for mp4 demuxer to seek for general mp4(ftyp-mdat-moov).
This commit is contained in:
parent
bbee16e4db
commit
9d21a8bb33
16 changed files with 237 additions and 101 deletions
|
@ -280,7 +280,7 @@ void SrsHttpFileReader::skip(int64_t /*size*/)
|
|||
{
|
||||
}
|
||||
|
||||
int64_t SrsHttpFileReader::lseek(int64_t offset)
|
||||
int64_t SrsHttpFileReader::seek2(int64_t offset)
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
@ -324,4 +324,10 @@ int SrsHttpFileReader::read(void* buf, size_t count, ssize_t* pnread)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsHttpFileReader::lseek(off_t offset, int whence, off_t* seeked)
|
||||
{
|
||||
// TODO: FIXME: Use HTTP range for seek.
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -120,14 +120,11 @@ public:
|
|||
virtual bool is_open();
|
||||
virtual int64_t tellg();
|
||||
virtual void skip(int64_t size);
|
||||
virtual int64_t lseek(int64_t offset);
|
||||
virtual int64_t seek2(int64_t offset);
|
||||
virtual int64_t filesize();
|
||||
public:
|
||||
/**
|
||||
* read from file.
|
||||
* @param pnread the output nb_read, NULL to ignore.
|
||||
*/
|
||||
virtual int read(void* buf, size_t count, ssize_t* pnread);
|
||||
virtual int lseek(off_t offset, int whence, off_t* seeked);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -370,7 +370,7 @@ int SrsFlvSegment::update_flv_metadata()
|
|||
}
|
||||
|
||||
// update the flesize.
|
||||
fs->lseek(filesize_offset);
|
||||
fs->seek2(filesize_offset);
|
||||
if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -385,13 +385,13 @@ int SrsFlvSegment::update_flv_metadata()
|
|||
}
|
||||
|
||||
// update the duration
|
||||
fs->lseek(duration_offset);
|
||||
fs->seek2(duration_offset);
|
||||
if ((ret = fs->write(buf, SrsAmf0Size::number(), NULL)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// reset the offset.
|
||||
fs->lseek(cur);
|
||||
fs->seek2(cur);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r
|
|||
}
|
||||
|
||||
// write body.
|
||||
if ((ret = ffd.lseek(offset)) != ERROR_SUCCESS) {
|
||||
if ((ret = ffd.seek2(offset)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r
|
|||
w->header()->set("Content-Range", content_range.str());
|
||||
|
||||
// write body.
|
||||
fs.lseek(start);
|
||||
fs.seek2(start);
|
||||
|
||||
// send data
|
||||
if ((ret = copy(w, &fs, r, (int)left)) != ERROR_SUCCESS) {
|
||||
|
|
|
@ -248,9 +248,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_MP4_BOX_ILLEGAL_SCHEMA 3072
|
||||
#define ERROR_MP4_BOX_STRING 3073
|
||||
#define ERROR_MP4_BOX_ILLEGAL_BRAND 3074
|
||||
#define ERROR_MP4_NOT_NON_SEEKABLE 3075
|
||||
#define ERROR_MP4_ESDS_SL_Config 3076
|
||||
#define ERROR_MP4_ILLEGAL_MOOV 3077
|
||||
#define ERROR_MP4_ESDS_SL_Config 3075
|
||||
#define ERROR_MP4_ILLEGAL_MOOV 3076
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// HTTP/StreamCaster/KAFKA protocol error.
|
||||
|
|
|
@ -117,7 +117,7 @@ bool SrsFileWriter::is_open()
|
|||
return fd > 0;
|
||||
}
|
||||
|
||||
void SrsFileWriter::lseek(int64_t offset)
|
||||
void SrsFileWriter::seek2(int64_t offset)
|
||||
{
|
||||
::lseek(fd, (off_t)offset, SEEK_SET);
|
||||
}
|
||||
|
@ -167,6 +167,19 @@ int SrsFileWriter::writev(const iovec* iov, int iovcnt, ssize_t* pnwrite)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsFileWriter::lseek(off_t offset, int whence, off_t* seeked)
|
||||
{
|
||||
off_t sk = ::lseek(fd, offset, whence);
|
||||
if (sk < 0) {
|
||||
return ERROR_SYSTEM_FILE_SEEK;
|
||||
}
|
||||
|
||||
if (seeked) {
|
||||
*seeked = sk;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SrsFileReader::SrsFileReader()
|
||||
{
|
||||
fd = -1;
|
||||
|
@ -231,7 +244,7 @@ void SrsFileReader::skip(int64_t size)
|
|||
::lseek(fd, (off_t)size, SEEK_CUR);
|
||||
}
|
||||
|
||||
int64_t SrsFileReader::lseek(int64_t offset)
|
||||
int64_t SrsFileReader::seek2(int64_t offset)
|
||||
{
|
||||
return (int64_t)::lseek(fd, (off_t)offset, SEEK_SET);
|
||||
}
|
||||
|
@ -268,3 +281,16 @@ int SrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsFileReader::lseek(off_t offset, int whence, off_t* seeked)
|
||||
{
|
||||
off_t sk = ::lseek(fd, offset, whence);
|
||||
if (sk < 0) {
|
||||
return ERROR_SYSTEM_FILE_SEEK;
|
||||
}
|
||||
|
||||
if (seeked) {
|
||||
*seeked = sk;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
/**
|
||||
* file writer, to write to file.
|
||||
*/
|
||||
class SrsFileWriter : public ISrsWriter
|
||||
class SrsFileWriter : public ISrsWriteSeeker
|
||||
{
|
||||
private:
|
||||
std::string path;
|
||||
|
@ -67,25 +67,19 @@ public:
|
|||
virtual void close();
|
||||
public:
|
||||
virtual bool is_open();
|
||||
virtual void lseek(int64_t offset);
|
||||
virtual void seek2(int64_t offset);
|
||||
virtual int64_t tellg();
|
||||
// Interface ISrsWriteSeeker
|
||||
public:
|
||||
/**
|
||||
* write to file.
|
||||
* @param pnwrite the output nb_write, NULL to ignore.
|
||||
*/
|
||||
virtual int write(void* buf, size_t count, ssize_t* pnwrite);
|
||||
/**
|
||||
* for the HTTP FLV, to writev to improve performance.
|
||||
* @see https://github.com/ossrs/srs/issues/405
|
||||
*/
|
||||
virtual int writev(const iovec* iov, int iovcnt, ssize_t* pnwrite);
|
||||
virtual int lseek(off_t offset, int whence, off_t* seeked);
|
||||
};
|
||||
|
||||
/**
|
||||
* file reader, to read from file.
|
||||
*/
|
||||
class SrsFileReader : public ISrsReader
|
||||
class SrsFileReader : public ISrsReadSeeker
|
||||
{
|
||||
private:
|
||||
std::string path;
|
||||
|
@ -109,14 +103,12 @@ public:
|
|||
virtual bool is_open();
|
||||
virtual int64_t tellg();
|
||||
virtual void skip(int64_t size);
|
||||
virtual int64_t lseek(int64_t offset);
|
||||
virtual int64_t seek2(int64_t offset);
|
||||
virtual int64_t filesize();
|
||||
// Interface ISrsReadSeeker
|
||||
public:
|
||||
/**
|
||||
* read from file.
|
||||
* @param pnread the output nb_read, NULL to ignore.
|
||||
*/
|
||||
virtual int read(void* buf, size_t count, ssize_t* pnread);
|
||||
virtual int lseek(off_t offset, int whence, off_t* seeked);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -949,7 +949,7 @@ int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* p
|
|||
|
||||
// seek to the sequence header start offset.
|
||||
if (av_sequence_offset_start > 0) {
|
||||
reader->lseek(av_sequence_offset_start);
|
||||
reader->seek2(av_sequence_offset_start);
|
||||
*pstart = av_sequence_offset_start;
|
||||
*psize = (int)(av_sequence_offset_end - av_sequence_offset_start);
|
||||
}
|
||||
|
@ -957,7 +957,7 @@ int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* p
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsFlvVodStreamDecoder::lseek(int64_t offset)
|
||||
int SrsFlvVodStreamDecoder::seek2(int64_t offset)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -969,7 +969,7 @@ int SrsFlvVodStreamDecoder::lseek(int64_t offset)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (reader->lseek(offset) < 0) {
|
||||
if (reader->seek2(offset) < 0) {
|
||||
ret = ERROR_SYSTEM_FILE_SEEK;
|
||||
srs_warn("flv fast decoder seek error, "
|
||||
"size=%"PRId64", offset=%"PRId64", ret=%d",
|
||||
|
|
|
@ -597,7 +597,7 @@ public:
|
|||
/**
|
||||
* for start offset, seed to this position and response flv stream.
|
||||
*/
|
||||
virtual int lseek(int64_t offset);
|
||||
virtual int seek2(int64_t offset);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,22 @@ ISrsReader::~ISrsReader()
|
|||
{
|
||||
}
|
||||
|
||||
ISrsSeeker::ISrsSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsSeeker::~ISrsSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsReadSeeker::ISrsReadSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsReadSeeker::~ISrsReadSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsStreamWriter::ISrsStreamWriter()
|
||||
{
|
||||
}
|
||||
|
@ -55,3 +71,11 @@ ISrsWriter::~ISrsWriter()
|
|||
{
|
||||
}
|
||||
|
||||
ISrsWriteSeeker::ISrsWriteSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsWriteSeeker::~ISrsWriteSeeker()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,37 @@ public:
|
|||
virtual int read(void* buf, size_t size, ssize_t* nread) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The seeker to seek with a device.
|
||||
*/
|
||||
class ISrsSeeker
|
||||
{
|
||||
public:
|
||||
ISrsSeeker();
|
||||
virtual ~ISrsSeeker();
|
||||
public:
|
||||
/**
|
||||
* The lseek() function repositions the offset of the file descriptor fildes to the argument offset, according to the
|
||||
* directive whence. lseek() repositions the file pointer fildes as follows:
|
||||
* If whence is SEEK_SET, the offset is set to offset bytes.
|
||||
* If whence is SEEK_CUR, the offset is set to its current location plus offset bytes.
|
||||
* If whence is SEEK_END, the offset is set to the size of the file plus offset bytes.
|
||||
* @param seeked Upon successful completion, lseek() returns the resulting offset location as measured in bytes from
|
||||
* the beginning of the file. NULL to ignore.
|
||||
*/
|
||||
virtual int lseek(off_t offset, int whence, off_t* seeked) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The reader and seeker.
|
||||
*/
|
||||
class ISrsReadSeeker : virtual public ISrsReader, virtual public ISrsSeeker
|
||||
{
|
||||
public:
|
||||
ISrsReadSeeker();
|
||||
virtual ~ISrsReadSeeker();
|
||||
};
|
||||
|
||||
/**
|
||||
* The writer to write stream data to channel.
|
||||
*/
|
||||
|
@ -79,6 +110,8 @@ public:
|
|||
/**
|
||||
* write iov over writer.
|
||||
* @nwrite the actual written bytes. NULL to ignore.
|
||||
* @remark for the HTTP FLV, to writev to improve performance.
|
||||
* @see https://github.com/ossrs/srs/issues/405
|
||||
*/
|
||||
virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite) = 0;
|
||||
};
|
||||
|
@ -93,5 +126,15 @@ public:
|
|||
virtual ~ISrsWriter();
|
||||
};
|
||||
|
||||
/**
|
||||
* The writer and seeker.
|
||||
*/
|
||||
class ISrsWriteSeeker : virtual public ISrsWriter, virtual public ISrsSeeker
|
||||
{
|
||||
public:
|
||||
ISrsWriteSeeker();
|
||||
virtual ~ISrsWriteSeeker();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2959,7 +2959,8 @@ int SrsMp4UserDataBox::decode_header(SrsBuffer* buf)
|
|||
|
||||
SrsMp4Decoder::SrsMp4Decoder()
|
||||
{
|
||||
reader = NULL;
|
||||
rsio = NULL;
|
||||
brand = SrsMp4BoxBrandForbidden;
|
||||
buf = new char[SRS_MP4_BUF_SIZE];
|
||||
stream = new SrsSimpleStream();
|
||||
}
|
||||
|
@ -2970,66 +2971,83 @@ SrsMp4Decoder::~SrsMp4Decoder()
|
|||
srs_freep(stream);
|
||||
}
|
||||
|
||||
int SrsMp4Decoder::initialize(ISrsReader* r)
|
||||
int SrsMp4Decoder::initialize(ISrsReadSeeker* rs)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
srs_assert(r);
|
||||
reader = r;
|
||||
srs_assert(rs);
|
||||
rsio = rs;
|
||||
|
||||
// File Type Box (ftyp)
|
||||
if (true) {
|
||||
SrsMp4Box* box = NULL;
|
||||
SrsAutoFree(SrsMp4Box, box);
|
||||
// For mdat before moov, we must reset the io.
|
||||
off_t offset = -1;
|
||||
|
||||
if ((ret = load_next_box(&box, SrsMp4BoxTypeFTYP)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
SrsMp4FileTypeBox* ftyp = dynamic_cast<SrsMp4FileTypeBox*>(box);
|
||||
|
||||
bool legal_brand = false;
|
||||
static SrsMp4BoxBrand legal_brands[] = {
|
||||
SrsMp4BoxBrandISOM, SrsMp4BoxBrandISO2, SrsMp4BoxBrandAVC1, SrsMp4BoxBrandMP41
|
||||
};
|
||||
for (int i = 0; i < sizeof(legal_brands)/sizeof(SrsMp4BoxBrand); i++) {
|
||||
if (ftyp->major_brand == legal_brands[i]) {
|
||||
legal_brand = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!legal_brand) {
|
||||
ret = ERROR_MP4_BOX_ILLEGAL_BRAND;
|
||||
srs_error("MP4 brand is illegal, brand=%d. ret=%d", ftyp->major_brand, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Media Data Box (mdat) or Movie Box (moov)
|
||||
SrsMp4Box* box = NULL;
|
||||
SrsAutoFree(SrsMp4Box, box);
|
||||
while (true) {
|
||||
SrsMp4Box* box = NULL;
|
||||
|
||||
if ((ret = load_next_box(&box, 0)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!box->is_mdat() && !box->is_moov()) {
|
||||
srs_freep(box);
|
||||
continue;
|
||||
if (box->is_ftyp()) {
|
||||
SrsMp4FileTypeBox* ftyp = dynamic_cast<SrsMp4FileTypeBox*>(box);
|
||||
if ((ret = parse_ftyp(ftyp)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
} else if (box->is_mdat()) {
|
||||
off_t cur = 0;
|
||||
if ((ret = rsio->lseek(0, SEEK_CUR, &cur)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
offset = off_t(cur - box->sz());
|
||||
} else if (box->is_moov()) {
|
||||
SrsMp4MovieBox* moov = dynamic_cast<SrsMp4MovieBox*>(box);
|
||||
if ((ret = parse_moov(moov)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
srs_freep(box);
|
||||
}
|
||||
|
||||
// Only support non-seek mp4, that is, mdat should never before moov.
|
||||
// @see https://github.com/ossrs/srs/issues/738#issuecomment-276343669
|
||||
if (box->is_mdat()) {
|
||||
ret = ERROR_MP4_NOT_NON_SEEKABLE;
|
||||
srs_error("MP4 is not non-seekable. ret=%d", ret);
|
||||
if (brand == SrsMp4BoxBrandForbidden) {
|
||||
ret = ERROR_MP4_BOX_ILLEGAL_SCHEMA;
|
||||
srs_error("MP4 missing ftyp. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Parse the Movie Header Box(moov).
|
||||
SrsMp4MovieBox* moov = dynamic_cast<SrsMp4MovieBox*>(box);
|
||||
return parse_moov(moov);
|
||||
// Reset the io to the start to reparse the general MP4.
|
||||
if (offset >= 0) {
|
||||
return rsio->lseek(offset, SEEK_SET, NULL);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsMp4Decoder::parse_ftyp(SrsMp4FileTypeBox* ftyp)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// File Type Box (ftyp)
|
||||
bool legal_brand = false;
|
||||
static SrsMp4BoxBrand legal_brands[] = {
|
||||
SrsMp4BoxBrandISOM, SrsMp4BoxBrandISO2, SrsMp4BoxBrandAVC1, SrsMp4BoxBrandMP41
|
||||
};
|
||||
for (int i = 0; i < sizeof(legal_brands)/sizeof(SrsMp4BoxBrand); i++) {
|
||||
if (ftyp->major_brand == legal_brands[i]) {
|
||||
legal_brand = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!legal_brand) {
|
||||
ret = ERROR_MP4_BOX_ILLEGAL_BRAND;
|
||||
srs_error("MP4 brand is illegal, brand=%d. ret=%d", ftyp->major_brand, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
brand = ftyp->major_brand;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov)
|
||||
|
@ -3110,7 +3128,7 @@ int SrsMp4Decoder::do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_typ
|
|||
uint64_t required = box? box->sz():4;
|
||||
while (stream->length() < required) {
|
||||
ssize_t nread;
|
||||
if ((ret = reader->read(buf, SRS_MP4_BUF_SIZE, &nread)) != ERROR_SUCCESS) {
|
||||
if ((ret = rsio->read(buf, SRS_MP4_BUF_SIZE, &nread)) != ERROR_SUCCESS) {
|
||||
srs_error("MP4 load failed, nread=%d, required=%d. ret=%d", nread, required, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3131,17 +3149,35 @@ int SrsMp4Decoder::do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_typ
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Decode util we can demux the whole box.
|
||||
if (!buffer->require((int)box->sz())) {
|
||||
continue;
|
||||
}
|
||||
// For mdat, skip the content.
|
||||
if (box->is_mdat()) {
|
||||
// Never load the mdat box content, instead we skip it, for it's too large.
|
||||
// The demuxer use seeker to read sample one by one.
|
||||
if (box->is_mdat()) {
|
||||
int offset = (int)(box->sz() - stream->length());
|
||||
if (offset < 0) {
|
||||
stream->erase(stream->length() + offset);
|
||||
} else {
|
||||
stream->erase(stream->length());
|
||||
}
|
||||
if (offset > 0 && (ret = rsio->lseek(offset, SEEK_CUR, NULL)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Util we can demux the whole box.
|
||||
if (!buffer->require((int)box->sz())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!required_box_type || box->type == required_box_type) {
|
||||
ret = box->decode(buffer);
|
||||
}
|
||||
// Decode the matched box or any box is matched.
|
||||
if (!required_box_type || box->type == required_box_type) {
|
||||
ret = box->decode(buffer);
|
||||
}
|
||||
|
||||
// Remove the consumed bytes.
|
||||
stream->erase((int)box->sz());
|
||||
// Remove the consumed bytes.
|
||||
stream->erase((int)box->sz());
|
||||
}
|
||||
|
||||
if (ret != ERROR_SUCCESS) {
|
||||
srs_freep(box);
|
||||
|
|
|
@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class ISrsReader;
|
||||
class ISrsReadSeeker;
|
||||
class SrsMp4TrackBox;
|
||||
class SrsMp4MediaBox;
|
||||
class SrsSimpleStream;
|
||||
|
@ -1342,8 +1342,12 @@ protected:
|
|||
class SrsMp4Decoder
|
||||
{
|
||||
private:
|
||||
// Underlayer reader.
|
||||
ISrsReader* reader;
|
||||
// The major brand of decoder, parse from ftyp.
|
||||
SrsMp4BoxBrand brand;
|
||||
private:
|
||||
// Underlayer reader and seeker.
|
||||
// @remark The demuxer must use seeker for general MP4 to seek the moov.
|
||||
ISrsReadSeeker* rsio;
|
||||
// The stream used to demux the boxes.
|
||||
// TODO: FIXME: refine for performance issue.
|
||||
SrsSimpleStream* stream;
|
||||
|
@ -1358,13 +1362,15 @@ public:
|
|||
* @param r The underlayer io reader, user must manage it for decoder never open/free it,
|
||||
* the decoder just read data from the reader.
|
||||
*/
|
||||
virtual int initialize(ISrsReader* r);
|
||||
virtual int initialize(ISrsReadSeeker* rs);
|
||||
private:
|
||||
virtual int parse_moov(SrsMp4MovieBox* box);
|
||||
virtual int parse_ftyp(SrsMp4FileTypeBox* ftyp);
|
||||
virtual int parse_moov(SrsMp4MovieBox* moov);
|
||||
private:
|
||||
// Load the next box from reader.
|
||||
// @param required_box_type The box type required, 0 for any box.
|
||||
virtual int load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type);
|
||||
// @remark Never load the mdat box content, for it's too large.
|
||||
virtual int do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type);
|
||||
};
|
||||
|
||||
|
|
|
@ -1755,7 +1755,7 @@ int64_t srs_flv_tellg(srs_flv_t flv)
|
|||
void srs_flv_lseek(srs_flv_t flv, int64_t offset)
|
||||
{
|
||||
FlvContext* context = (FlvContext*)flv;
|
||||
context->reader.lseek(offset);
|
||||
context->reader.seek2(offset);
|
||||
}
|
||||
|
||||
srs_bool srs_flv_is_eof(int error_code)
|
||||
|
|
|
@ -131,7 +131,7 @@ void MockSrsFileReader::skip(int64_t _size)
|
|||
offset += _size;
|
||||
}
|
||||
|
||||
int64_t MockSrsFileReader::lseek(int64_t _offset)
|
||||
int64_t MockSrsFileReader::seek2(int64_t _offset)
|
||||
{
|
||||
offset = (int)_offset;
|
||||
return offset;
|
||||
|
@ -163,6 +163,12 @@ int MockSrsFileReader::read(void* buf, size_t count, ssize_t* pnread)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int MockSrsFileReader::lseek(off_t _offset, int /*whence*/, off_t* /*seeked*/)
|
||||
{
|
||||
offset = (int)_offset;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void MockSrsFileReader::mock_append_data(const char* _data, int _size)
|
||||
{
|
||||
int s = srs_min(MAX_MOCK_DATA_SIZE - offset, _size);
|
||||
|
@ -952,10 +958,10 @@ VOID TEST(KernelFlvTest, FlvVSDecoderSeek)
|
|||
fs.mock_append_data(tag_header, 11);
|
||||
EXPECT_TRUE(11 == fs.offset);
|
||||
|
||||
EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(0));
|
||||
EXPECT_TRUE(ERROR_SUCCESS == dec.seek2(0));
|
||||
EXPECT_TRUE(0 == fs.offset);
|
||||
|
||||
EXPECT_TRUE(ERROR_SUCCESS == dec.lseek(5));
|
||||
EXPECT_TRUE(ERROR_SUCCESS == dec.seek2(5));
|
||||
EXPECT_TRUE(5 == fs.offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,10 +81,11 @@ public:
|
|||
virtual bool is_open();
|
||||
virtual int64_t tellg();
|
||||
virtual void skip(int64_t size);
|
||||
virtual int64_t lseek(int64_t offset);
|
||||
virtual int64_t seek2(int64_t offset);
|
||||
virtual int64_t filesize();
|
||||
public:
|
||||
virtual int read(void* buf, size_t count, ssize_t* pnread);
|
||||
virtual int lseek(off_t offset, int whence, off_t* seeked);
|
||||
// for mock
|
||||
public:
|
||||
// append data to current offset, modify the offset and size.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue