예제 #1
0
def ProcessEditDecision(tmpFilePath, edit, width, height):
    """\
    Prefab.
    
    Applies an edit decision - reading in the relevant video frames and applying
    the reframing. Outputs the reframed video frames out of the "outbox" outbox.
    
    Arguments:
    
    - tmpFilePath  -- temp directory into which video frames have been saved
    - edit         -- the edit instruction (dictionary containing: "start","end","left","top","right","bottom")
    - width        -- width (in pixels) for output video frames
    - height       -- height (in pixels) for output video frames
    
    Inboxes:
    
    - "inbox"    -- NOT USED
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- NOT USED
    - "signal"  -- Shutdown signalling
    """
    print " Video segment: ", edit
    filenames = [
        tmpFilePath + "%08d.yuv" % i
        for i in range(edit["start"], edit["end"] + 1)
    ]
    newsize = (width, height)
    cropbounds = (edit["left"], edit["top"], edit["right"], edit["bottom"])

    return Graphline( \
        FILENAMES = ForwardIteratingChooser(filenames),
        FRAME_LOADER = Carousel( lambda filename :
                                 Pipeline(
                                     2, MaxSpeedFileReader(filename,chunksize=1024*1024),
                                     2, YUV4MPEGToFrame(),
                                     ),
                                 make1stRequest=False ),
        REFRAMING = Pipeline( 2, ToRGB_interleaved(),
                              2, CropAndScale(newsize, cropbounds),
                              2, ToYUV420_planar(),
                            ),
        linkages = {
            ("FRAME_LOADER", "requestNext") : ("FILENAMES", "inbox"),

            ("FILENAMES",    "outbox") : ("FRAME_LOADER", "next"),
            ("FRAME_LOADER", "outbox") : ("REFRAMING", "inbox"),
            ("REFRAMING",    "outbox") : ("", "outbox"),

            ("FILENAMES",    "signal") : ("FRAME_LOADER", "control"),
            ("FRAME_LOADER", "signal") : ("REFRAMING", "control"),
            ("REFRAMING",    "signal") : ("", "signal"),
        },
        boxsizes = {
        },
    )
예제 #2
0
def DetermineMaxFrameNumber(edlfile):
    """\
    Prefab.
    
    "outbox" sends out the highest frame number referenced in the EDL xml file.
    Then terminates immediately and sends out a producerFinished() message from
    the "signal" outbox.
    
    Arguments:
    
    - edlfile  -- full filepathname of the EDL xml file
    
    Inboxes:
    
    - "inbox"    -- NOT USED
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- sends out the highest frame number referenced in the EDL file
    - "signal"  -- Shutdown signalling
    """
    return Pipeline(
        RateControlledFileReader(edlfile,readmode="lines",rate=1000000),
        SimpleXMLParser(),
        EDLParser(),
        SimpleDetupler("end"),
        Collate(),
        Max(),
        )
예제 #3
0
def AudioSplitterByFrames(framerate, channels, sample_rate, sample_format,
                          tmpFilePath, edlfile):
    """\
    Prefab.
    
    Saves raw audio data in the specified (chanels,sample_rate,sample_format)
    format sent to the "inbox" inbox into the specified temp
    directory. Chunks the audio into frames, as per the specified frame-rate.
    Only saves those frames actually referenced in the EDL file.
    
    Frames are saved in individual files in WAV format. They are named
    sequentially "00000001.wav", "00000002.wav", "00000003.wav", etc - being
    assigned frame numbers as they arrive, starting at 1.
    
    Arguments:
    
    - frame_rate   -- the frame rate to chunk the audio into for saving
    - channels     -- number of channels in the audio data
    - sample_rate  -- sample rate of the audio data
    - sample_format  -- sample format of the audio data
    - tmpFilePath  -- temp directory into which frames should be saved
    - edlfile      -- full filepathname of the EDL xml file
    
    Inboxes:
    
    - "inbox"    -- raw audio data
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- NOT USED
    - "signal"  -- Shutdown signalling
    """
    from Kamaelia.Support.PyMedia.AudioFormats import format2BytesPerSample

    quantasize = format2BytesPerSample[sample_format] * channels
    audioByteRate = quantasize * sample_rate

    return Pipeline(
        10, RateChunker(datarate=audioByteRate, quantasize=quantasize, chunkrate=framerate),
        1, TagWithSequenceNumber(),
        1, FilterForWantedFrameNumbers(edlfile),
        1, InboxControlledCarousel( lambda (framenum, audiochunk) : \
            Pipeline( 1, OneShot(audiochunk),
                      1, WAVWriter(channels,sample_format,sample_rate),
                      1, SimpleFileWriter(tmpFilePath+("%08d.wav" % framenum)),
                    ),
                    boxsize=1,
            ),
        )
