def _updateFilter(self, blockPad): def unlinkAndReplace(pad, blocked): self._videoscaler.set_state(gst.STATE_NULL) self._capsfilter.set_state(gst.STATE_NULL) self._videobox.set_state(gst.STATE_NULL) self._configureOutput() self._videobox.set_state(gst.STATE_PLAYING) self._videoscaler.set_state(gst.STATE_PLAYING) self._capsfilter.set_state(gst.STATE_PLAYING) # unlink the sink and source pad of the old deinterlacer reactor.callFromThread(blockPad.set_blocked, False) self._sinkPad.send_event(gstreamer.flumotion_reset_event()) # We might be called from the streaming thread self.info("Replaced capsfilter") reactor.callFromThread(blockPad.set_blocked_async, True, unlinkAndReplace)
def _updateFilter(self, blockPad): def unlinkAndReplace(pad, blocked): self._videoscaler.set_state(gst.STATE_NULL) self._capsfilter.set_state(gst.STATE_NULL) self._videobox.set_state(gst.STATE_NULL) self._configureOutput() self._videobox.set_state(gst.STATE_PLAYING) self._videoscaler.set_state(gst.STATE_PLAYING) self._capsfilter.set_state(gst.STATE_PLAYING) # unlink the sink and source pad of the old deinterlacer reactor.callFromThread(blockPad.set_blocked, False) self._sinkPad.send_event(gstreamer.flumotion_reset_event()) # We might be called from the streaming thread self.info("Replaced capsfilter") reactor.callFromThread(blockPad.set_blocked_async, True, unlinkAndReplace)
def _send_reset_event(self): for elem in self.get_output_elements(): pad = elem.get_pad('sink') pad.send_event(gstreamer.flumotion_reset_event())
def modify_element_property(self, element_name, property_name, value, mutable_state=Gst.State.READY, needs_reset=False): ''' Sets a property on the fly on a gstreamer element @param element_name: Name of the gstreamer element @type element_name: str @param property_name: Name of the property to change @type property_name: str @param value: Value to set @param mutable_state: Minimum state required to set the property @type mutable_state: L{Gst.Enum} @param needs_reset: Whether setting this property requires sending a 'flumotion-reset' event @type needs_reset: bool ''' def drop_stream_headers(pad, buf): if buf.flag_is_set(Gst.BUFFER_FLAG_IN_CAPS): return False pad.remove_probe(probes[pad]) return True probes = {} element = self.get_element(element_name) if not element: self.warning("The property %s cannot be set because the " "element %s could not be found", property_name, element_name) return state = self.pipeline.get_state(0)[1] # get the peer pad for each sink pad sink_pads = [p.get_peer() for p in element.pads() if p.get_direction() == Gst.PAD_SINK] src_pads = [p for p in element.pads() if p.get_direction() == Gst.PAD_SRC] # Iterate over all the sink pads and block them for pad in sink_pads: pad.set_blocked(True) # If the state of the element is above the mutable state of the # property, we need to change its state to the mutable one, block the # sink pads, set the property, unblock the sink pads and set the # element's state back to its original state if state > mutable_state: element.set_state(mutable_state) element.get_state(0) element.set_property(property_name, value) # If the property change cause creating new streamheaders, # sending a 'flumotion-reset' event is needed to instruct the # downstream elements like muxers to reset them self if needs_reset: for pad in src_pads: pad.push_event(gstreamer.flumotion_reset_event()) # If a reset is not needed we must make sure to drop the duplicated # streamheaders, iterating over all the src pads and installing a # pad_probe to drop them. (eg: theora restarted after a bitrate change # re-sending the headers again) else: for pad in src_pads: probes[pad] = pad.add_probe(Gst.PadProbeType.BUFFER, drop_stream_headers, None) if state > mutable_state: element.set_state(state) # Unblock all sink pads for pad in sink_pads: pad.set_blocked(False)
def _on_connected(self, element): self.info("FGDP producer connected") pad = self.get_element('src').get_pad('src') pad.push_event(gstreamer.flumotion_reset_event())
def modify_element_property(self, element_name, property_name, value, mutable_state=gst.STATE_READY, needs_reset=False): ''' Sets a property on the fly on a gstreamer element @param element_name: Name of the gstreamer element @type element_name: str @param property_name: Name of the property to change @type property_name: str @param value: Value to set @param mutable_state: Minimum state required to set the property @type mutable_state: L{gst.Enum} @param needs_reset: Whether setting this property requires sending a 'flumotion-reset' event @type needs_reset: bool ''' def drop_stream_headers(pad, buf): if buf.flag_is_set(gst.BUFFER_FLAG_IN_CAPS): return False pad.remove_buffer_probe(probes[pad]) return True probes = {} element = self.get_element(element_name) if not element: self.warning( "The property %s cannot be set because the " "element %s could not be found", property_name, element_name) return state = self.pipeline.get_state(0)[1] # get the peer pad for each sink pad sink_pads = [ p.get_peer() for p in element.pads() if p.get_direction() == gst.PAD_SINK ] src_pads = [ p for p in element.pads() if p.get_direction() == gst.PAD_SRC ] # Iterate over all the sink pads and block them for pad in sink_pads: pad.set_blocked(True) # If the state of the element is above the mutable state of the # property, we need to change its state to the mutable one, block the # sink pads, set the property, unblock the sink pads and set the # element's state back to its original state if state > mutable_state: element.set_state(mutable_state) element.get_state(0) element.set_property(property_name, value) # If the property change cause creating new streamheaders, # sending a 'flumotion-reset' event is needed to instruct the # downstream elements like muxers to reset them self if needs_reset: for pad in src_pads: pad.push_event(gstreamer.flumotion_reset_event()) # If a reset is not needed we must make sure to drop the duplicated # streamheaders, iterating over all the src pads and installing a # pad_probe to drop them. (eg: theora restarted after a bitrate change # re-sending the headers again) else: for pad in src_pads: probes[pad] = pad.add_buffer_probe(drop_stream_headers) if state > mutable_state: element.set_state(state) # Unblock all sink pads for pad in sink_pads: pad.set_blocked(False)
def _send_reset_event(self): for elem in self.get_output_elements(): pad = elem.get_pad("sink") pad.send_event(gstreamer.flumotion_reset_event())
def _on_connected(self, element): self.info("FGDP producer connected") pad = self.get_element('src').get_pad('src') pad.push_event(gstreamer.flumotion_reset_event())