Changeset 86

Show
Ignore:
Timestamp:
09/19/06 23:54:03 (2 years ago)
Author:
dconrad
Message:

FFmpeg now builds a partial index for flv files, which isn't usable to us for now, so force flv files to import as though they don't have an index. Fixes #8

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ff_MovieImport.c

    r72 r86  
    334334        TimeRecord time; 
    335335        int i; 
     336        short hadIndex = 0; 
    336337         
    337338        /* make sure that in case of error, the flag movieImportResultComplete is not set */ 
     
    417418        /* Import the Data*/ 
    418419        /* FIXME: Implement the progress upp */ 
    419         import_avi(ic, map, dataOffset); 
     420        /* note: flv builds a partial index that's unusable, so force importing without an index */ 
     421        if (!(storage->componentType == 'FLV ')) 
     422                hadIndex = import_avi(ic, map, dataOffset); 
     423         
     424        if (!hadIndex) 
     425                import_without_index(ic, map, dataOffset); 
    420426         
    421427        /* Insert the Medias into the Tracks */ 
  • trunk/ff_private.c

    r74 r86  
    527527/* This function imports the avi represented by the AVFormatContext to the movie media represented 
    528528 * in the map function. The aviheader_offset is used to calculate the packet offset from the 
    529  * beginning of the file */ 
    530 void import_avi(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset) 
     529 * beginning of the file. It returns whether it was successful or not (i.e. whether the file had an index) */ 
     530short import_avi(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset) 
    531531{ 
    532532        int j, k, l; 
     
    620620                } 
    621621        } 
    622         if(hadIndex == 0) 
     622        return hadIndex; 
     623} /* import_avi() */ 
     624 
     625/* This function imports the video file using standard av_read_frame() calls,  
     626 * which works on files that don't have an index */ 
     627void import_without_index(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset) 
     628
     629        int i; 
     630        NCStream *ncstr; 
     631        AVStream *stream; 
     632        AVCodecContext *codec; 
     633        SampleReference64Record sampleRec; 
     634        short flags; 
     635        AVPacket pkt; 
     636         
     637        while(av_read_frame(ic, &pkt) == noErr) 
    623638        { 
    624                 AVPacket pkt; 
    625                 while(av_read_frame(ic, &pkt) == noErr) 
     639                ncstr = &map[pkt.stream_index]; 
     640                stream = ncstr->str; 
     641                codec = stream->codec; 
     642                 
     643                flags = 0; 
     644                if((pkt.flags & PKT_FLAG_KEY) == 0) 
     645                        flags |= mediaSampleNotSync; 
     646                 
     647                memset(&sampleRec, 0, sizeof(sampleRec)); 
     648                sampleRec.dataOffset.hi = pkt.pos >> 32; 
     649                sampleRec.dataOffset.lo = (uint32_t) pkt.pos; 
     650                sampleRec.dataSize = pkt.size; 
     651                sampleRec.sampleFlags = flags; 
     652                 
     653                if(sampleRec.dataSize <= 0) 
     654                        continue; 
     655                 
     656                if (codec->codec_type == CODEC_TYPE_AUDIO && !ncstr->vbr) 
     657                        sampleRec.numberOfSamples = (pkt.size * ncstr->asbd.mFramesPerPacket) / ncstr->asbd.mBytesPerPacket; 
     658                else 
     659                        sampleRec.numberOfSamples = 1; 
     660                 
     661                // we have a sample waiting to be added; calculate the duration and add it 
     662                if (ncstr->lastSample.numberOfSamples > 0) { 
     663                        ncstr->lastSample.durationPerSample = (pkt.pts - ncstr->lastpts) * ncstr->base.num; 
     664                        AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &ncstr->lastSample, NULL); 
     665                } 
     666                 
     667                if (pkt.duration == 0) { 
     668                        // no duration, we'll have to wait for the next packet to calculate it 
     669                        // keep the duration of the last sample, so we can use it if it's the last frame 
     670                        sampleRec.durationPerSample = ncstr->lastSample.durationPerSample; 
     671                        ncstr->lastSample = sampleRec; 
     672                        ncstr->lastpts = pkt.pts; 
     673                         
     674                } else { 
     675                        ncstr->lastSample.numberOfSamples = 0; 
     676                        if (codec->codec_type == CODEC_TYPE_AUDIO && !ncstr->vbr) 
     677                                sampleRec.durationPerSample = 1; 
     678                        else 
     679                                sampleRec.durationPerSample = pkt.duration * ncstr->base.num; 
     680                        AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &sampleRec, NULL); 
     681                } 
     682#if 0 
     683                if(codec->codec_type == CODEC_TYPE_VIDEO) 
    626684                { 
    627                         ncstr = &map[pkt.stream_index]; 
    628                         stream = ncstr->str; 
    629                         codec = stream->codec; 
    630                          
    631                         flags = 0; 
    632                         if((pkt.flags & PKT_FLAG_KEY) == 0) 
    633                                 flags |= mediaSampleNotSync; 
    634                          
    635                         memset(&sampleRec, 0, sizeof(sampleRec)); 
    636                         sampleRec.dataOffset.hi = pkt.pos >> 32; 
    637                         sampleRec.dataOffset.lo = (uint32_t) pkt.pos; 
    638                         sampleRec.dataSize = pkt.size; 
    639                         sampleRec.sampleFlags = flags; 
    640                          
    641                         if(sampleRec.dataSize <= 0) 
    642                                 continue; 
    643                          
    644                         if (codec->codec_type == CODEC_TYPE_AUDIO && !ncstr->vbr) 
     685                        if(pkt.duration == 0) 
     686                                sampleRec.durationPerSample = map->base.num; 
     687                        else 
     688                                sampleRec.durationPerSample = map->base.num * pkt.duration; 
     689                        sampleRec.numberOfSamples = 1; 
     690                } 
     691                else if (codec->codec_type == CODEC_TYPE_AUDIO) 
     692                { 
     693                        if(ncstr->vbr) { 
     694                                if(codec->frame_size == ncstr->base.num) { 
     695                                        sampleRec.durationPerSample = codec->frame_size; 
     696                                        sampleRec.numberOfSamples = 1; 
     697                                } else if (ncstr->asbd.mFormatID == kAudioFormatMPEG4AAC) { 
     698                                        /* AVI-mux GUI, the author of which created this hack in the first place, 
     699                                        * seems to special-case getting an AAC audio sample's duration this way */ 
     700                                        sampleRec.durationPerSample = ic->streams[pkt.stream_index]->time_base.num; 
     701                                        sampleRec.numberOfSamples = 1; 
     702                                } else { 
     703                                        /* This seems to work. Although I have no idea why. 
     704                                        * Perhaps the stream's timebase is adjusted to 
     705                                        * let that work. as the timebase has strange values...*/ 
     706                                        sampleRec.durationPerSample = sampleRec.dataSize; 
     707                                        sampleRec.numberOfSamples = 1; 
     708                                } 
     709                        } else { 
     710                                sampleRec.durationPerSample = 1; 
    645711                                sampleRec.numberOfSamples = (pkt.size * ncstr->asbd.mFramesPerPacket) / ncstr->asbd.mBytesPerPacket; 
    646                         else 
    647                                 sampleRec.numberOfSamples = 1; 
    648                                  
    649                         // we have a sample waiting to be added; calculate the duration and add it 
    650                         if (ncstr->lastSample.numberOfSamples > 0) { 
    651                                 ncstr->lastSample.durationPerSample = (pkt.pts - ncstr->lastpts) * ncstr->base.num; 
    652                                 AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &ncstr->lastSample, NULL); 
    653712                        } 
    654                          
    655                         if (pkt.duration == 0) { 
    656                                 // no duration, we'll have to wait for the next packet to calculate it 
    657                                 // keep the duration of the last sample, so we can use it if it's the last frame 
    658                                 sampleRec.durationPerSample = ncstr->lastSample.durationPerSample; 
    659                                 ncstr->lastSample = sampleRec; 
    660                                 ncstr->lastpts = pkt.pts; 
    661                                  
    662                         } else { 
    663                                 ncstr->lastSample.numberOfSamples = 0; 
    664                                 if (codec->codec_type == CODEC_TYPE_AUDIO && !ncstr->vbr) 
    665                                         sampleRec.durationPerSample = 1; 
    666                                 else 
    667                                         sampleRec.durationPerSample = pkt.duration * ncstr->base.num; 
    668                                 AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &sampleRec, NULL); 
    669                         } 
    670 #if 0 
    671                         if(codec->codec_type == CODEC_TYPE_VIDEO) 
    672                         { 
    673                                 if(pkt.duration == 0) 
    674                                         sampleRec.durationPerSample = map->base.num; 
    675                                 else 
    676                                         sampleRec.durationPerSample = map->base.num * pkt.duration; 
    677                                 sampleRec.numberOfSamples = 1; 
    678                         } 
    679                         else if (codec->codec_type == CODEC_TYPE_AUDIO) 
    680                         { 
    681                                 if(ncstr->vbr) { 
    682                                         if(codec->frame_size == ncstr->base.num) { 
    683                                                 sampleRec.durationPerSample = codec->frame_size; 
    684                                                 sampleRec.numberOfSamples = 1; 
    685                                         } else if (ncstr->asbd.mFormatID == kAudioFormatMPEG4AAC) { 
    686                                                 /* AVI-mux GUI, the author of which created this hack in the first place, 
    687                                                 * seems to special-case getting an AAC audio sample's duration this way */ 
    688                                                 sampleRec.durationPerSample = ic->streams[pkt.stream_index]->time_base.num; 
    689                                                 sampleRec.numberOfSamples = 1; 
    690                                         } else { 
    691                                                 /* This seems to work. Although I have no idea why. 
    692                                                 * Perhaps the stream's timebase is adjusted to 
    693                                                 * let that work. as the timebase has strange values...*/ 
    694                                                 sampleRec.durationPerSample = sampleRec.dataSize; 
    695                                                 sampleRec.numberOfSamples = 1; 
    696                                         } 
    697                                 } else { 
    698                                         sampleRec.durationPerSample = 1; 
    699                                         sampleRec.numberOfSamples = (pkt.size * ncstr->asbd.mFramesPerPacket) / ncstr->asbd.mBytesPerPacket; 
    700                                 } 
    701                         } 
    702                         err = AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &sampleRec, NULL); 
     713                } 
     714                err = AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &sampleRec, NULL); 
    703715#endif 
    704                         //Need to do something like this when the libavformat doesn't give us a position 
    705 /*                      Handle dataIn = NewHandle(pkt.size); 
    706                         HLock(dataIn); 
    707                         memcpy(*dataIn, pkt.data, pkt.size); 
    708                         HUnlock(dataIn); 
    709                         err = AddMediaSample(ncstr->media, dataIn, 0, pkt.size, 1, ncstr->sampleHdl, pkt.duration, sampleRec.sampleFlags, NULL);*/ 
    710                         av_free_packet(&pkt); 
    711                 } 
    712                 // import the last frames 
    713                 for (j = 0; j < ic->nb_streams; j++) { 
    714                         ncstr = &map[j]; 
    715                         if (ncstr->lastSample.numberOfSamples > 0) 
    716                                 AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &ncstr->lastSample, NULL); 
    717                 } 
    718         } 
    719 } /* import_avi() */ 
     716                //Need to do something like this when the libavformat doesn't give us a position 
     717                /*                      Handle dataIn = NewHandle(pkt.size); 
     718                HLock(dataIn); 
     719                memcpy(*dataIn, pkt.data, pkt.size); 
     720                HUnlock(dataIn); 
     721                err = AddMediaSample(ncstr->media, dataIn, 0, pkt.size, 1, ncstr->sampleHdl, pkt.duration, sampleRec.sampleFlags, NULL);*/ 
     722                av_free_packet(&pkt); 
     723        } 
     724        // import the last frames 
     725        for (i = 0; i < ic->nb_streams; i++) { 
     726                ncstr = &map[i]; 
     727                if (ncstr->lastSample.numberOfSamples > 0) 
     728                        AddMediaSampleReferences64(ncstr->media, ncstr->sampleHdl, 1, &ncstr->lastSample, NULL); 
     729        } 
     730
  • trunk/ff_private.h

    r74 r86  
    5656void initialize_audio_map(NCStream *map, Track targetTrack, Handle dataRef, OSType dataRefType); 
    5757 
    58 void import_avi(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset); 
     58short import_avi(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset); 
     59void import_without_index(AVFormatContext *ic, NCStream *map, int64_t aviheader_offset); 
    5960 
    6061OSType map_video_codec_to_mov_tag(enum CodecID codec_id);