[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