예제 #4
0
def FilterForWantedFrameNumbers(edlfile):
    """\
    Prefab.
    
    Send messages of the form (framenum, data) to the "inbox" inbox. Items with
    a frame number that isn't in the edit decision list are dropped. Other items
    with frame numbers that are in the edit decision list are passed through out
    of the "outbox" outbox.
    
    Arguments:
    
    - edlfile  -- full filepathname of the EDL xml file
    
    Inboxes:
    
    - "inbox"    -- (framenum, data) items to be filtered
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- items not filtered out
    - "signal"  -- Shutdown signalling
    """
    class ExtractRanges(object):
        def filter(self, edit):
            try:
                return (edit['start'],edit['end'])
            except:
                return None
    
    return Graphline(
        RANGESRC = Pipeline(
                       RateControlledFileReader(edlfile,readmode="lines",rate=1000000),
                       SimpleXMLParser(),
                       EDLParser(),
                       Filter(filter = ExtractRanges()),
                       Collate(),
                   ),
        FILTER   = Carousel(lambda ranges : RangeFilter(ranges)),
        linkages = {
            ("RANGESRC","outbox") : ("FILTER","next"),
            
            ("","inbox") : ("FILTER","inbox"),
            ("FILTER","outbox") : ("","outbox"),
            
            ("","control") : ("FILTER","control"),
            ("FILTER","signal") :("","signal"),
        },
        )
예제 #5
0
def PassThroughAudio(edlfile, tmpFilePath):
    """\
    Prefab.
    
    Goes through the specified edit decision list file and reads in the audio
    frames corresponding to the video frames referred to in the reframing
    instructions in sequence. Outputs the audio frames out of the "outbox"
    outbox.
    
    Arguments:
    
    - edlfile      -- full filepathname of the EDL xml file
    - tmpFilePath  -- temp directory into which video frames have been saved
    
    Inboxes:
    
    - "inbox"    -- NOT USED
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- raw audio data, chunked by frames
    - "signal"  -- Shutdown signalling
    """
    backplane_name = "AUDIO_FORMAT"
    return Graphline( \
        GET_EDL = EditDecisionSource(edlfile),
        AUDIO = Carousel( lambda edit : PassThroughAudioSegment(tmpFilePath, edit, backplane_name),
                          make1stRequest=True),
        
        BACKPLANE = Backplane(backplane_name),
        AUDIOFORMAT = Pipeline( SubscribeTo(backplane_name), FirstOnly() ),
        
        linkages = {
            ("AUDIO", "requestNext") : ("GET_EDL", "inbox"),
            
            ("GET_EDL", "outbox") : ("AUDIO", "next"),
            
            ("AUDIO", "outbox") : ("", "outbox"),
            
            ("AUDIOFORMAT", "outbox") : ("", "audioformat"),
            
            ("GET_EDL", "signal") : ("AUDIO", "control"),
            ("AUDIO", "signal") : ("AUDIOFORMAT", "control"),
            ("AUDIOFORMAT", "signal") : ("BACKPLANE", "control"),
            ("BACKPLANE", "signal") : ("", "signal"),
        },
        )
예제 #6
0
def EditDecisionSource(edlfile):
    """\
    Prefab.
    
    Reads in the edit decisions from the edit decision list file; then sends
    then out, one at a time, out of the "outbox" outbox whenever a message is
    sent to the "inbox" inbox. The message sent to the inbox does not matter.
    
    Edit decisions are of the form::
    
        { "start"  : start frame number for this edit decision
          "end"    : end frame number for this edit decision
          "left"   : left edge to crop to (in pixels)
          "top"    : top edge to crop to (in pixels)
          "right"  : right edge to crop to (in pixels)
          "bottom" : bottom edge to crop to (in pixels)
        }
    
    Arguments:
    
    - edlfile      -- full filepathname of the EDL xml file
    
    Inboxes:
    
    - "inbox"    -- Messages to trigger sending out of edit decisions
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- Individual edit decisions
    - "signal"  -- Shutdown signalling
    """
    return Graphline( \
        PARSING = Pipeline( RateControlledFileReader(edlfile,readmode="lines",rate=1000000),
                            SimpleXMLParser(),
                            EDLParser(),
                          ),
        GATE = PromptedTurnstile(),
        linkages = {
            ("", "inbox") : ("GATE", "next"),

            ("PARSING", "outbox") : ("GATE", "inbox"),
            ("GATE",    "outbox") : ("",     "outbox"),
            
            ("PARSING", "signal") : ("GATE", "control"),
            ("GATE",    "signal") : ("", "signal"),

        } )
