Changeset 466


Ignore:
Timestamp:
23-05-11 16:57:16 (2 years ago)
Author:
thomas
Message:
  • morituri/test/test_common_encode.py: Generate an actual file by spawning gst-launch; otherwise with proper error handling we get an error from wavparse that there is not enough data to typefind.
  • morituri/common/gstreamer.py: Move the gst import to start() and set it as a class attribute. Document methods.
  • morituri/common/encode.py: Convert EncodeTask? to a GstPipelineTask?.
Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r465 r466  
     12011-05-23  Thomas Vander Stichele  <thomas at apestaart dot org> 
     2 
     3        * morituri/test/test_common_encode.py: 
     4          Generate an actual file by spawning gst-launch; otherwise 
     5          with proper error handling we get an error from wavparse that 
     6          there is not enough data to typefind. 
     7        * morituri/common/gstreamer.py: 
     8          Move the gst import to start() and set it as a class attribute. 
     9          Document methods. 
     10        * morituri/common/encode.py: 
     11          Convert EncodeTask to a GstPipelineTask. 
     12 
    1132011-05-23  Thomas Vander Stichele  <thomas at apestaart dot org> 
    214 
  • trunk/morituri/common/encode.py

    r465 r466  
    2626import tempfile 
    2727 
    28 from morituri.common import common, task, log 
     28from morituri.common import common, task, log, gstreamer 
    2929 
    3030class Profile(object): 
     
    123123ALL_PROFILES.update(LOSSY_PROFILES) 
    124124 
    125 class EncodeTask(task.Task): 
     125class EncodeTask(gstreamer.GstPipelineTask): 
    126126    """ 
    127127    I am a task that encodes a .wav file. 
     
    159159        self._profile.test() 
    160160 
    161     def start(self, runner): 
    162         task.Task.start(self, runner) 
    163  
    164         # here to avoid import gst eating our options 
    165         import gst 
    166  
    167         desc = ''' 
     161    def getPipelineDesc(self): 
     162        return ''' 
    168163            filesrc location="%s" ! 
    169164            decodebin name=decoder ! 
     
    176171                common.quoteParse(self._outpath).encode('utf-8')) 
    177172 
    178         self.debug('creating pipeline: %r', desc) 
    179         self._pipeline = gst.parse_launch(desc) 
    180  
    181         tagger = self._pipeline.get_by_name('tagger') 
     173    def parsed(self): 
     174        tagger = self.pipeline.get_by_name('tagger') 
    182175 
    183176        # set tags 
     
    186179            # See for example comment saying wavenc did not have it. 
    187180            try: 
    188                 tagger.merge_tags(self._taglist, gst.TAG_MERGE_APPEND) 
     181                tagger.merge_tags(self._taglist, self.gst.TAG_MERGE_APPEND) 
    189182            except AttributeError, e: 
    190183                self.warning('Could not merge tags: %r', 
    191184                    log.getExceptionMessage(e)) 
    192185 
    193         self.debug('pausing pipeline') 
    194         self._pipeline.set_state(gst.STATE_PAUSED) 
    195         self._pipeline.get_state() 
    196         self.debug('paused pipeline') 
    197  
     186    def paused(self): 
    198187        # get length 
    199         identity = self._pipeline.get_by_name('identity') 
     188        identity = self.pipeline.get_by_name('identity') 
    200189        self.debug('query duration') 
    201190        try: 
    202             length, qformat = identity.query_duration(gst.FORMAT_DEFAULT) 
    203         except gst.QueryError, e: 
     191            length, qformat = identity.query_duration(self.gst.FORMAT_DEFAULT) 
     192        except self.gst.QueryError, e: 
    204193            self.setException(e) 
    205194            self.stop() 
     
    207196 
    208197        # wavparse 0.10.14 returns in bytes 
    209         if qformat == gst.FORMAT_BYTES: 
     198        if qformat == self.gst.FORMAT_BYTES: 
    210199            self.debug('query returned in BYTES format') 
    211200            length /= 4 
     
    213202        self._length = length 
    214203 
    215         # add eos handling 
    216         bus = self._pipeline.get_bus() 
     204        # set up level callbacks 
     205        # FIXME: publicize bus and reuse it instead of regetting and adding ? 
     206        bus = self.pipeline.get_bus() 
    217207        bus.add_signal_watch() 
    218         bus.connect('message::eos', self._message_eos_cb) 
    219  
    220         # set up level callbacks 
     208 
    221209        bus.connect('message::element', self._message_element_cb) 
    222         self._level = self._pipeline.get_by_name('level') 
     210        self._level = self.pipeline.get_by_name('level') 
    223211        # add a probe so we can track progress 
    224212        # we connect to level because this gives us offset in samples 
     
    226214        srcpad.add_buffer_probe(self._probe_handler) 
    227215 
     216        # FIXME: move to base class ? 
    228217        self.debug('scheduling setting to play') 
    229218        # since set_state returns non-False, adding it as timeout_add 
    230219        # will repeatedly call it, and block the main loop; so 
    231         #   gobject.timeout_add(0L, self._pipeline.set_state, gst.STATE_PLAYING) 
     220        #   gobject.timeout_add(0L, self.pipeline.set_state, self.gst.STATE_PLAYING) 
    232221        # would not work. 
    233222 
    234223        def play(): 
    235             self._pipeline.set_state(gst.STATE_PLAYING) 
     224            self.pipeline.set_state(self.gst.STATE_PLAYING) 
    236225            return False 
    237226        self.runner.schedule(0, play) 
    238227 
    239         #self._pipeline.set_state(gst.STATE_PLAYING) 
     228        #self.pipeline.set_state(gst.STATE_PLAYING) 
    240229        self.debug('scheduled setting to play') 
    241230 
     
    250239        return True 
    251240 
    252     def _message_eos_cb(self, bus, message): 
     241    def bus_eos_cb(self, bus, message): 
    253242        self.debug('eos, scheduling stop') 
    254243        self.runner.schedule(0, self.stop) 
     
    271260                self._peakdB = p 
    272261 
     262    # FIXME: move to base class, have stopped handler ? 
    273263    def stop(self): 
    274         # here to avoid import gst eating our options 
    275         import gst 
    276  
    277264        self.debug('stopping') 
    278265        self.debug('setting state to NULL') 
    279         self._pipeline.set_state(gst.STATE_NULL) 
     266        self.pipeline.set_state(self.gst.STATE_NULL) 
    280267        self.debug('set state to NULL') 
    281268        # FIXME: maybe this should move lower ? If used by BaseMultiTask, 
  • trunk/morituri/common/gstreamer.py

    r457 r466  
    2121# along with morituri.  If not, see <http://www.gnu.org/licenses/>. 
    2222 
    23 import gst 
    24  
    2523from morituri.common import common, task 
    2624 
     
    3634 
    3735    I handle errors and raise them appropriately. 
     36 
     37    @cvar gst: the GStreamer module, so code does not have to import gst 
     38               as a module in code everywhere to avoid option stealing. 
    3839    """ 
     40 
     41    gst = None 
     42 
    3943    def start(self, runner): 
     44        import gst 
     45        self.gst = gst 
     46 
    4047        task.Task.start(self, runner) 
    4148        desc = self.getPipelineDesc() 
    4249 
    4350        self.debug('creating pipeline %r', desc) 
    44         self.pipeline = gst.parse_launch(desc) 
     51        self.pipeline = self.gst.parse_launch(desc) 
    4552 
    4653        self._bus = self.pipeline.get_bus() 
    47         gst.debug('got bus %r' % self._bus) 
     54        self.gst.debug('got bus %r' % self._bus) 
    4855 
    4956        # a signal watch calls callbacks from an idle loop 
     
    6067 
    6168        self.debug('pausing pipeline') 
    62         self.pipeline.set_state(gst.STATE_PAUSED) 
     69        self.pipeline.set_state(self.gst.STATE_PAUSED) 
    6370        # FIXME: this can block 
    6471        self.pipeline.get_state() 
     
    8693 
    8794    def bus_eos_cb(self, bus, message): 
     95        """ 
     96        Called synchronously (ie from messaging thread) on eos message. 
     97 
     98        Override me to handle eos 
     99        """ 
    88100        pass 
    89101 
    90102    def bus_tag_cb(self, bus, message): 
     103        """ 
     104        Called synchronously (ie from messaging thread) on tag message. 
     105 
     106        Override me to handle tags. 
     107        """ 
    91108        pass 
    92109 
    93110    def bus_error_cb(self, bus, message): 
     111        """ 
     112        Called synchronously (ie from messaging thread) on error message. 
     113        """ 
    94114        exc = GstException(*message.parse_error()) 
    95115        self.setAndRaiseException(exc) 
    96         gst.debug('error, scheduling stop') 
     116        # FIXME: why is this commented ? 
     117        # self.gst.debug('error, scheduling stop') 
    97118        #self.runner.schedule(0, self.stop) 
  • trunk/morituri/test/test_common_encode.py

    r401 r466  
    1010import gst 
    1111 
    12 from morituri.test import common 
     12from morituri.test import common as tcommon 
    1313 
    14 from morituri.common import task, encode, log 
     14from morituri.common import task, encode, log, common 
    1515 
    16 class PathTestCase(common.TestCase): 
     16class PathTestCase(tcommon.TestCase): 
    1717    def _testSuffix(self, suffix): 
    1818        self.runner = task.SyncRunner(verbose=False) 
    19         fd, path = tempfile.mkstemp( 
    20             suffix=suffix) 
     19        fd, path = tempfile.mkstemp(suffix=suffix) 
     20        cmd = "gst-launch " \ 
     21            "audiotestsrc num-buffers=100 samplesperbuffer=1024 ! " \ 
     22            "audioconvert ! audio/x-raw-int,width=16,depth=16,channels =2 ! " \ 
     23            "wavenc ! " \ 
     24            "filesink location=\"%s\" > /dev/null 2>&1" % ( 
     25            common.quoteParse(path).encode('utf-8'), ) 
     26        os.system(cmd) 
     27        self.failUnless(os.path.exists(path)) 
    2128        encodetask = encode.EncodeTask(path, path + '.out', 
    2229            encode.WavProfile()) 
    23         e = self.assertRaises(task.TaskException, self.runner.run, 
    24             encodetask, verbose=False) 
    25         self.failUnless(isinstance(e.exception, gst.QueryError), 
    26             "%r is not a gst.QueryError" % e.exception) 
     30        self.runner.run(encodetask, verbose=False) 
    2731        os.close(fd) 
    2832        os.unlink(path) 
    2933        os.unlink(path + '.out') 
    3034 
    31 class UnicodePathTestCase(PathTestCase, common.UnicodeTestMixin): 
     35class UnicodePathTestCase(PathTestCase, tcommon.UnicodeTestMixin): 
    3236    def testUnicodePath(self): 
    3337        # this test makes sure we can checksum a unicode path 
     
    4145        self._testSuffix(u'.morituri.test_encode.12" edit') 
    4246 
    43 class TagReadTestCase(common.TestCase): 
     47class TagReadTestCase(tcommon.TestCase): 
    4448    def testRead(self): 
    4549        path = os.path.join(os.path.dirname(__file__), u'track.flac') 
     
    5155        self.assertEquals(t.taglist['description'], 'audiotest wave') 
    5256 
    53 class TagWriteTestCase(common.TestCase): 
     57class TagWriteTestCase(tcommon.TestCase): 
    5458    def testWrite(self): 
    5559        fd, inpath = tempfile.mkstemp(suffix=u'.morituri.tagwrite.flac') 
     
    8286        os.unlink(outpath) 
    8387         
    84 class SafeRetagTestCase(common.TestCase): 
     88class SafeRetagTestCase(tcommon.TestCase): 
    8589    def setUp(self): 
    8690        self._fd, self._path = tempfile.mkstemp(suffix=u'.morituri.retag.flac') 
Note: See TracChangeset for help on using the changeset viewer.