changes for aac decoder
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24229 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -275,15 +275,25 @@ MP4FileReader::getVideoFrameCount(uint32 streamIndex)
|
|||||||
uint32
|
uint32
|
||||||
MP4FileReader::getAudioFrameCount(uint32 streamIndex)
|
MP4FileReader::getAudioFrameCount(uint32 streamIndex)
|
||||||
{
|
{
|
||||||
if (IsAudio(streamIndex)) {
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex);
|
||||||
return uint32(((getAudioDuration(streamIndex)
|
|
||||||
* AudioFormat(streamIndex)->SampleRate) / 1000000L) + 0.5);
|
if (aAtomBase && dynamic_cast<TRAKAtom *>(aAtomBase)->IsAudio())
|
||||||
}
|
return dynamic_cast<TRAKAtom *>(aAtomBase)->FrameCount();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
MP4FileReader::getAudioChunkCount(uint32 streamIndex)
|
||||||
|
{
|
||||||
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'), streamIndex);
|
||||||
|
|
||||||
|
if (aAtomBase && dynamic_cast<TRAKAtom *>(aAtomBase)->IsAudio())
|
||||||
|
return dynamic_cast<TRAKAtom *>(aAtomBase)->getTotalChunks();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MP4FileReader::IsVideo(uint32 streamIndex)
|
MP4FileReader::IsVideo(uint32 streamIndex)
|
||||||
{
|
{
|
||||||
@@ -329,23 +339,18 @@ MP4FileReader::getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
|
MP4FileReader::getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo)
|
||||||
{
|
{
|
||||||
// Find Track
|
// Find Track
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
uint32 ChunkNo = 1;
|
uint32 ChunkNo = 1;
|
||||||
|
|
||||||
if (IsAudio(stream_index))
|
|
||||||
ChunkNo = pFrameNo;
|
|
||||||
|
|
||||||
if (IsVideo(stream_index)) {
|
|
||||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||||
|
|
||||||
uint32 OffsetInChunk;
|
uint32 OffsetInChunk;
|
||||||
ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
ChunkNo = aTrakAtom->getChunkForSample(SampleNo, &OffsetInChunk);
|
||||||
}
|
|
||||||
|
|
||||||
return aTrakAtom->getNoSamplesInChunk(ChunkNo);
|
return aTrakAtom->getNoSamplesInChunk(ChunkNo);
|
||||||
}
|
}
|
||||||
@@ -355,22 +360,13 @@ MP4FileReader::getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo)
|
|||||||
|
|
||||||
|
|
||||||
uint64
|
uint64
|
||||||
MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
|
MP4FileReader::getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo)
|
||||||
{
|
{
|
||||||
// Find Track
|
// Find Track
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
|
|
||||||
if (IsAudio(stream_index)) {
|
|
||||||
// FrameNo is really chunk No for audio
|
|
||||||
uint32 ChunkNo = pFrameNo;
|
|
||||||
|
|
||||||
// Get Offset For Chunk
|
|
||||||
return aTrakAtom->getOffsetForChunk(ChunkNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsVideo(stream_index)) {
|
|
||||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||||
// Get Sample for Frame
|
// Get Sample for Frame
|
||||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||||
@@ -398,7 +394,6 @@ MP4FileReader::getOffsetForFrame(uint32 stream_index, uint32 pFrameNo)
|
|||||||
return OffsetNo;
|
return OffsetNo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -476,10 +471,10 @@ MP4FileReader::MovMainHeader()
|
|||||||
|
|
||||||
|
|
||||||
const AudioMetaData *
|
const AudioMetaData *
|
||||||
MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
|
MP4FileReader::AudioFormat(uint32 streamIndex, size_t *size)
|
||||||
{
|
{
|
||||||
if (IsAudio(stream_index)) {
|
if (IsAudio(streamIndex)) {
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
|
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
@@ -496,7 +491,7 @@ MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
|
|||||||
theAudio.NoOfChannels = aAudioDescription.theAudioSampleEntry.ChannelCount;
|
theAudio.NoOfChannels = aAudioDescription.theAudioSampleEntry.ChannelCount;
|
||||||
theAudio.SampleSize = aAudioDescription.theAudioSampleEntry.SampleSize;
|
theAudio.SampleSize = aAudioDescription.theAudioSampleEntry.SampleSize;
|
||||||
theAudio.SampleRate = aAudioDescription.theAudioSampleEntry.SampleRate / 65536; // Convert from fixed point decimal to float
|
theAudio.SampleRate = aAudioDescription.theAudioSampleEntry.SampleRate / 65536; // Convert from fixed point decimal to float
|
||||||
theAudio.PacketSize = uint32((theAudio.SampleRate * theAudio.NoOfChannels * theAudio.SampleSize) / 8);
|
theAudio.PacketSize = uint32((theAudio.SampleSize * theAudio.NoOfChannels * 1024) / 8);
|
||||||
|
|
||||||
theAudio.theVOL = aAudioDescription.theVOL;
|
theAudio.theVOL = aAudioDescription.theVOL;
|
||||||
theAudio.VOLSize = aAudioDescription.VOLSize;
|
theAudio.VOLSize = aAudioDescription.VOLSize;
|
||||||
@@ -509,12 +504,11 @@ MP4FileReader::AudioFormat(uint32 stream_index, size_t *size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const VideoMetaData*
|
const VideoMetaData*
|
||||||
MP4FileReader::VideoFormat(uint32 stream_index)
|
MP4FileReader::VideoFormat(uint32 streamIndex)
|
||||||
{
|
{
|
||||||
if (IsVideo(stream_index)) {
|
if (IsVideo(streamIndex)) {
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
|
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
@@ -556,26 +550,26 @@ MP4FileReader::VideoFormat(uint32 stream_index)
|
|||||||
|
|
||||||
|
|
||||||
const mp4_stream_header*
|
const mp4_stream_header*
|
||||||
MP4FileReader::StreamFormat(uint32 stream_index)
|
MP4FileReader::StreamFormat(uint32 streamIndex)
|
||||||
{
|
{
|
||||||
// Fill In a Stream Header
|
// Fill In a Stream Header
|
||||||
theStreamHeader.length = 0;
|
theStreamHeader.length = 0;
|
||||||
|
|
||||||
if (IsActive(stream_index) == false) {
|
if (IsActive(streamIndex) == false) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsVideo(stream_index)) {
|
if (IsVideo(streamIndex)) {
|
||||||
theStreamHeader.rate = uint32(1000000L*VideoFormat(stream_index)->FrameRate);
|
theStreamHeader.rate = uint32(1000000L*VideoFormat(streamIndex)->FrameRate);
|
||||||
theStreamHeader.scale = 1000000L;
|
theStreamHeader.scale = 1000000L;
|
||||||
theStreamHeader.length = getVideoFrameCount(stream_index);
|
theStreamHeader.length = getVideoFrameCount(streamIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAudio(stream_index)) {
|
if (IsAudio(streamIndex)) {
|
||||||
theStreamHeader.rate = uint32(AudioFormat(stream_index)->SampleRate);
|
theStreamHeader.rate = uint32(AudioFormat(streamIndex)->SampleRate);
|
||||||
theStreamHeader.scale = 1;
|
theStreamHeader.scale = 1;
|
||||||
theStreamHeader.length = getAudioFrameCount(stream_index);
|
theStreamHeader.length = getAudioFrameCount(streamIndex);
|
||||||
theStreamHeader.sample_size = AudioFormat(stream_index)->SampleSize;
|
theStreamHeader.sample_size = AudioFormat(streamIndex)->SampleSize;
|
||||||
theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size;
|
theStreamHeader.suggested_buffer_size = theStreamHeader.rate * theStreamHeader.sample_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,38 +578,26 @@ MP4FileReader::StreamFormat(uint32 stream_index)
|
|||||||
|
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
MP4FileReader::getChunkSize(uint32 stream_index, uint32 pFrameNo)
|
MP4FileReader::getChunkSize(uint32 streamIndex, uint32 pFrameNo)
|
||||||
{
|
{
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
|
|
||||||
if (IsAudio(stream_index)) {
|
|
||||||
// We read audio in chunk by chunk so chunk size is chunk size
|
|
||||||
uint32 ChunkNo = pFrameNo;
|
|
||||||
off_t Chunk_Start = aTrakAtom->getOffsetForChunk(ChunkNo);
|
|
||||||
uint32 ChunkSize = theChunkSuperIndex.getChunkSize(stream_index,ChunkNo,Chunk_Start);
|
|
||||||
|
|
||||||
return ChunkSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsVideo(stream_index)) {
|
|
||||||
if (pFrameNo < aTrakAtom->FrameCount()) {
|
if (pFrameNo < aTrakAtom->FrameCount()) {
|
||||||
// We read video in Sample by Sample so we use get Sample Size
|
|
||||||
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
uint32 SampleNo = aTrakAtom->getSampleForFrame(pFrameNo);
|
||||||
return aTrakAtom->getSizeForSample(SampleNo);
|
return aTrakAtom->getSizeForSample(SampleNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo)
|
MP4FileReader::IsKeyFrame(uint32 streamIndex, uint32 pFrameNo)
|
||||||
{
|
{
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
|
|
||||||
@@ -628,14 +610,14 @@ MP4FileReader::IsKeyFrame(uint32 stream_index, uint32 pFrameNo)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo,
|
MP4FileReader::GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo,
|
||||||
off_t *start, uint32 *size, bool *keyframe)
|
off_t *start, uint32 *size, bool *keyframe)
|
||||||
{
|
{
|
||||||
*start = getOffsetForFrame(stream_index, pFrameNo);
|
*start = getOffsetForFrame(streamIndex, pFrameNo);
|
||||||
*size = getChunkSize(stream_index, pFrameNo);
|
*size = getChunkSize(streamIndex, pFrameNo);
|
||||||
|
|
||||||
if ((*start > 0) && (*size > 0)) {
|
if ((*start > 0) && (*size > 0)) {
|
||||||
*keyframe = IsKeyFrame(stream_index, pFrameNo);
|
*keyframe = IsKeyFrame(streamIndex, pFrameNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it.
|
// TODO need a better method for detecting End of Data Note ChunkSize of 0 seems to be it.
|
||||||
@@ -645,9 +627,9 @@ MP4FileReader::GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo,
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MP4FileReader::IsActive(uint32 stream_index)
|
MP4FileReader::IsActive(uint32 streamIndex)
|
||||||
{
|
{
|
||||||
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),stream_index);
|
AtomBase *aAtomBase = GetChildAtom(uint32('trak'),streamIndex);
|
||||||
if (aAtomBase) {
|
if (aAtomBase) {
|
||||||
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
TRAKAtom *aTrakAtom = dynamic_cast<TRAKAtom *>(aAtomBase);
|
||||||
return aTrakAtom->IsActive();
|
return aTrakAtom->IsActive();
|
||||||
|
|||||||
@@ -81,45 +81,47 @@ public:
|
|||||||
// Duration defined by the movie header
|
// Duration defined by the movie header
|
||||||
bigtime_t getMovieDuration();
|
bigtime_t getMovieDuration();
|
||||||
|
|
||||||
// The first video track duration indexed by stream_index
|
// The first video track duration indexed by streamIndex
|
||||||
bigtime_t getVideoDuration(uint32 stream_index);
|
bigtime_t getVideoDuration(uint32 streamIndex);
|
||||||
// the first audio track duration indexed by stream_index
|
// the first audio track duration indexed by streamIndex
|
||||||
bigtime_t getAudioDuration(uint32 stream_index);
|
bigtime_t getAudioDuration(uint32 streamIndex);
|
||||||
// the max of all active audio or video durations
|
// the max of all active audio or video durations
|
||||||
bigtime_t getMaxDuration();
|
bigtime_t getMaxDuration();
|
||||||
|
|
||||||
// The no of frames in the video track indexed by stream_index
|
// The no of frames in the video track indexed by streamIndex
|
||||||
uint32 getVideoFrameCount(uint32 stream_index);
|
// 1 frame = 1 chunk
|
||||||
// The no of frames in the audio track indexed by stream_index
|
uint32 getVideoFrameCount(uint32 streamIndex);
|
||||||
uint32 getAudioFrameCount(uint32 stream_index);
|
// The no of frames in the audio track indexed by streamIndex
|
||||||
|
uint32 getAudioFrameCount(uint32 streamIndex);
|
||||||
|
// The no of chunks in the audio track indexed by streamIndex
|
||||||
|
uint32 getAudioChunkCount(uint32 streamIndex);
|
||||||
// Is stream (track) a video track
|
// Is stream (track) a video track
|
||||||
bool IsVideo(uint32 stream_index);
|
bool IsVideo(uint32 streamIndex);
|
||||||
// Is stream (track) a audio track
|
// Is stream (track) a audio track
|
||||||
bool IsAudio(uint32 stream_index);
|
bool IsAudio(uint32 streamIndex);
|
||||||
|
|
||||||
uint32 getNoFramesInChunk(uint32 stream_index, uint32 pFrameNo);
|
uint32 getNoFramesInChunk(uint32 streamIndex, uint32 pFrameNo);
|
||||||
uint32 getFirstFrameInChunk(uint32 stream_index, uint32 pChunkID);
|
uint32 getFirstFrameInChunk(uint32 streamIndex, uint32 pChunkID);
|
||||||
|
|
||||||
uint64 getOffsetForFrame(uint32 stream_index, uint32 pFrameNo);
|
uint64 getOffsetForFrame(uint32 streamIndex, uint32 pFrameNo);
|
||||||
uint32 getChunkSize(uint32 stream_index, uint32 pFrameNo);
|
uint32 getChunkSize(uint32 streamIndex, uint32 pFrameNo);
|
||||||
bool IsKeyFrame(uint32 stream_index, uint32 pFrameNo);
|
bool IsKeyFrame(uint32 streamIndex, uint32 pFrameNo);
|
||||||
|
|
||||||
status_t ParseFile();
|
status_t ParseFile();
|
||||||
BPositionIO *Source() {return theStream;};
|
BPositionIO *Source() {return theStream;};
|
||||||
|
|
||||||
bool IsActive(uint32 stream_index);
|
bool IsActive(uint32 streamIndex);
|
||||||
|
|
||||||
bool GetNextChunkInfo(uint32 stream_index, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe);
|
bool GetNextChunkInfo(uint32 streamIndex, uint32 pFrameNo, off_t *start, uint32 *size, bool *keyframe);
|
||||||
|
|
||||||
// Return all Audio Meta Data
|
// Return all Audio Meta Data
|
||||||
const AudioMetaData *AudioFormat(uint32 stream_index, size_t *size = 0);
|
const AudioMetaData *AudioFormat(uint32 streamIndex, size_t *size = 0);
|
||||||
// Return all Video Meta Data
|
// Return all Video Meta Data
|
||||||
const VideoMetaData *VideoFormat(uint32 stream_index);
|
const VideoMetaData *VideoFormat(uint32 streamIndex);
|
||||||
|
|
||||||
// XXX these need work
|
// XXX these need work
|
||||||
const mp4_main_header *MovMainHeader();
|
const mp4_main_header *MovMainHeader();
|
||||||
const mp4_stream_header *StreamFormat(uint32 stream_index);
|
const mp4_stream_header *StreamFormat(uint32 streamIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ void MOOVAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *MOOVAtom::OnGetAtomName()
|
char *MOOVAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Movie";
|
return "MPEG-4 Movie";
|
||||||
}
|
}
|
||||||
|
|
||||||
CMOVAtom::CMOVAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
|
CMOVAtom::CMOVAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
|
||||||
@@ -322,7 +322,7 @@ void CMOVAtom::OnChildProcessingComplete()
|
|||||||
|
|
||||||
char *CMOVAtom::OnGetAtomName()
|
char *CMOVAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Compressed Quicktime Movie";
|
return "Compressed MPEG-4 Movie";
|
||||||
}
|
}
|
||||||
|
|
||||||
DCOMAtom::DCOMAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
|
DCOMAtom::DCOMAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
|
||||||
@@ -438,7 +438,7 @@ void MVHDAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *MVHDAtom::OnGetAtomName()
|
char *MVHDAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Movie Header";
|
return "MPEG-4 Movie Header";
|
||||||
}
|
}
|
||||||
|
|
||||||
MVHDAtom *MOOVAtom::getMVHDAtom()
|
MVHDAtom *MOOVAtom::getMVHDAtom()
|
||||||
@@ -908,7 +908,7 @@ uint64 STCOAtom::getOffsetForChunk(uint32 pChunkID)
|
|||||||
return 0LL;
|
return 0LL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESDSAtom::ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
|
ESDSAtom::ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
|
||||||
{
|
{
|
||||||
theVOL = NULL;
|
theVOL = NULL;
|
||||||
}
|
}
|
||||||
@@ -920,15 +920,116 @@ ESDSAtom::~ESDSAtom()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESDSAtom::OnProcessMetaData()
|
bool ESDSAtom::SkipTag(uint8 Tag, uint32 *offset) {
|
||||||
{
|
uint8 byte;
|
||||||
theVOL = (uint8 *)(malloc(getBytesRemaining()));
|
|
||||||
Read(theVOL,getBytesRemaining());
|
byte = theVOL[(*offset)++];
|
||||||
|
if (byte == Tag) {
|
||||||
|
uint8 numBytes = 0;
|
||||||
|
unsigned int length = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
byte = theVOL[(*offset)++];
|
||||||
|
numBytes++;
|
||||||
|
length = (length << 7) | (byte & 0x7F);
|
||||||
|
} while ((byte & 0x80) && numBytes < 4);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// go back Tag not found
|
||||||
|
(*offset)--;
|
||||||
|
printf("No Tag %d\n",Tag);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 *ESDSAtom::getVOL()
|
void ESDSAtom::OnProcessMetaData()
|
||||||
{
|
{
|
||||||
return theVOL;
|
FullAtom::OnProcessMetaData();
|
||||||
|
|
||||||
|
VOLSize = getBytesRemaining();
|
||||||
|
uint32 offset = 0;
|
||||||
|
|
||||||
|
theVOL = (uint8 *)(malloc(VOLSize));
|
||||||
|
Read(theVOL,VOLSize);
|
||||||
|
|
||||||
|
// Display the VOL
|
||||||
|
if (VOLSize > 0) {
|
||||||
|
if (SkipTag(0x03,&offset)) {
|
||||||
|
offset += 3;
|
||||||
|
} else {
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SkipTag(0x04,&offset)) {
|
||||||
|
printf("type id is %d", theVOL[offset]);
|
||||||
|
switch (theVOL[offset]) {
|
||||||
|
case 1: printf("system v1"); break;
|
||||||
|
case 2: printf("system v2"); break;
|
||||||
|
case 32: printf("MPEG-4 video"); break;
|
||||||
|
case 33: printf("MPEG-4 AVC SPS"); break;
|
||||||
|
case 34: printf("MPEG-4 AVC PPS"); break;
|
||||||
|
case 64: printf("MPEG-4 audio"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset+=2;
|
||||||
|
|
||||||
|
uint32 a,b,c;
|
||||||
|
uint32 buff;
|
||||||
|
|
||||||
|
a = theVOL[offset];
|
||||||
|
b = theVOL[offset+1];
|
||||||
|
c = theVOL[offset+2];
|
||||||
|
|
||||||
|
buff = (a << 16) | (b << 8) | c;
|
||||||
|
|
||||||
|
printf(" buf size %ld ",buff);
|
||||||
|
printf(" max bit rate %ld",uint32(theVOL[offset+4]));
|
||||||
|
printf(" avg bit rate %ld\n",uint32(theVOL[offset+8]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
printf("VOL size is 0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ESDSAtom::getVOLSize(bool forAudio)
|
||||||
|
{
|
||||||
|
uint32 offset = 0;
|
||||||
|
if (forAudio) {
|
||||||
|
if (SkipTag(0x03,&offset)) {
|
||||||
|
offset += 3;
|
||||||
|
} else {
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
if (SkipTag(0x04,&offset)) {
|
||||||
|
offset += 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipTag(0x05,&offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( VOLSize - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 *ESDSAtom::getVOL(bool forAudio)
|
||||||
|
{
|
||||||
|
uint32 offset = 0;
|
||||||
|
if (forAudio) {
|
||||||
|
if (SkipTag(0x03,&offset)) {
|
||||||
|
offset += 3;
|
||||||
|
} else {
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
if (SkipTag(0x04,&offset)) {
|
||||||
|
offset += 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipTag(0x05,&offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &theVOL[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ESDSAtom::OnGetAtomName()
|
char *ESDSAtom::OnGetAtomName()
|
||||||
@@ -961,7 +1062,7 @@ uint32 STSDAtom::getMediaHandlerType()
|
|||||||
return dynamic_cast<STBLAtom *>(getParent())->getMediaHandlerType();
|
return dynamic_cast<STBLAtom *>(getParent())->getMediaHandlerType();
|
||||||
}
|
}
|
||||||
|
|
||||||
void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize)
|
void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize, bool forAudio)
|
||||||
{
|
{
|
||||||
// Check for a esds and if it exists read it into the VOL buffer
|
// Check for a esds and if it exists read it into the VOL buffer
|
||||||
// MPEG-4 video/audio use the esds to store the VOL (STUPID COMMITTEE IDEA)
|
// MPEG-4 video/audio use the esds to store the VOL (STUPID COMMITTEE IDEA)
|
||||||
@@ -976,9 +1077,9 @@ void STSDAtom::ReadESDS(uint8 **VOL, size_t *VOLSize)
|
|||||||
|
|
||||||
if (dynamic_cast<ESDSAtom *>(aAtomBase)) {
|
if (dynamic_cast<ESDSAtom *>(aAtomBase)) {
|
||||||
// ESDS atom good
|
// ESDS atom good
|
||||||
*VOLSize = aAtomBase->getDataSize();
|
*VOLSize = dynamic_cast<ESDSAtom *>(aAtomBase)->getVOLSize(forAudio);
|
||||||
*VOL = (uint8 *)(malloc(*VOLSize));
|
*VOL = (uint8 *)(malloc(*VOLSize));
|
||||||
memcpy(*VOL,dynamic_cast<ESDSAtom *>(aAtomBase)->getVOL(),*VOLSize);
|
memcpy(*VOL,dynamic_cast<ESDSAtom *>(aAtomBase)->getVOL(forAudio),*VOLSize);
|
||||||
|
|
||||||
delete aAtomBase;
|
delete aAtomBase;
|
||||||
} else {
|
} else {
|
||||||
@@ -998,7 +1099,7 @@ void STSDAtom::ReadSoundDescription()
|
|||||||
Read(&theAudioDescription.theAudioSampleEntry.reserved);
|
Read(&theAudioDescription.theAudioSampleEntry.reserved);
|
||||||
Read(&theAudioDescription.theAudioSampleEntry.SampleRate);
|
Read(&theAudioDescription.theAudioSampleEntry.SampleRate);
|
||||||
|
|
||||||
ReadESDS(&theAudioDescription.theVOL,&theAudioDescription.VOLSize);
|
ReadESDS(&theAudioDescription.theVOL,&theAudioDescription.VOLSize,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STSDAtom::ReadVideoDescription()
|
void STSDAtom::ReadVideoDescription()
|
||||||
@@ -1028,7 +1129,7 @@ void STSDAtom::ReadVideoDescription()
|
|||||||
Read(&theVideoDescription.theVideoSampleEntry.Depth);
|
Read(&theVideoDescription.theVideoSampleEntry.Depth);
|
||||||
Read(&theVideoDescription.theVideoSampleEntry.pre_defined3);
|
Read(&theVideoDescription.theVideoSampleEntry.pre_defined3);
|
||||||
|
|
||||||
ReadESDS(&theVideoDescription.theVOL,&theVideoDescription.VOLSize);
|
ReadESDS(&theVideoDescription.theVOL,&theVideoDescription.VOLSize, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void STSDAtom::OnProcessMetaData()
|
void STSDAtom::OnProcessMetaData()
|
||||||
@@ -1253,7 +1354,7 @@ void MINFAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *MINFAtom::OnGetAtomName()
|
char *MINFAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Media Information Atom";
|
return "MPEG-4 Media Information Atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MINFAtom::getMediaHandlerType()
|
uint32 MINFAtom::getMediaHandlerType()
|
||||||
@@ -1275,7 +1376,7 @@ void STBLAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *STBLAtom::OnGetAtomName()
|
char *STBLAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Sample Table Atom";
|
return "MPEG-4 Sample Table Atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 STBLAtom::getMediaHandlerType()
|
uint32 STBLAtom::getMediaHandlerType()
|
||||||
@@ -1297,7 +1398,7 @@ void DINFAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *DINFAtom::OnGetAtomName()
|
char *DINFAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Data Information Atom";
|
return "MPEG-4 Data Information Atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
TKHDAtom::TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
|
TKHDAtom::TKHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
|
||||||
@@ -1371,7 +1472,7 @@ void TKHDAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *TKHDAtom::OnGetAtomName()
|
char *TKHDAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Track Header";
|
return "MPEG-4 Track Header";
|
||||||
}
|
}
|
||||||
|
|
||||||
MDIAAtom::MDIAAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
|
MDIAAtom::MDIAAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomContainer(pStream, pstreamOffset, patomType, patomSize)
|
||||||
@@ -1388,7 +1489,7 @@ void MDIAAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *MDIAAtom::OnGetAtomName()
|
char *MDIAAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Media Atom";
|
return "MPEG-4 Media Atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 MDIAAtom::getMediaHandlerType()
|
uint32 MDIAAtom::getMediaHandlerType()
|
||||||
@@ -1443,7 +1544,7 @@ void MDHDAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *MDHDAtom::OnGetAtomName()
|
char *MDHDAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Media Header";
|
return "MPEG-4 Media Header";
|
||||||
}
|
}
|
||||||
|
|
||||||
bigtime_t MDHDAtom::getDuration()
|
bigtime_t MDHDAtom::getDuration()
|
||||||
@@ -1486,7 +1587,7 @@ void HDLRAtom::OnProcessMetaData()
|
|||||||
char *HDLRAtom::OnGetAtomName()
|
char *HDLRAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
printf("%s %s:",(char *)&(theHeader.handler_type),name);
|
printf("%s %s:",(char *)&(theHeader.handler_type),name);
|
||||||
return "Quicktime Handler Reference Atom ";
|
return "MPEG-4 Handler Reference Atom ";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HDLRAtom::IsVideoHandler()
|
bool HDLRAtom::IsVideoHandler()
|
||||||
@@ -1524,7 +1625,7 @@ void VMHDAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *VMHDAtom::OnGetAtomName()
|
char *VMHDAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Video Media Header";
|
return "MPEG-4 Video Media Header";
|
||||||
}
|
}
|
||||||
|
|
||||||
SMHDAtom::SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
|
SMHDAtom::SMHDAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : FullAtom(pStream, pstreamOffset, patomType, patomSize)
|
||||||
@@ -1545,5 +1646,5 @@ void SMHDAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *SMHDAtom::OnGetAtomName()
|
char *SMHDAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Sound Media Header";
|
return "MPEG-4 Sound Media Header";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,16 +300,19 @@ public:
|
|||||||
off_t getEOF();
|
off_t getEOF();
|
||||||
};
|
};
|
||||||
|
|
||||||
class ESDSAtom : public AtomBase {
|
class ESDSAtom : public FullAtom {
|
||||||
public:
|
public:
|
||||||
ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
|
ESDSAtom(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize);
|
||||||
virtual ~ESDSAtom();
|
virtual ~ESDSAtom();
|
||||||
void OnProcessMetaData();
|
void OnProcessMetaData();
|
||||||
char *OnGetAtomName();
|
char *OnGetAtomName();
|
||||||
|
|
||||||
uint8 *getVOL();
|
uint8 *getVOL(bool forAudio);
|
||||||
|
size_t getVOLSize(bool forAudio);
|
||||||
private:
|
private:
|
||||||
|
bool SkipTag(uint8 Tag, uint32 *offset);
|
||||||
uint8 *theVOL;
|
uint8 *theVOL;
|
||||||
|
size_t VOLSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Atom class for reading the sdst atom
|
// Atom class for reading the sdst atom
|
||||||
@@ -326,7 +329,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
uint32 getMediaHandlerType();
|
uint32 getMediaHandlerType();
|
||||||
|
|
||||||
void ReadESDS(uint8 **VOL, size_t *VOLSize);
|
void ReadESDS(uint8 **VOL, size_t *VOLSize, bool forAudio);
|
||||||
void ReadSoundDescription();
|
void ReadSoundDescription();
|
||||||
void ReadVideoDescription();
|
void ReadVideoDescription();
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ void TRAKAtom::OnProcessMetaData()
|
|||||||
|
|
||||||
char *TRAKAtom::OnGetAtomName()
|
char *TRAKAtom::OnGetAtomName()
|
||||||
{
|
{
|
||||||
return "Quicktime Track Atom";
|
return "MPEG-4 Track Atom";
|
||||||
}
|
}
|
||||||
|
|
||||||
TKHDAtom *TRAKAtom::getTKHDAtom()
|
TKHDAtom *TRAKAtom::getTKHDAtom()
|
||||||
|
|||||||
@@ -421,31 +421,56 @@ mp4Reader::AllocateCookie(int32 streamNumber, void **_cookie)
|
|||||||
format->user_data_type = B_CODEC_TYPE_INFO;
|
format->user_data_type = B_CODEC_TYPE_INFO;
|
||||||
*(uint32 *)format->user_data = description.u.quicktime.codec; format->user_data[4] = 0;
|
*(uint32 *)format->user_data = description.u.quicktime.codec; format->user_data[4] = 0;
|
||||||
|
|
||||||
format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec;
|
// format->u.encoded_video.max_bit_rate = 8 * theFileReader->MovMainHeader()->max_bytes_per_sec;
|
||||||
format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this
|
// format->u.encoded_video.avg_bit_rate = format->u.encoded_video.max_bit_rate / 2; // XXX fix this
|
||||||
format->u.encoded_video.output.field_rate = cookie->frames_per_sec_rate / (float)cookie->frames_per_sec_scale;
|
format->u.encoded_video.output.field_rate = cookie->frames_per_sec_rate / (float)cookie->frames_per_sec_scale;
|
||||||
format->u.encoded_video.output.interlace = 1; // 1: progressive
|
|
||||||
format->u.encoded_video.output.first_active = 0;
|
format->u.encoded_video.avg_bit_rate = 1;
|
||||||
format->u.encoded_video.output.last_active = cookie->line_count - 1;
|
format->u.encoded_video.max_bit_rate = 1;
|
||||||
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
|
|
||||||
format->u.encoded_video.output.pixel_width_aspect = 1;
|
format->u.encoded_video.frame_size = video_format->width * video_format->height * video_format->planes / 8;
|
||||||
format->u.encoded_video.output.pixel_height_aspect = 1;
|
format->u.encoded_video.output.display.bytes_per_row = video_format->planes / 8 * video_format->width;
|
||||||
// format->u.encoded_video.output.display.format = 0;
|
// align to 2 bytes
|
||||||
format->u.encoded_video.output.display.line_width = theFileReader->MovMainHeader()->width;
|
format->u.encoded_video.output.display.bytes_per_row += format->u.encoded_video.output.display.bytes_per_row & 1;
|
||||||
format->u.encoded_video.output.display.line_count = cookie->line_count;
|
|
||||||
format->u.encoded_video.output.display.bytes_per_row = 0; // format->u.encoded_video.output.display.line_width * 4;
|
switch (video_format->planes) {
|
||||||
|
case 16:
|
||||||
|
format->u.encoded_video.output.display.format = B_RGB15_BIG;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
format->u.encoded_video.output.display.format = B_RGB24_BIG;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
format->u.encoded_video.output.display.format = B_RGB32_BIG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
format->u.encoded_video.output.display.format = B_NO_COLOR_SPACE;
|
||||||
|
format->u.encoded_video.frame_size = video_format->width * video_format->height * 8 / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
format->u.encoded_video.output.display.line_width = video_format->width;
|
||||||
|
format->u.encoded_video.output.display.line_count = video_format->height;
|
||||||
format->u.encoded_video.output.display.pixel_offset = 0;
|
format->u.encoded_video.output.display.pixel_offset = 0;
|
||||||
format->u.encoded_video.output.display.line_offset = 0;
|
format->u.encoded_video.output.display.line_offset = 0;
|
||||||
format->u.encoded_video.output.display.flags = 0;
|
format->u.encoded_video.output.display.flags = 0;
|
||||||
|
format->u.encoded_video.output.interlace = 1; // 1: progressive
|
||||||
|
format->u.encoded_video.output.first_active = 0;
|
||||||
|
format->u.encoded_video.output.last_active = format->u.encoded_video.output.display.line_count - 1;
|
||||||
|
format->u.encoded_video.output.orientation = B_VIDEO_TOP_LEFT_RIGHT;
|
||||||
|
format->u.encoded_video.output.pixel_width_aspect = 1;
|
||||||
|
format->u.encoded_video.output.pixel_height_aspect = 1;
|
||||||
|
|
||||||
TRACE("max_bit_rate %.3f\n", format->u.encoded_video.max_bit_rate);
|
TRACE("max_bit_rate %.3f\n", format->u.encoded_video.max_bit_rate);
|
||||||
TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate);
|
TRACE("field_rate %.3f\n", format->u.encoded_video.output.field_rate);
|
||||||
|
|
||||||
// Set the VOL
|
// Set the VOL
|
||||||
if (video_format->VOLSize > 0) {
|
if (video_format->VOLSize > 0) {
|
||||||
|
TRACE("VOL Found Size is %ld\n",video_format->VOLSize);
|
||||||
size_t size = video_format->VOLSize;
|
size_t size = video_format->VOLSize;
|
||||||
const void *data = video_format->theVOL;
|
const void *data = video_format->theVOL;
|
||||||
format->SetMetaData(data, size);
|
if (format->SetMetaData(data, size) != B_OK) {
|
||||||
|
printf("Failed to set VOL\n %d %d",(16 << 20),32000);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TRACE_MP4_READER
|
#ifdef TRACE_MP4_READER
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -485,8 +510,17 @@ mp4Reader::GetStreamInfo(void *_cookie, int64 *frameCount, bigtime_t *duration,
|
|||||||
*frameCount = cookie->frame_count;
|
*frameCount = cookie->frame_count;
|
||||||
*duration = cookie->duration;
|
*duration = cookie->duration;
|
||||||
*format = cookie->format;
|
*format = cookie->format;
|
||||||
*infoBuffer = 0;
|
|
||||||
*infoSize = 0;
|
// Copy metadata to infoBuffer
|
||||||
|
if (theFileReader->IsVideo(cookie->stream)) {
|
||||||
|
const VideoMetaData *video_format = theFileReader->VideoFormat(cookie->stream);
|
||||||
|
*infoBuffer = video_format->theVOL;
|
||||||
|
*infoSize = video_format->VOLSize;
|
||||||
|
} else {
|
||||||
|
const AudioMetaData *audio_format = theFileReader->AudioFormat(cookie->stream);
|
||||||
|
*infoBuffer = audio_format->theVOL;
|
||||||
|
*infoSize = audio_format->VOLSize;
|
||||||
|
}
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,6 +612,8 @@ mp4Reader::GetNextChunk(void *_cookie, const void **chunkBuffer,
|
|||||||
mediaHeader->u.encoded_video.field_flags = keyframe ? B_MEDIA_KEY_FRAME : 0;
|
mediaHeader->u.encoded_video.field_flags = keyframe ? B_MEDIA_KEY_FRAME : 0;
|
||||||
mediaHeader->u.encoded_video.first_active_line = 0;
|
mediaHeader->u.encoded_video.first_active_line = 0;
|
||||||
mediaHeader->u.encoded_video.line_count = cookie->line_count;
|
mediaHeader->u.encoded_video.line_count = cookie->line_count;
|
||||||
|
mediaHeader->u.encoded_video.field_number = 0;
|
||||||
|
mediaHeader->u.encoded_video.field_sequence = cookie->frame_pos;
|
||||||
|
|
||||||
cookie->frame_pos++;
|
cookie->frame_pos++;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user