예제 #7
0
def SaveVideoFrames(tmpFilePath,edlfile):
    """\
    Prefab.
    
    Saves video frames sent to the "inbox" inbox into the specified temp
    directory. Only saves those frames actually referenced in the EDL file.
    
    Frames are saved in individual files in YUV4MPEG2 format. They are named
    sequentially "00000001.yuv", "00000002.yuv", "00000003.yuv", etc - being
    assigned frame numbers as they arrive, starting at 1.
    
    Arguments:
    
    - tmpFilePath  -- temp directory into which frames should be saved
    - edlfile      -- full filepathname of the EDL xml file
    
    Inboxes:
    
    - "inbox"    -- video frames to be saved
    - "control"  -- Shutdown signalling
    
    Outboxes:
    
    - "outbox"  -- NOT USED
    - "signal"  -- Shutdown signalling
    """
    return \
        Pipeline(
            1, TagWithSequenceNumber(),
            1, FilterForWantedFrameNumbers(edlfile),
            1, InboxControlledCarousel( lambda (framenum, frame) : \
                Pipeline( OneShot(frame),
                          1, FrameToYUV4MPEG(),
                          1, SimpleFileWriter(tmpFilePath+("%08d.yuv" % framenum)),
                        ),
                boxsize=1,
                ),
        )
예제 #8
0
    )


Graphline(
    DECODE=UnixProcess2(
        "ffmpeg -i " + infile +
        " -f yuv4mpegpipe -y vidpipe.yuv -f wav -y audpipe.wav",
        outpipes={
            "vidpipe.yuv": "video",
            "audpipe.wav": "audio"
        },
        buffersize=131072,
    ),
    VIDEO=Pipeline(
        1,
        YUV4MPEGToFrame(),
        FrameRateLimitedPlayback(VideoOverlay()),
    ),
    AUDIO=Graphline(
        PARSE=WAVParser(),
        OUT=Carousel(lambda format: Output(format['sample_rate'],
                                           format['channels'],
                                           format['sample_format'],
                                           maximumLag=0.5)),
        linkages={
            ("", "inbox"): ("PARSE", "inbox"),
            ("PARSE", "outbox"): ("OUT", "inbox"),
            ("PARSE", "all_meta"): ("OUT", "next"),
            ("", "control"): ("PARSE", "control"),
            ("PARSE", "signal"): ("OUT", "control"),
            ("OUT", "signal"): ("", "signal"),
예제 #9
0
            " [--show] [threshold] videofile\n\n* threshold is a floating point value greater than zero (default=0.9)\n\n"
        )
        sys.exit(1)

    infile = files[0].replace(" ", "\ ")

    if not show:
        # simple cut detector

        Pipeline(
            UnixProcess2(
                "ffmpeg -i " + infile + " -f yuv4mpegpipe -y /dev/stdout",
                32768),
            2,
            YUV4MPEGToFrame(),
            1,
            TagWithSequenceNumber(),
            1,
            DetectShotChanges(threshold),
            FormatOutput(),
            ConsoleEchoer(),
            StopSelector(waitForTrigger=True),
        ).run()

    else:
        # cut detector plus playback at the same time

        from Kamaelia.UI.Pygame.Display import PygameDisplay
        from Kamaelia.UI.Pygame.VideoOverlay import VideoOverlay
        from Kamaelia.Util.Backplane import Backplane, PublishTo, SubscribeTo
        from Kamaelia.Util.RateFilter import MessageRateLimit
예제 #10
0
    
    class SlowOutputter(threadedcomponent):
        def __init__(self):
            super(SlowOutputter,self).__init__(queuelengths=1)
            
        Outboxes = { "outbox" : "",
                        "signal" : "",
                        "reqNext" : "",
                    }
        def main(self):
            while 1:
                
                if self.dataReady("inbox"):
                    print self.recv("inbox")

                    t=time.time()+0.2
                    while t>time.time():
                        self.pause(t-time.time())

                else:
                    if self.dataReady("control"):
                        self.send(self.recv("control"), "signal")
                        return

                
    Pipeline(    MaxSpeedFileReader("TestEDL.xml",chunksize=128),
              1, SimpleXMLParser(),
              1, SlowOutputter(),
            ).run()

예제 #11
0
                yield 1


__kamaelia_components__ = (TwoWaySplitter, )

if __name__ == "__main__":
    from Kamaelia.Experimental.Chassis import Graphline, Pipeline
    from Kamaelia.Util.DataSource import DataSource
    from Kamaelia.Util.RateFilter import MessageRateLimit
    from Kamaelia.Util.Console import ConsoleEchoer

    Graphline(SRC=DataSource([str(i) + "\n" for i in range(0, 100)]),
              SPLIT=TwoWaySplitter(),
              DST1=Pipeline(
                  10,
                  MessageRateLimit(10, 5),
                  ConsoleEchoer(),
              ),
              DST2=Pipeline(
                  10,
                  MessageRateLimit(20, 5),
                  ConsoleEchoer(),
              ),
              linkages={
                  ("SRC", "outbox"): ("SPLIT", "inbox"),
                  ("SPLIT", "outbox"): ("DST1", "inbox"),
                  ("SPLIT", "outbox2"): ("DST2", "inbox"),
                  ("SRC", "signal"): ("SPLIT", "control"),
                  ("SPLIT", "signal"): ("DST1", "control"),
                  ("SPLIT", "signal2"): ("DST2", "control"),
              },