Performance improvements to mov_reader
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13209 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -231,35 +231,39 @@ bool MOVFileReader::IsAudio(uint32 stream_index)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 MOVFileReader::getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID)
|
||||
{
|
||||
// Find Track
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
||||
if (aAtomBase) {
|
||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||
|
||||
return aTrakAtom->getFirstSampleInChunk(pChunkID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 MOVFileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
|
||||
{
|
||||
// Find Track
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
||||
if (aAtomBase) {
|
||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
uint32 ChunkNo = 1;
|
||||
|
||||
if (IsAudio(stream_index)) {
|
||||
uint32 OffsetInChunk;
|
||||
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||
|
||||
// Go back to first Sample in Chunk
|
||||
while (aTrakAtom->getChunkForSample(SampleNo-1, &OffsetInChunk) == ChunkNo) {
|
||||
SampleNo--;
|
||||
}
|
||||
|
||||
// Add up all sample sizes in chunk
|
||||
while (aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk) == ChunkNo) {
|
||||
SampleNo++;
|
||||
}
|
||||
return SampleNo ;
|
||||
ChunkNo = pFrameNo;
|
||||
}
|
||||
|
||||
if (IsVideo(stream_index)) {
|
||||
return 1;
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
|
||||
uint32 OffsetInChunk;
|
||||
ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||
}
|
||||
|
||||
return aTrakAtom->getNoSamplesInChunk(ChunkNo);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -267,54 +271,47 @@ uint32 MOVFileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
|
||||
|
||||
uint64 MOVFileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
|
||||
{
|
||||
// BStopWatch *watch;
|
||||
|
||||
// Find Track
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
||||
if (aAtomBase) {
|
||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||
|
||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||
// Convert Frame to Track Time
|
||||
// uint32 FrameTime = aTrakAtom->getTimeForFrame(pFrameNo, getMovieTimeScale());
|
||||
// Get Sample for Frame
|
||||
// watch = new BStopWatch("getSampleForFrame");
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
// delete watch;
|
||||
// Get Chunk For Sample and the offset for the frame within that chunk
|
||||
// watch = new BStopWatch("getChunkForSample");
|
||||
uint32 OffsetInChunk;
|
||||
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||
// delete watch;
|
||||
// Get Offset For Chunk
|
||||
// printf("Stream: %ld Frame %ld %ld <%ld/%ld> (",stream_index, pFrameNo, SampleNo, ChunkNo, OffsetInChunk);
|
||||
// watch = new BStopWatch("getOffsetForChunk");
|
||||
uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo);
|
||||
// delete watch;
|
||||
// printf("Frame %ld {%lld} <%ld/%ld> (",pFrameNo, OffsetNo, ChunkNo, OffsetInChunk);
|
||||
if (IsAudio(stream_index)) {
|
||||
// FrameNo is really chunk No for audio
|
||||
uint32 ChunkNo = pFrameNo;
|
||||
|
||||
if (ChunkNo != 0) {
|
||||
uint32 SampleSize;
|
||||
// Adjust the Offset for the Offset in the chunk
|
||||
// watch = new BStopWatch("getSizeForSample");
|
||||
if (aTrakAtom->IsSingleSampleSize()) {
|
||||
SampleSize = aTrakAtom->getSizeForSample(SampleNo);
|
||||
OffsetNo = OffsetNo + (OffsetInChunk * SampleSize);
|
||||
} else {
|
||||
// This is bad news performance wise
|
||||
for (uint32 i=1;i<=OffsetInChunk;i++) {
|
||||
SampleSize = aTrakAtom->getSizeForSample(SampleNo-i);
|
||||
// printf(" %ld ",SampleSize);
|
||||
OffsetNo = OffsetNo + SampleSize;
|
||||
// Get Offset For Chunk
|
||||
return aTrakAtom->getOffsetForChunk(ChunkNo);
|
||||
}
|
||||
|
||||
if (IsVideo(stream_index)) {
|
||||
|
||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||
// Get Sample for Frame
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
// Get Chunk For Sample and the offset for the frame within that chunk
|
||||
uint32 OffsetInChunk;
|
||||
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||
// Get Offset For Chunk
|
||||
uint64 OffsetNo = aTrakAtom->getOffsetForChunk(ChunkNo);
|
||||
|
||||
if (ChunkNo != 0) {
|
||||
uint32 SampleSize;
|
||||
// Adjust the Offset for the Offset in the chunk
|
||||
if (aTrakAtom->IsSingleSampleSize()) {
|
||||
SampleSize = aTrakAtom->getSizeForSample(SampleNo);
|
||||
OffsetNo = OffsetNo + (OffsetInChunk * SampleSize);
|
||||
} else {
|
||||
// This is bad news performance wise
|
||||
for (uint32 i=1;i<=OffsetInChunk;i++) {
|
||||
SampleSize = aTrakAtom->getSizeForSample(SampleNo-i);
|
||||
OffsetNo = OffsetNo + SampleSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
// printf(") %lld\n",OffsetNo);
|
||||
// delete watch;
|
||||
}
|
||||
// printf("%ld:%ld:%ld:%lld\n",pFrameNo, SampleNo, ChunkNo, OffsetNo);
|
||||
// printf("\n");
|
||||
|
||||
return OffsetNo;
|
||||
return OffsetNo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,33 +492,32 @@ uint32 MOVFileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo)
|
||||
if (aAtomBase) {
|
||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||
|
||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
if (IsAudio(stream_index)) {
|
||||
|
||||
if (IsAudio(stream_index)) {
|
||||
uint32 OffsetInChunk;
|
||||
uint32 ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||
|
||||
// Go back to first Sample in Chunk
|
||||
while (aTrakAtom->getChunkForSample(SampleNo-1, &OffsetInChunk) == ChunkNo) {
|
||||
SampleNo--;
|
||||
}
|
||||
|
||||
// Add up all sample sizes in chunk
|
||||
uint32 ChunkSize = 0;
|
||||
// We read audio in chunk by chunk so chunk size is chunk size
|
||||
uint32 ChunkNo = pFrameNo;
|
||||
|
||||
while (aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk) == ChunkNo) {
|
||||
ChunkSize += aTrakAtom->getSizeForSample(SampleNo);
|
||||
SampleNo++;
|
||||
}
|
||||
return ChunkSize;
|
||||
// Get first sample in chunk
|
||||
uint32 SampleNo = aTrakAtom->getFirstSampleInChunk(ChunkNo);
|
||||
|
||||
// Add up all sample sizes in chunk
|
||||
uint32 ChunkSize = 0;
|
||||
for (uint32 i=0;i<aTrakAtom->getNoSamplesInChunk(ChunkNo);i++) {
|
||||
ChunkSize += aTrakAtom->getSizeForSample(SampleNo);
|
||||
SampleNo++;
|
||||
}
|
||||
|
||||
return ChunkSize;
|
||||
}
|
||||
|
||||
if (IsVideo(stream_index)) {
|
||||
if (IsVideo(stream_index)) {
|
||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||
// We read video in Sample by Sample so chunk size is Sample Size
|
||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||
return aTrakAtom->getSizeForSample(SampleNo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -550,9 +546,7 @@ bool MOVFileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t
|
||||
*keyframe = IsKeyFrame(stream_index, pFrameNo);
|
||||
}
|
||||
|
||||
return ((*start > 0) && (*size > 0));
|
||||
|
||||
// return !(IsEndOfFile(*start) || *start < 0);
|
||||
return ((*start > 0) && (*size > 0) && !(IsEndOfFile(*start)));
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
||||
@@ -93,6 +93,7 @@ public:
|
||||
bool IsAudio(uint32 stream_index);
|
||||
|
||||
uint32 getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo);
|
||||
uint32 getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID);
|
||||
|
||||
uint64 getOffsetForFrame(uint32 stream_index, uint32 pFrameNo);
|
||||
uint32 getChunkSize(uint32 stream_index, uint32 pFrameNo);
|
||||
|
||||
@@ -528,6 +528,7 @@ SampleToChunk *aSampleToChunk;
|
||||
}
|
||||
|
||||
theSampleToChunkArray[i] = aSampleToChunk;
|
||||
// printf("%ld/%ld/%ld\n",aSampleToChunk->FirstChunk,aSampleToChunk->SamplesPerChunk,aSampleToChunk->TotalPrevFrames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,6 +537,30 @@ char *STSCAtom::OnGetAtomName()
|
||||
return "Sample to Chunk Atom";
|
||||
}
|
||||
|
||||
uint32 STSCAtom::getNoSamplesInChunk(uint32 pChunkID)
|
||||
{
|
||||
for (uint32 i=0;i<theHeader.NoEntries;i++) {
|
||||
if (theSampleToChunkArray[i]->FirstChunk > pChunkID) {
|
||||
return theSampleToChunkArray[i-1]->SamplesPerChunk;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 STSCAtom::getFirstSampleInChunk(uint32 pChunkID)
|
||||
{
|
||||
for (uint32 i=0;i<theHeader.NoEntries;i++) {
|
||||
if (theSampleToChunkArray[i]->FirstChunk > pChunkID) {
|
||||
uint32 Diff = pChunkID - theSampleToChunkArray[i-1]->FirstChunk;
|
||||
uint32 pSampleNo = (Diff * theSampleToChunkArray[i-1]->SamplesPerChunk) + theSampleToChunkArray[i-1]->TotalPrevFrames;
|
||||
return pSampleNo;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 STSCAtom::getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk)
|
||||
{
|
||||
uint32 ChunkID = 0;
|
||||
|
||||
@@ -186,6 +186,8 @@ public:
|
||||
char *OnGetAtomName();
|
||||
|
||||
uint32 getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk);
|
||||
uint32 getFirstSampleInChunk(uint32 pChunkID);
|
||||
uint32 getNoSamplesInChunk(uint32 pChunkID);
|
||||
private:
|
||||
array_header theHeader;
|
||||
SampleToChunkArray theSampleToChunkArray;
|
||||
@@ -353,8 +355,10 @@ public:
|
||||
uint32 getSampleForTime(uint32 pTime);
|
||||
uint32 getSampleForFrame(uint32 pFrame);
|
||||
uint32 getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk);
|
||||
uint64 getOffsetForChunk(uint32 pChunk);
|
||||
uint64 getOffsetForChunk(uint32 pChunkID);
|
||||
uint32 getFirstSampleInChunk(uint32 pChunkID);
|
||||
uint32 getSizeForSample(uint32 pSample);
|
||||
uint32 getNoSamplesInChunk(uint32 pChunkID);
|
||||
bool IsSyncSample(uint32 pSampleNo);
|
||||
bool IsSingleSampleSize();
|
||||
|
||||
|
||||
@@ -154,6 +154,17 @@ uint32 TRAKAtom::getChunkForSample(uint32 pSample, uint32 *pOffsetInChunk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 TRAKAtom::getNoSamplesInChunk(uint32 pChunkID)
|
||||
{
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('stsc'),0);
|
||||
|
||||
if (aAtomBase) {
|
||||
return (dynamic_cast<STSCAtom *>(aAtomBase))->getNoSamplesInChunk(pChunkID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 TRAKAtom::getSizeForSample(uint32 pSample)
|
||||
{
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('stsz'),0);
|
||||
@@ -165,17 +176,29 @@ uint32 TRAKAtom::getSizeForSample(uint32 pSample)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 TRAKAtom::getOffsetForChunk(uint32 pChunk)
|
||||
uint64 TRAKAtom::getOffsetForChunk(uint32 pChunkID)
|
||||
{
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('stco'),0);
|
||||
|
||||
if (aAtomBase) {
|
||||
return (dynamic_cast<STCOAtom *>(aAtomBase))->getOffsetForChunk(pChunk);
|
||||
return (dynamic_cast<STCOAtom *>(aAtomBase))->getOffsetForChunk(pChunkID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 TRAKAtom::getFirstSampleInChunk(uint32 pChunkID)
|
||||
{
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('stsc'),0);
|
||||
|
||||
if (aAtomBase) {
|
||||
return (dynamic_cast<STSCAtom *>(aAtomBase))->getFirstSampleInChunk(pChunkID);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool TRAKAtom::IsSyncSample(uint32 pSampleNo)
|
||||
{
|
||||
AtomBase *aAtomBase = GetChildAtom(uint32('stss'),0);
|
||||
|
||||
@@ -54,16 +54,19 @@ struct mov_cookie
|
||||
|
||||
bool audio;
|
||||
|
||||
// audio only:
|
||||
int64 byte_pos;
|
||||
// audio only:
|
||||
off_t byte_pos;
|
||||
uint32 chunk_pos;
|
||||
uint32 bytes_per_sec_rate;
|
||||
uint32 bytes_per_sec_scale;
|
||||
|
||||
// video only:
|
||||
uint32 line_count;
|
||||
|
||||
// Common
|
||||
uint32 frame_pos;
|
||||
uint32 frames_per_sec_rate;
|
||||
uint32 frames_per_sec_scale;
|
||||
uint32 line_count;
|
||||
};
|
||||
|
||||
|
||||
@@ -138,6 +141,7 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
||||
cookie->stream = streamNumber;
|
||||
cookie->buffer = 0;
|
||||
cookie->buffer_size = 0;
|
||||
cookie->frame_pos = 0;
|
||||
|
||||
BMediaFormats formats;
|
||||
media_format *format = &cookie->format;
|
||||
@@ -188,10 +192,10 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
||||
*/
|
||||
cookie->audio = true;
|
||||
cookie->byte_pos = 0;
|
||||
cookie->frame_pos = 0;
|
||||
cookie->chunk_pos = 1;
|
||||
|
||||
if (stream_header->scale && stream_header->rate && stream_header->sample_size) {
|
||||
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size;
|
||||
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size * audio_format->NoOfChannels / 8;
|
||||
cookie->bytes_per_sec_scale = stream_header->scale;
|
||||
cookie->frames_per_sec_rate = stream_header->rate;
|
||||
cookie->frames_per_sec_scale = stream_header->scale;
|
||||
@@ -202,9 +206,11 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
||||
cookie->frames_per_sec_rate = audio_format->SampleSize;
|
||||
cookie->frames_per_sec_scale = 1;
|
||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using avg_bytes_per_sec)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||
} else if (stream_header->rate) {
|
||||
cookie->bytes_per_sec_rate = stream_header->rate;
|
||||
} else if (stream_header->rate && stream_header->sample_size) {
|
||||
cookie->bytes_per_sec_rate = stream_header->rate * stream_header->sample_size * audio_format->NoOfChannels / 8;
|
||||
cookie->bytes_per_sec_scale = 1;
|
||||
cookie->frames_per_sec_rate = stream_header->sample_size;
|
||||
cookie->frames_per_sec_scale = 1;
|
||||
TRACE("bytes_per_sec_rate %ld, bytes_per_sec_scale %ld (using rate)\n", cookie->bytes_per_sec_rate, cookie->bytes_per_sec_scale);
|
||||
} else {
|
||||
cookie->frames_per_sec_rate = 16000;
|
||||
@@ -324,7 +330,6 @@ movReader::AllocateCookie(int32 streamNumber, void **_cookie)
|
||||
}
|
||||
|
||||
cookie->audio = false;
|
||||
cookie->frame_pos = 0;
|
||||
cookie->line_count = theFileReader->MovMainHeader()->height;
|
||||
|
||||
if (stream_header->scale && stream_header->rate) {
|
||||
@@ -458,8 +463,14 @@ movReader::GetNextChunk(void *_cookie,
|
||||
mov_cookie *cookie = (mov_cookie *)_cookie;
|
||||
|
||||
int64 start; uint32 size; bool keyframe;
|
||||
if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, &start, &size, &keyframe))
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
|
||||
if (cookie->audio) {
|
||||
if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->chunk_pos, &start, &size, &keyframe))
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
} else {
|
||||
if (!theFileReader->GetNextChunkInfo(cookie->stream, cookie->frame_pos, &start, &size, &keyframe))
|
||||
return B_LAST_BUFFER_ERROR;
|
||||
}
|
||||
|
||||
if (cookie->buffer_size < size) {
|
||||
delete [] cookie->buffer;
|
||||
@@ -468,20 +479,22 @@ movReader::GetNextChunk(void *_cookie,
|
||||
}
|
||||
|
||||
if (cookie->audio) {
|
||||
TRACE("Audio stream %d: frame %ld start %lld Size %ld key %d\n",cookie->stream, cookie->frame_pos, start, size, keyframe);
|
||||
mediaHeader->start_time = (cookie->byte_pos * 1000000LL * (int64)cookie->bytes_per_sec_scale) / cookie->bytes_per_sec_rate;
|
||||
TRACE("Audio stream %d: chunk %ld expected start %lld Size %ld key %d\n",cookie->stream, cookie->chunk_pos, start, size, keyframe);
|
||||
mediaHeader->type = B_MEDIA_ENCODED_AUDIO;
|
||||
mediaHeader->u.encoded_audio.buffer_flags = keyframe ? B_MEDIA_KEY_FRAME : 0;
|
||||
|
||||
// This will only work with raw audio I think.
|
||||
mediaHeader->start_time = (cookie->byte_pos * 1000000L * cookie->bytes_per_sec_scale) / cookie->bytes_per_sec_rate;
|
||||
TRACE("Audio - Frames in Chunk %ld / Actual Start Time %Ld using byte_pos\n",theFileReader->getNoFramesInChunk(cookie->stream,cookie->chunk_pos),mediaHeader->start_time);
|
||||
|
||||
// Should be frame_pos += frames per chunk
|
||||
// We should find the current frame position (ie first frame in chunk) then compute using fps
|
||||
cookie->frame_pos = theFileReader->getFirstFrameInChunk(cookie->stream,cookie->chunk_pos);
|
||||
mediaHeader->start_time = (cookie->frame_pos * 1000000LL * (int64)cookie->frames_per_sec_scale) / cookie->frames_per_sec_rate;
|
||||
TRACE("Audio - Frames in Chunk %ld / Actual Start Time %Ld using frame_no %ld\n",theFileReader->getNoFramesInChunk(cookie->stream,cookie->chunk_pos),mediaHeader->start_time, cookie->frame_pos);
|
||||
|
||||
cookie->byte_pos += size;
|
||||
if ((int64)cookie->frames_per_sec_scale > 0) {
|
||||
cookie->frame_pos = ((mediaHeader->start_time * cookie->frames_per_sec_rate) / (int64)cookie->frames_per_sec_scale) / 1000000LL;
|
||||
} else {
|
||||
cookie->frame_pos = 0;
|
||||
}
|
||||
// cookie->frame_pos += theFileReader->getNoFramesInChunk(cookie->stream,cookie->frame_pos);
|
||||
// cookie->frame_pos += 2205;
|
||||
// frame_pos is chunk No for audio
|
||||
cookie->chunk_pos++;
|
||||
} else {
|
||||
TRACE("Video stream %d: frame %ld start %lld Size %ld key %d\n",cookie->stream, cookie->frame_pos, start, size, keyframe);
|
||||
mediaHeader->start_time = (cookie->frame_pos * 1000000LL * (int64)cookie->frames_per_sec_scale) / cookie->frames_per_sec_rate;
|
||||
@@ -490,7 +503,7 @@ movReader::GetNextChunk(void *_cookie,
|
||||
mediaHeader->u.encoded_video.first_active_line = 0;
|
||||
mediaHeader->u.encoded_video.line_count = cookie->line_count;
|
||||
|
||||
cookie->frame_pos += 1;
|
||||
cookie->frame_pos++;
|
||||
}
|
||||
|
||||
TRACE("stream %d: start_time %.6f\n", cookie->stream, mediaHeader->start_time / 1000000.0);
|
||||
|
||||
Reference in New Issue
Block a user