[xiph-commits] r11370 - in trunk/xiph-qt: OggImport/src Theora/src
arek at svn.xiph.org
arek at svn.xiph.org
Sun May 7 15:39:35 PDT 2006
Author: arek
Date: 2006-05-07 15:39:25 -0700 (Sun, 07 May 2006)
New Revision: 11370
Modified:
trunk/xiph-qt/OggImport/src/stream_theora.c
trunk/xiph-qt/OggImport/src/stream_types_theora.h
trunk/xiph-qt/Theora/src/TheoraDecoder.c
trunk/xiph-qt/Theora/src/TheoraDecoder.r
trunk/xiph-qt/Theora/src/TheoraDecoderDispatch.h
trunk/xiph-qt/Theora/src/decoder_types.h
Log:
Changed Theora samples layout in Media and corrected segmented packet reassembling in TheoraDecoder. Changed track offset handling in OggImporter/stream_theora.
Modified: trunk/xiph-qt/OggImport/src/stream_theora.c
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_theora.c 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/OggImport/src/stream_theora.c 2006-05-07 22:39:25 UTC (rev 11370)
@@ -44,6 +44,11 @@
#include "data_types.h"
+#define MAX_FPS_DENOMINATOR 198
+#define DESIRED_MULTIPLIER 197
+#define SEGMENT_RATIO_DENOM 3
+
+
#if TARGET_OS_WIN32
EXTERN_API_C(SInt32 ) U64Compare(UInt64 left, UInt64 right)
{
@@ -129,6 +134,12 @@
si->si_theora.state = kTStateInitial;
+ si->si_theora.lpkt_data_offset = S64Set(0);
+ si->si_theora.lpkt_data_size = 0;
+ si->si_theora.lpkt_duration = 0;
+ si->si_theora.lpkt_flags = 0;
+
+ si->si_theora.psegment_ratio = SEGMENT_RATIO_DENOM;
return 0;
};
@@ -147,10 +158,10 @@
ImageDescriptionPtr imgdsc = (ImageDescriptionPtr) *desc;
imgdsc->idSize = sizeof(ImageDescription);
- imgdsc->cType = 'XiTh';
+ imgdsc->cType = kVideoFormatXiphTheora;
imgdsc->version = 1; //major ver num
imgdsc->revisionLevel = 1; //minor ver num
- imgdsc->vendor = 'XiQT';
+ imgdsc->vendor = kXiphComponentsManufacturer;
imgdsc->temporalQuality = codecMaxQuality;
imgdsc->spatialQuality = codecMaxQuality;
imgdsc->width = si->si_theora.ti.frame_width;
@@ -192,9 +203,6 @@
return ret;
};
-#define MAX_FPS_DENOMINATOR 20
-#define DESIRED_MULTIPLIER 19
-
int process_first_packet__theora(StreamInfo *si, ogg_page *op, ogg_packet *opckt)
{
unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo),
@@ -206,6 +214,8 @@
th_decode_headerin(&si->si_theora.ti, &si->si_theora.tc, &si->si_theora.ts, opckt); //check errors?
si->numChannels = 0;
+ //si->lastMediaInserted = 0;
+ si->mediaLength = 0;
fps_N = si->si_theora.ti.fps_numerator;
fps_D = si->si_theora.ti.fps_denominator;
@@ -248,6 +258,10 @@
Boolean loop = true;
Boolean movie_changed = false;
+ TimeValue movieTS = GetMovieTimeScale(globals->theMovie);
+ TimeValue mediaTS = 0;
+ TimeValue mediaTS_fl = 0.0;
+
ogg_packet op;
switch(si->si_theora.state) {
@@ -317,6 +331,11 @@
si->si_theora.state = kTStateReadingFirstPacket;
si->insertTime = 0;
si->streamOffset = globals->currentGroupOffset;
+ mediaTS = GetMediaTimeScale(si->theMedia);
+ mediaTS_fl = (Float64) mediaTS;
+ si->streamOffsetSamples = (TimeValue) (mediaTS_fl * globals->currentGroupOffsetSubSecond) -
+ ((globals->currentGroupOffset % movieTS) * mediaTS / movieTS);
+ dbg_printf("---/ / streamOffset: [%ld, %ld], %lg\n", si->streamOffset, si->streamOffsetSamples, globals->currentGroupOffsetSubSecond);
si->incompleteCompensation = 0;
loop = false; //there should be an end of page here according to specs...
}
@@ -376,79 +395,111 @@
for (i = 0; i < segments; i++) {
int val = opg->header[27 + i];
int incomplete = (i == segments - 1) && (val == 255);
- TimeValue pduration = 0;
psize += val;
if (val < 255 || incomplete) {
- pduration = si->si_theora.fps_framelen;
+ TimeValue pduration = si->si_theora.fps_framelen;
if (incomplete) {
- pduration = 1;
- si->incompleteCompensation -= 1;
psize += 4; // this should allow decoder to see that if (packet_len % 255 == 4) and
// last 4 bytes contain 'OggS' sync pattern then that's an incomplete packet
- } else if (continued) {
- pduration += si->incompleteCompensation;
- si->incompleteCompensation = 0;
- /* QT doesn't like zero-size samples, do this: */
- if (val == 0) {
- psize = 1;
- poffset -= 1;
+ }
+ if (psize == 0 || (opg->body[poffset] & 0x40) != 0)
+ smp_flags |= mediaSampleNotSync;
+
+ if (si->si_theora.lpkt_data_size != 0) {
+ /* add last packet to media */
+ memset(&sampleRec, 0, sizeof(sampleRec));
+ sampleRec.dataOffset = SInt64ToWide(si->si_theora.lpkt_data_offset);
+ sampleRec.dataSize = si->si_theora.lpkt_data_size;
+ sampleRec.sampleFlags = si->si_theora.lpkt_flags;
+ sampleRec.numberOfSamples = 1;
+ if (!incomplete) {
+ /* packet finishes here */
+ if (si->si_theora.lpkt_duration > 0) {
+ sampleRec.durationPerSample = si->si_theora.lpkt_duration;
+ } else {
+ sampleRec.durationPerSample = 1;
+ pduration += si->si_theora.lpkt_duration - 1;
+ }
+ } else {
+ /* segmented packet */
+ if (si->si_theora.lpkt_duration > 0) {
+ sampleRec.durationPerSample = si->si_theora.lpkt_duration / si->si_theora.psegment_ratio;
+ if (sampleRec.durationPerSample == 0)
+ sampleRec.durationPerSample = 1;
+ pduration = si->si_theora.lpkt_duration - sampleRec.durationPerSample;
+ } else {
+ sampleRec.durationPerSample = 1;
+ pduration = si->si_theora.lpkt_duration - 1 /* sampleRec.durationPerSample */;
+ }
}
- /* */
+ dbg_printf(" T :++: adding sampleRef: %8lld, len: %8d, dur: %8d, fl: %08x\n",
+ sampleRec.dataOffset, sampleRec.dataSize, sampleRec.durationPerSample, sampleRec.sampleFlags);
+ ret = AddMediaSampleReferences64(si->theMedia, si->sampleDesc, 1, &sampleRec, inserted == -1 ? &inserted : NULL);
+ if (ret != noErr)
+ break;
+
+ duration += sampleRec.durationPerSample;
+ packet_count += 1;
+ } else if (si->streamOffsetSamples > 0) {
+ /* first packet (and stream has a sample offset) */
+ dbg_printf(" - :++: increasing duration (%ld) by sampleOffset: %ld\n", pduration, si->streamOffsetSamples);
+ pduration += si->streamOffsetSamples;
}
- if ((opg->body[poffset] & 0x40) != 0)
- smp_flags |= mediaSampleNotSync;
- memset(&sampleRec, 0, sizeof(sampleRec));
- tmp = globals->dataOffset + S64Set(poffset + opg->header_len);
- sampleRec.dataOffset = SInt64ToWide(tmp);
- sampleRec.dataSize = psize;
- sampleRec.sampleFlags = smp_flags;
- sampleRec.durationPerSample = pduration;
- sampleRec.numberOfSamples = 1;
- dbg_printf(" T :++: adding sampleRef: %8lld, len: %8d, dur: %8d, fl: %08x\n",
- sampleRec.dataOffset, psize, pduration, smp_flags);
- ret = AddMediaSampleReferences64(si->theMedia, si->sampleDesc, 1, &sampleRec, inserted == -1 ? &inserted : NULL);
- if (ret != noErr)
- break;
- duration += pduration;
- packet_count += 1;
+ /* prepending packet with one padding byte (zero-sized samples are not allowed) here
+ (see ...BeginBand() in TheoraDecoder) */
+ si->si_theora.lpkt_data_offset = globals->dataOffset + S64Set(poffset + opg->header_len - 1);
+ si->si_theora.lpkt_data_size = psize + 1;
+ si->si_theora.lpkt_flags = smp_flags;
+ si->si_theora.lpkt_duration = pduration;
+
poffset += psize;
-
psize = 0;
continued = false;
smp_flags = 0;
}
}
-#if 0
- while ((ovret = ogg_stream_packetout(&si->os, &op)) > 0) {
- packet_count += 1;
- last_packet_pos += 1;
+ loop = false;
+ if (ovret < 0) {
+ ret = invalidMedia;
+ break;
+ }
+
+ if (ret == noErr && si->si_theora.lpkt_data_size != 0 && ogg_page_eos(opg)) {
+ /* it's EOS here, flush */
memset(&sampleRec, 0, sizeof(sampleRec));
- sampleRec.dataOffset = SInt64ToWide(globals->dataOffset + S64Set(opg->header_len + op->packet - opg->body)); // + packet offset within the page! - :/
- sampleRec.dataSize = op.bytes;
- sampleRec.sampleFlags = smp_flags;
- sampleRec.durationPerSample = si->si_theora.ti.fps_denominator;
+ sampleRec.dataOffset = SInt64ToWide(si->si_theora.lpkt_data_offset);
+ sampleRec.dataSize = si->si_theora.lpkt_data_size;
+ sampleRec.sampleFlags = si->si_theora.lpkt_flags;
sampleRec.numberOfSamples = 1;
- dbg_printf(" - :++: adding sampleRef: %lld, len: %d, dur: %d\n", globals->dataOffset, len, duration);
+
+ /* this the last page of the stream, packet SHOULD finish here */
+ if (si->si_theora.lpkt_duration > 0) {
+ sampleRec.durationPerSample = si->si_theora.lpkt_duration;
+ } else {
+ sampleRec.durationPerSample = 1;
+ }
+
+ dbg_printf(" T :++: adding sampleRef! %8lld, len: %8d, dur: %8d, fl: %08x\n",
+ sampleRec.dataOffset, sampleRec.dataSize, sampleRec.durationPerSample, sampleRec.sampleFlags);
ret = AddMediaSampleReferences64(si->theMedia, si->sampleDesc, 1, &sampleRec, inserted == -1 ? &inserted : NULL);
if (ret != noErr)
break;
+
+ duration += sampleRec.durationPerSample;
+ packet_count += 1;
}
-#endif /* 0 */
- loop = false;
- if (ovret < 0) {
- ret = invalidMedia;
- break;
- }
if (ret == noErr && packet_count > 0) {
TimeValue timeLoaded;
+ Float64 timeLoadedSubSecond;
+ si->mediaLength += duration;
+
dbg_printf(" - :><: added page %04ld at %14ld (size: %5ld, tsize: %6d), f: %d\n",
ogg_page_pageno(opg), inserted,
opg->body_len, len, !logg_page_last_packet_incomplete(opg));
- //dbg_printf(" - :/>: inserting media: %ld, mt: %lld, dur: %d\n", si->insertTime, si->lastGranulePos, duration);
dbg_printf(" - :/>: inserting media: %ld, mt: %ld, dur: %ld\n", si->insertTime, inserted, duration);
ret = InsertMediaIntoTrack(si->theTrack, si->insertTime /*inserted*/, /* si->lastGranulePos */ inserted,
duration, fixed1);
@@ -463,70 +514,27 @@
SetTrackEnabled(si->theTrack, true);
}
}
- if (GetMovieTimeScale(globals->theMovie) < GetMediaTimeScale(si->theMedia)) {
- dbg_printf(" # - changing movie time scale: %ld --> %ld\n",
- GetMovieTimeScale(globals->theMovie), GetMediaTimeScale(si->theMedia));
- SetMovieTimeScale(globals->theMovie, GetMediaTimeScale(si->theMedia));
- }
}
si->insertTime = -1;
- timeLoaded = GetTrackDuration(si->theTrack);
- dbg_printf(" - :><: added page %04ld at %14ld; offset: %ld, duration: %ld (%ld, %ld), mediats: %ld; moviets: %ld, ret = %ld\n",
+ mediaTS = GetMediaTimeScale(si->theMedia);
+ mediaTS_fl = (Float64) mediaTS;
+ timeLoaded = si->streamOffset + si->mediaLength / mediaTS * movieTS + (si->mediaLength % mediaTS) * movieTS / mediaTS;
+ timeLoadedSubSecond = (Float64) ((si->streamOffset % movieTS * mediaTS / movieTS + si->mediaLength) % mediaTS) / mediaTS_fl;
+
+ dbg_printf(" - :><: added page %04ld at %14ld; offset: %ld, duration: %ld (%ld(%lg); %ld; ml: %ld), mediats: %ld; moviets: %ld, ret = %ld\n",
ogg_page_pageno(opg), inserted,
- GetTrackOffset(si->theTrack), GetTrackDuration(si->theTrack), timeLoaded,
- (duration * GetMovieTimeScale(globals->theMovie)) / GetMediaTimeScale(si->theMedia),
- GetMediaTimeScale(si->theMedia), GetMovieTimeScale(globals->theMovie), ret);
- if (globals->timeLoaded < timeLoaded)
+ GetTrackOffset(si->theTrack), GetTrackDuration(si->theTrack), timeLoaded, timeLoadedSubSecond,
+ (duration * movieTS) / mediaTS, si->mediaLength,
+ mediaTS, movieTS, ret);
+ if (globals->timeLoaded < timeLoaded || (globals->timeLoaded == timeLoaded && globals->timeLoadedSubSecond < timeLoadedSubSecond)) {
globals->timeLoaded = timeLoaded;
+ globals->timeLoadedSubSecond = timeLoadedSubSecond;
+ }
movie_changed = true;
}
-#if 0
- dbg_printf(" - :++: adding sampleRef: %lld, len: %d, dur: %d\n", globals->dataOffset, len, duration);
- ret = AddMediaSampleReference(si->theMedia, S32Set(globals->dataOffset),
- len, duration, si->sampleDesc, 1, smp_flags, &inserted); //@@@@ 64-bit enable
- if (ret == noErr) {
- TimeValue timeLoaded;
-
- dbg_printf(" - :><: added page %04ld at %14ld (size: %5ld, tsize: %6d), f: %d\n",
- ogg_page_pageno(opg), inserted,
- opg->header_len + opg->body_len, len, !logg_page_last_packet_incomplete(opg));
- dbg_printf(" - :/>: inserting media: %ld, mt: %lld, dur: %d\n", si->insertTime, si->lastGranulePos, duration);
- ret = InsertMediaIntoTrack(si->theTrack, si->insertTime /*inserted*/, /* si->lastGranulePos */ inserted,
- duration, fixed1);
- if (si->insertTime == 0) {
- if (si->streamOffset != 0) {
- SetTrackOffset(si->theTrack, si->streamOffset);
- dbg_printf(" # -- SetTrackOffset(%ld) = %ld --> %ld\n",
- si->streamOffset, GetMoviesError(),
- GetTrackOffset(si->theTrack));
- if (globals->dataIsStream) {
- SetTrackEnabled(si->theTrack, false);
- SetTrackEnabled(si->theTrack, true);
- }
- }
- if (GetMovieTimeScale(globals->theMovie) < GetMediaTimeScale(si->theMedia)) {
- dbg_printf(" # - changing movie time scale: %ld --> %ld\n",
- GetMovieTimeScale(globals->theMovie), GetMediaTimeScale(si->theMedia));
- SetMovieTimeScale(globals->theMovie, GetMediaTimeScale(si->theMedia));
- }
- }
- si->insertTime = -1;
- timeLoaded = GetTrackDuration(si->theTrack);
-
- dbg_printf(" - :><: added page %04ld at %14ld; offset: %ld, duration: %ld (%ld, %ld), mediats: %ld; moviets: %ld, ret = %ld\n",
- ogg_page_pageno(opg), inserted,
- GetTrackOffset(si->theTrack), GetTrackDuration(si->theTrack), timeLoaded,
- (duration * GetMovieTimeScale(globals->theMovie)) / GetMediaTimeScale(si->theMedia),
- GetMediaTimeScale(si->theMedia), GetMovieTimeScale(globals->theMovie), ret);
- if (globals->timeLoaded < timeLoaded)
- globals->timeLoaded = timeLoaded;
-
- movie_changed = true;
- }
-#endif /* 0 */
si->lastGranulePos = pos;
}
loop = false;
Modified: trunk/xiph-qt/OggImport/src/stream_types_theora.h
===================================================================
--- trunk/xiph-qt/OggImport/src/stream_types_theora.h 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/OggImport/src/stream_types_theora.h 2006-05-07 22:39:25 UTC (rev 11370)
@@ -57,6 +57,15 @@
UInt32 granulepos_shift;
UInt32 fps_framelen;
+
+ //variables to store last packet params
+ SInt64 lpkt_data_offset;
+ UInt32 lpkt_data_size;
+ SInt32 lpkt_duration;
+ short lpkt_flags;
+
+ // segmentation ratio; defined as a denominator, with numerator = 1
+ UInt32 psegment_ratio;
} StreamInfo__theora;
Modified: trunk/xiph-qt/Theora/src/TheoraDecoder.c
===================================================================
--- trunk/xiph-qt/Theora/src/TheoraDecoder.c 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/Theora/src/TheoraDecoder.c 2006-05-07 22:39:25 UTC (rev 11370)
@@ -248,7 +248,7 @@
pascal ComponentResult Theora_ImageCodecInitialize(Theora_Globals glob, ImageSubCodecDecompressCapabilities *cap)
{
- dbg_printf("--:Theora:- CodecInitalize(%08lx) called\n", (long)glob);
+ dbg_printf("--:Theora:- CodecInitalize(%08lx) called (Qsize: %d)\n", (long)glob, cap->suggestedQueueSize);
cap->decompressRecordSize = sizeof(Theora_DecompressRecord);
cap->canAsync = true;
@@ -256,6 +256,9 @@
if (cap->recordSize > offsetof(ImageSubCodecDecompressCapabilities, baseCodecShouldCallDecodeBandForAllFrames) ) {
cap->subCodecIsMultiBufferAware = true;
cap->baseCodecShouldCallDecodeBandForAllFrames = true;
+
+ // the following setting is not entirely true, but some applications seem to need it
+ cap->subCodecSupportsOutOfOrderDisplayTimes = true; // ?!!
}
return noErr;
@@ -267,8 +270,9 @@
OSTypePtr formats = *glob->wantedDestinationPixelTypeH;
OSErr ret = noErr;
- dbg_printf("--:Theora:- CodecPreflight(%08lx) called (seqid: %08lx, frN: %8ld, first: %d, data1: %02x)\n",
- (long)glob, p->sequenceID, p->frameNumber, (p->conditionFlags & codecConditionFirstFrame) != 1, p->data[0]);
+ dbg_printf("--:Theora:- CodecPreflight(%08lx) called (seqid: %08lx, frN: %8ld, first: %d, data1: %02x, flags: %08lx, flags2: %08lx)\n",
+ (long)glob, p->sequenceID, p->frameNumber, (p->conditionFlags & codecConditionFirstFrame) != 1, p->bufferSize > 1 ? p->data[1] : 0,
+ capabilities->flags, capabilities->flags2);
dbg_printf(" :- image: %dx%d, pixform: %x\n", (**p->imageDescription).width, (**p->imageDescription).height, glob->ti.pixel_fmt);
/* only decode full images at the moment */
@@ -299,13 +303,14 @@
long offsetH, offsetV;
Theora_DecompressRecord *myDrp = (Theora_DecompressRecord *)drp->userDecompressRecord;
- dbg_printf("--:Theora:- CodecBeginBand(%08lx, %08lx, %08lx) called (seqid: %08lx, frN: %8ld, first: %d, data1: %02x) (pixF: '%4.4s')\n",
+ dbg_printf("--:Theora:- CodecBeginBand(%08lx, %08lx, %08lx) called (seqid: %08lx, frN: %8ld, first: %d, data1: %02x[%02x]) (pixF: '%4.4s') (complP: %8lx)\n",
(long)glob, (long)drp, (long)myDrp, p->sequenceID, p->frameNumber, (p->conditionFlags & codecConditionFirstFrame) != 1,
- p->data[0], &p->dstPixMap.pixelFormat);
+ p->bufferSize > 1 ? p->data[1] : 0, p->bufferSize > 1 ? ((unsigned char *)drp->codecData)[1] : 0, &p->dstPixMap.pixelFormat, p->completionProcRecord);
if (p->frameTime != NULL) {
- dbg_printf("--:Theora:- BeginBand::frameTime: scale: %8ld, duration: %8ld, rate: %5ld.%05ld (vd: %8ld)\n",
+ dbg_printf("--:Theora:- BeginBand::frameTime: scale: %8ld, duration: %8ld, rate: %5ld.%05ld (vd: %8ld) [fl: %02lx]\n",
p->frameTime->scale, p->frameTime->duration, p->frameTime->rate >> 16, p->frameTime->rate & 0xffff,
- (p->frameTime->flags & icmFrameTimeHasVirtualStartTimeAndDuration) ? p->frameTime->virtualDuration : -1);
+ (p->frameTime->flags & icmFrameTimeHasVirtualStartTimeAndDuration) ? p->frameTime->virtualDuration : -1,
+ p->frameTime->flags);
}
#if 0
@@ -327,7 +332,14 @@
}
#endif /* 0 */
- if ((*(unsigned char *)drp->codecData) & 0x40 == 0)
+ /* importer should send us samples prepended by a single pading
+ byte (this is because QT doesn't allow zero-sized samples) and
+ it is PREpended because there is ALWAYS some data BEFORE a
+ packet but not necesarrily after */
+ /* p->bufferSize -= 1; */
+ drp->codecData += 1;
+
+ if (p->bufferSize > 1 && ((unsigned char *)drp->codecData)[0] & 0x40 == 0)
drp->frameType = kCodecFrameTypeKey;
else
drp->frameType = kCodecFrameTypeDifference;
@@ -335,10 +347,13 @@
myDrp->width = (**p->imageDescription).width;
myDrp->height = (**p->imageDescription).height;
myDrp->depth = (**p->imageDescription).depth;
- myDrp->dataSize = p->bufferSize;
+ myDrp->dataSize = p->bufferSize - 1;
myDrp->frameNumber = p->frameNumber;
myDrp->pixelFormat = p->dstPixMap.pixelFormat;
myDrp->draw = 0;
+ myDrp->decoded = 0;
+ if (p->frameTime != NULL && (p->frameTime->flags & icmFrameAlreadyDecoded) != 0)
+ myDrp->decoded = 1;
if (glob->last_frame < 0) {
dbg_printf("--:Theora:- calling theora_decode_init()...\n");
@@ -354,15 +369,19 @@
OSErr err = noErr;
Theora_DecompressRecord *myDrp = (Theora_DecompressRecord *)drp->userDecompressRecord;
unsigned char *dataPtr = (unsigned char *)drp->codecData;
+ SInt32 dataConsumed = 0;
ICMDataProcRecordPtr dataProc = drp->dataProcRecord.dataProc ? &drp->dataProcRecord : NULL;
SInt32 dataAvailable = dataProc != NULL ? codecMinimumDataSize : -1;
dbg_printf("--:Theora:- CodecDecodeBand(%08lx, %08lx, %08lx) cald ( frN: %8ld, dataProc: %8lx)\n",
(long)glob, (long)drp, (long)myDrp, myDrp->frameNumber, (long)dataProc);
-#if 0
- // TODO: implement using dataProc for loading data if not all available at once
if (dataAvailable > -1) {
+#if 1
+ dbg_printf(" ! ! ! CodecDecodeBand(): NOT IMPLEMENTED - use dataProc to load data!\n");
+ err = codecErr;
+#else
+ // TODO: implement using dataProc for loading data if not all available at once
unsigned char *tmpDataPtr = dataPtr;
UInt32 bytesToLoad = myDrp->dataSize;
while (dataAvailable > 0) {
@@ -370,14 +389,13 @@
if (err == eofErr)
err = noErr;
}
+#endif /* 1 */
}
-#endif /* 0 */
-
- {
+ if (err == noErr) {
ogg_packet op;
int terr;
- Boolean drop = false;
+ Boolean do_decode = true;
Boolean continued = (glob->p_buffer_used > 0);
UInt8 *data_buffer = dataPtr;
UInt32 data_size = myDrp->dataSize;
@@ -390,26 +408,28 @@
glob->last_frame = myDrp->frameNumber;
if (myDrp->dataSize % 255 == 4) {
- // TODO: extend the checks below with frame duration checks
if (!memcmp(dataPtr + myDrp->dataSize - 4, "OggS", 4)) {
- err = codecDroppedFrameErr;
- drop = true;
- if (myDrp->dataSize + glob->p_buffer_used > glob->p_buffer_len) {
- // TODO: implement reallocation with expansion
+ do_decode = false;
+ if (myDrp->dataSize - 4 + glob->p_buffer_used > glob->p_buffer_len) {
+ dbg_printf(" !!! CodecDecodeBand(): NOT IMPLEMENTED - reallocate with resize!\n");
err = codecErr;
} else {
BlockMoveData(dataPtr, glob->p_buffer + glob->p_buffer_used, myDrp->dataSize - 4);
glob->p_buffer_used += myDrp->dataSize - 4;
}
+ } else {
+ myDrp->draw = 1;
}
- } else if (myDrp->dataSize == 1) {
- myDrp->dataSize = 0;
+ } else if (myDrp->dataSize == 0 && !continued) {
myDrp->draw = 1;
+ drp->frameType = kCodecFrameTypeDroppableDifference;
} else {
myDrp->draw = 1;
}
- if (!drop && continued) {
+ dataConsumed = myDrp->dataSize;
+
+ if (do_decode && continued) {
/* this should be the last fragment */
if (myDrp->dataSize > 0)
BlockMoveData(dataPtr, glob->p_buffer + glob->p_buffer_used, myDrp->dataSize);
@@ -418,10 +438,9 @@
data_buffer = glob->p_buffer;
}
- if (drop)
+ if (myDrp->draw == 0)
err = codecDroppedFrameErr;
-
- if (!drop && myDrp->draw != 0) {
+ else {
op.b_o_s = 0;
op.e_o_s = 0;
op.granulepos = -1;
@@ -429,7 +448,7 @@
op.bytes = data_size;
op.packet = data_buffer;
terr = th_decode_packetin(glob->td, &op, NULL);
- dbg_printf("--:Theora:- theora_decode_packetin() = %d\n", terr);
+ dbg_printf("--:Theora:- theora_decode_packetin(pktno: %lld, size: %ld, data1: [%02x]) = %d\n", op.packetno, op.bytes, data_buffer[0], terr);
if (terr != 0) {
myDrp->draw = 0;
@@ -438,7 +457,8 @@
}
}
-
+ myDrp->decoded = 1;
+ drp->codecData += dataConsumed;
return err;
}
@@ -453,39 +473,50 @@
dbg_printf("--:Theora:- CodecDrawBand(%08lx, %08lx, %08lx) called ( frN: %8ld, dataProc: %8lx)\n",
(long)glob, (long)drp, (long)myDrp, myDrp->frameNumber, (long)dataProc);
- if (myDrp->draw == 0)
- err = codecDroppedFrameErr;
- else {
- th_ycbcr_buffer ycbcrB;
- dbg_printf("--:Theora:- calling theora_decode_YUVout()...\n");
- th_decode_ycbcr_out(glob->td, ycbcrB);
- if (myDrp->pixelFormat == k422YpCbCr8PixelFormat) {
- if (glob->ti.pixel_fmt == TH_PF_420) {
- err = CopyPlanarYCbCr420ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
- } else if (glob->ti.pixel_fmt == TH_PF_422) {
- err = CopyPlanarYCbCr422ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
- } else if (glob->ti.pixel_fmt == TH_PF_444) {
- err = CopyPlanarYCbCr444ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
+ if (myDrp->decoded == 0) {
+ err = Theora_ImageCodecDecodeBand(glob, drp, 0);
+ }
+
+ if (err == noErr) {
+ if (myDrp->draw == 0) {
+ err = codecDroppedFrameErr;
+ } else {
+ th_ycbcr_buffer ycbcrB;
+ dbg_printf("--:Theora:- calling theora_decode_YUVout()...\n");
+ th_decode_ycbcr_out(glob->td, ycbcrB);
+ if (myDrp->pixelFormat == k422YpCbCr8PixelFormat) {
+ if (glob->ti.pixel_fmt == TH_PF_420) {
+ err = CopyPlanarYCbCr420ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
+ } else if (glob->ti.pixel_fmt == TH_PF_422) {
+ err = CopyPlanarYCbCr422ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
+ } else if (glob->ti.pixel_fmt == TH_PF_444) {
+ err = CopyPlanarYCbCr444ToChunkyYUV422(myDrp->width, myDrp->height, ycbcrB, (UInt8 *)drp->baseAddr, drp->rowBytes);
+ } else {
+ dbg_printf("--:Theora:- 'What PLANET is this!?' (%d)\n", glob->ti.pixel_fmt);
+ err = codecBadDataErr;
+ }
+ } else if (myDrp->pixelFormat == kYUV420PixelFormat) {
+ err = CopyPlanarYCbCr422ToPlanarYUV422(ycbcrB, dataProc, (UInt8 *)drp->baseAddr, drp->rowBytes, myDrp->width, myDrp->height);
} else {
- dbg_printf("--:Theora:- 'What PLANET is this!?' (%d)\n", glob->ti.pixel_fmt);
+ dbg_printf("--:Theora:- 'Again, What PLANET is this!?' (%lx)\n", myDrp->pixelFormat);
err = codecBadDataErr;
}
- } else if (myDrp->pixelFormat == kYUV420PixelFormat) {
- err = CopyPlanarYCbCr422ToPlanarYUV422(ycbcrB, dataProc, (UInt8 *)drp->baseAddr, drp->rowBytes, myDrp->width, myDrp->height);
}
}
- //err = noErr;
- //err = codecBadDataErr;
return err;
}
pascal ComponentResult Theora_ImageCodecEndBand(Theora_Globals glob, ImageSubCodecDecompressRecord *drp, OSErr result, long flags)
{
-#pragma unused(glob, drp,result, flags)
+#pragma unused(glob, result, flags)
+ OSErr err = noErr;
+ Theora_DecompressRecord *myDrp = (Theora_DecompressRecord *)drp->userDecompressRecord;
dbg_printf("--:Theora:- CodecEndBand(%08lx, %08lx, %08lx, %08lx) called\n", (long)glob, (long)drp, (long)drp->userDecompressRecord, result);
- return noErr;
+ if (myDrp->draw == 0)
+ err = codecDroppedFrameErr;
+ return err;
}
pascal ComponentResult Theora_ImageCodecQueueStarting(Theora_Globals glob)
Modified: trunk/xiph-qt/Theora/src/TheoraDecoder.r
===================================================================
--- trunk/xiph-qt/Theora/src/TheoraDecoder.r 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/Theora/src/TheoraDecoder.r 2006-05-07 22:39:25 UTC (rev 11370)
@@ -82,9 +82,9 @@
#endif
-#define kTheoraDecoderFlags (codecInfoDoes32 /*| codecInfoDoes16 | codecInfoDoes8 | codecInfoDoes1*/ | codecInfoDoesSpool)
+#define kTheoraDecoderFlags (codecInfoDoes32 | codecInfoDoesTemporal | codecInfoDoesSpool)
-#define kTheoraFormatFlags (codecInfoDepth32 /* ??! */ | codecInfoDepth24)
+#define kTheoraFormatFlags (codecInfoDepth24)
resource 'cdci' (kTheoraDecoderResID) {
kTheoraDecoderFormatName, // Type
Modified: trunk/xiph-qt/Theora/src/TheoraDecoderDispatch.h
===================================================================
--- trunk/xiph-qt/Theora/src/TheoraDecoderDispatch.h 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/Theora/src/TheoraDecoderDispatch.h 2006-05-07 22:39:25 UTC (rev 11370)
@@ -84,8 +84,8 @@
ComponentDelegate (HitTestDataWithFlags)
ComponentDelegate (ValidateParameters)
ComponentDelegate (GetBaseMPWorkFunction)
- ComponentDelegate (0x0026)
- ComponentDelegate (0x0027)
+ ComponentDelegate (LockBits)
+ ComponentDelegate (UnlockBits)
ComponentDelegate (RequestGammaLevel)
ComponentDelegate (GetSourceDataGammaLevel)
ComponentDelegate (0x002A)
@@ -122,10 +122,15 @@
ComponentDelegate (DroppingFrame)
ComponentDelegate (ScheduleFrame)
ComponentDelegate (CancelTrigger)
- ComponentDelegate (0x020A)
- ComponentDelegate (0x020B)
- ComponentDelegate (0x020C)
- ComponentDelegate (0x020D)
- ComponentDelegate (0x020E)
+ //ComponentDelegate (0x020A)
+ //ComponentDelegate (0x020B)
+ //ComponentDelegate (0x020C)
+ //ComponentDelegate (0x020D)
+ //ComponentDelegate (0x020E)
+ ComponentDelegate (0x0A)
+ ComponentDelegate (0x0B)
+ ComponentDelegate (0x0C)
+ ComponentDelegate (0x0D)
+ ComponentDelegate (0x0E)
ComponentCall (DecodeBand)
ComponentRangeEnd (3)
Modified: trunk/xiph-qt/Theora/src/decoder_types.h
===================================================================
--- trunk/xiph-qt/Theora/src/decoder_types.h 2006-05-07 22:29:57 UTC (rev 11369)
+++ trunk/xiph-qt/Theora/src/decoder_types.h 2006-05-07 22:39:25 UTC (rev 11370)
@@ -98,9 +98,8 @@
long dataSize;
long frameNumber;
long draw;
+ long decoded;
OSType pixelFormat;
-
- long _padding_unused;
} Theora_DecompressRecord;
#endif /* __decoder_types_h__ */
More information about the commits
mailing list