I am using Gstreamer 1.0 with Python bindings.
Below is the pipeline I am trying to build considering Opengl plugins :
gltestsrc -> gltransformation -> glimagesink
I am trying to modify the properties of element 'gltransformation' dynamically based on the values received from external hardware device. Here is the link, for a similar question but it did not help me much in my usecase.
Below is the snipped of the python script :
import gi
gi.require_version('Gst','1.0')
from gi.repository import Gst,GstController
#global variables
#the values of a,b,c get updated for certain events dynamically based on external hardware
a = 0
b= 0
c = 0
source = Gst.ElementFactory.make("gltestsrc", "source")
gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
sink = Gst.ElementFactory.make("glimagesink", "sink")
# create the empty pipeline
pipeline = Gst.Pipeline.new("test-pipeline")
if not pipeline or not source or not gltrnsfrm or not sink:
print("ERROR: Not all elements could be created")
sys.exit(1)
# build the pipeline
pipeline.add(source,gltrnsfrm,sink)
if not source.link(gltrnsfrm):
print("ERROR: Could not link source to gltrsnfrm")
sys.exit(1)
if not gltrnsfrm.link(sink):
print("ERROR: Could not link gltrsnfrm to sink")
sys.exit(1)
# modify the gltransformation's properties
gltrnsfrm.set_property("rotation-z",a)
gltrnsfrm.set_property("rotation-x",b)
gltrnsfrm.set_property("rotation-y",c)
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
The above example shows only modification of 1 element property, however, I have other properties as well to be modified based on the values of a,b & c.
Executing the above script gives me the following error:
GStreamer-CRITICAL : gst_object_add_control_binding: assertion 'binding->pspec' failed.
I think I have to set certain more attributes in python to get this working.
Does anyone have a hand on this issue?
EDIT:
After the suggestions from Hugh Fisher, I tried to trace back to the source of the file. Here is a snippet from the original code :
GST_INFO_OBJECT (object, "trying to put property '%s' under control",
binding->name);
/* check if the object has a property of that name */
if ((pspec =
g_object_class_find_property (G_OBJECT_GET_CLASS (object),
binding->name))) {
GST_DEBUG_OBJECT (object, " psec->flags : 0x%08x", pspec->flags);
/* check if this param is witable && controlable && !construct-only */
if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
G_PARAM_CONSTRUCT_ONLY)) ==
(G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
binding->pspec = pspec;
} else {
GST_WARNING_OBJECT (object,
"property '%s' on class '%s' needs to "
"be writeable, controlable and not construct_only", binding->name,
G_OBJECT_TYPE_NAME (object));
}
} else {
GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
G_OBJECT_TYPE_NAME (object), binding->name);
}
gst_object_unref (object);
And this is the log file for my script :
0:00:00.174410648 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject#0x10b0020>[00m 0x10b0020 new
0:00:00.174697421 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:207:gst_object_init:<GstObject#0x10b20f0>[00m 0x10b20f0 new
0:00:00.174716708 [336m 8309[00m 0xd1b750 [36mINFO [00m [00m gstcontrolbinding gstcontrolbinding.c:144:gst_control_binding_constructor:<gltrnsfrm>[00m trying to put property 'rotation-x' under control
0:00:00.174723927 [336m 8309[00m 0xd1b750 [37mDEBUG [00m [00m gstcontrolbinding gstcontrolbinding.c:150:gst_control_binding_constructor:<gltrnsfrm>[00m psec->flags : 0x000000e3
0:00:00.174729088 [336m 8309[00m 0xd1b750 [33;01mWARN [00m [00m gstcontrolbinding gstcontrolbinding.c:161:gst_control_binding_constructor:<gltrnsfrm>[00m property 'rotation-x' on class 'GstGLTransformation' needs to be writeable, controlable and not construct_only
0:00:00.174733951 [336m 8309[00m 0xd1b750 [37mTRACE [00m [00;01;31;44m GST_REFCOUNTING gstobject.c:264:gst_object_unref:<gltrnsfrm>[00m 0x10a60e0 unref 4->3
(python3:8309): GStreamer-CRITICAL **: 10:37:00.609: gst_object_add_control_binding: assertion 'binding->pspec' failed
As per the man page of 'gltransformation', the properties rotation-x/y/z, are writable and readable. Also here is a link, of an application that takes input from GUI and changes the rotation-x/y/z for 'gltransformation'.
I have no clue, why here in my case this is an issue.
#gst-inspect-1.0 gltransformation
translation-x : Translates the video at the X-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-y : Translates the video at the Y-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
translation-z : Translates the video at the Z-Axis, in universal [0-1] coordinate.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-x : Rotates the video around the X-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-y : Rotates the video around the Y-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
rotation-z : Rotates the video around the Z-Axis in degrees.
flags: readable, writable
Float. Range: -3,402823e+38 - 3,402823e+38 Default: 0
Edit 2: updated the code, with a workaround for issue:
class Thread(object):
def __init__(self):
thread = threading.Thread(target=self.get)
self.gltrnsfrm = Gst.ElementFactory.make("gltransformation","gltrnsfrm")
thread.start()
def get(self):
try:
global a,b,c
while True:
self.gltrnsfrm.set_property("rotation-z",a)
self.gltrnsfrm.set_property("rotation-x",b)
self.gltrnsfrm.set_property("rotation-y",c)
#time.sleep(0.01)
except KeyboardInterrupt:
pass
The rest of the code is the same(with minor adaptation to use the threads) as described before in the post. However, the following code was ommited :
#dynamic controller
cs = GstController.InterpolationControlSource()
cs.set_property('mode', GstController.InterpolationMode.LINEAR)
cb= Gstcontorller.DirectControlBinding.new(gltrnsfrm,"rotation-x",cs)
gltrnsfrm.add_control_binding(cb)
#modify the values
cs.set(0*Gst.SECOND,b) #use updated values of b
cs.set(1*Gst.SECOND,b)
The problem here is that the gltransformation properties are not controllable. i.e. they don't have the GST_PARAM_CONTROLLABLE flag on property creation in the code.
You can either add controllability to gltransformation by proposing a patch upstream or not relying on controllable properties.
Related
I have a nextflow script with a channel for paired file inputs. I am trying to extract a substring from the file inputs to use as part of the shell call. I am trying to use Groovy's regex matching to extract the substring, but since it is based on an input value, I am having trouble executing the matching. An alternative would be to perform the regex in bash as part of the process shell call, but I am interested in figuring out how to manipulate inputs within a process anyways, as I feel it would be useful for other things too. How can I perform intermediate Groovy code with the process inputs prior to the shell call?
process alignment {
input:
val files
output:
stdout
def matcher = "${files[1][0]}" =~ /.+\/bcl2fastq_out\/([^\/]+)\/.+/
# this is the culprit, as if I hardcode the first string it works
def project = matcher.findAll()[0][1]
"""
echo ${project}
"""
}
workflow {
files = Channel
.fromFilePairs("${params.out_dir}/**{_R1,_R2}_00?.fastq.gz", checkIfExists:true, size: 2)
alignment(files)
}
when I execute this, I get the error
No such variable: files
an example input string would look like extractions/test/bcl2fastq_out/project1/example_L001_R1_001.fastq.gz where I'm trying to extract the project1 substring
As you've already discovered, you can declare variables in the script block, before the command string. For example:
process alignment {
input:
tuple val(sample), path(fastq_files)
output:
tuple val(sample), path(output_file)
script:
output_file = "${sample}.bam"
"""
>&2 echo "Aligning ${sample}..."
touch "${output_file}"
"""
}
Note that these are global (within the process scope) unless you define them using the def keyword. If you don't need these elsewhere in your process definition, like in your example, a local variable (using def) is usually preferable. If, however, you need to access these in your output declaration, for example, then they will need to be global.
Note that the fromFilePairs factory method emits a tuple, where the first element is a group key and the second element is a list of files. The problem with just using val to declare the inputs is that the files in the second element will not be localized to the working directory when your script is run. To fix this, you can just change your input definition to something like:
input:
tuple val(sample), path(fastq_files)
The problem with this approach, is that we're unable to extract the parent directory name from the localized filenames. So you will need to pass this in somehow. Usually, you could just get the parent name from the first file in the tuple, using:
params.input_dir = './path/to/files'
params.pattern = '**_R{1,2}_00?.fastq.gz'
process alignment {
debug true
input:
tuple val(sample), val(project), path(fastq_files)
"""
echo "${sample}: ${project}: ${fastq_files}"
"""
}
workflow {
Channel
.fromFilePairs( "${params.input_dir}/${params.pattern}" )
.map { sample, reads ->
def project = reads[0].parent.name
tuple( sample, project, reads )
}
.set { reads }
alignment( reads )
}
But since the glob pattern has an additional wildcard, i.e. _00?, you may not necessarily get the results you expect. For example:
$ mkdir -p path/to/files/project{1,2,3}
$ touch path/to/files/project1/sample1_R{1,2}_00{1,2,3,4}.fastq.gz
$ touch path/to/files/project2/sample2_R{1,2}_00{1,2,3,4}.fastq.gz
$ touch path/to/files/project3/sample3_R{1,2}_00{1,2,3,4}.fastq.gz
$ nextflow run main.nf
N E X T F L O W ~ version 22.04.0
Launching `main.nf` [determined_roentgen] DSL2 - revision: f80ab33ac8
executor > local (12)
[a8/9235cc] process > alignment (12) [100%] 12 of 12 ✔
sample2: project2: sample2_R1_001.fastq.gz sample2_R1_004.fastq.gz
sample1: project1: sample1_R1_003.fastq.gz sample1_R2_001.fastq.gz
sample1: project1: sample1_R1_004.fastq.gz sample1_R2_003.fastq.gz
sample3: project3: sample3_R1_001.fastq.gz sample3_R2_001.fastq.gz
sample1: project1: sample1_R1_001.fastq.gz sample1_R2_004.fastq.gz
sample1: project1: sample1_R1_002.fastq.gz sample1_R2_002.fastq.gz
sample2: project2: sample2_R1_002.fastq.gz sample2_R2_002.fastq.gz
sample2: project2: sample2_R2_001.fastq.gz sample2_R2_004.fastq.gz
sample2: project2: sample2_R1_003.fastq.gz sample2_R2_003.fastq.gz
sample3: project3: sample3_R2_002.fastq.gz sample3_R2_004.fastq.gz
sample3: project3: sample3_R1_003.fastq.gz sample3_R1_004.fastq.gz
sample3: project3: sample3_R1_002.fastq.gz sample3_R2_003.fastq.gz
Fortunately, we can supply a custom file pair grouping strategy using a closure. This uses the readPrefix helper function:
workflow {
Channel
.fromFilePairs( "${params.input_dir}/${params.pattern}" ) { file ->
prefix = Channel.readPrefix(file, params.pattern)
suffix = file.simpleName.tokenize('_').last()
"${file.parent.name}/${prefix}_${suffix}"
}
.map { key, reads ->
def (project, sample) = key.tokenize('/')
tuple( sample, project, reads )
}
.set { reads }
alignment( reads )
}
Results:
$ nextflow run main.nf
N E X T F L O W ~ version 22.04.0
Launching `main.nf` [loving_cantor] DSL2 - revision: 5a76ac712f
executor > local (12)
[f4/74edbc] process > alignment (12) [100%] 12 of 12 ✔
sample1_003: project1: sample1_R1_003.fastq.gz sample1_R2_003.fastq.gz
sample2_002: project2: sample2_R1_002.fastq.gz sample2_R2_002.fastq.gz
sample1_002: project1: sample1_R1_002.fastq.gz sample1_R2_002.fastq.gz
sample2_003: project2: sample2_R1_003.fastq.gz sample2_R2_003.fastq.gz
sample2_004: project2: sample2_R1_004.fastq.gz sample2_R2_004.fastq.gz
sample2_001: project2: sample2_R1_001.fastq.gz sample2_R2_001.fastq.gz
sample1_001: project1: sample1_R1_001.fastq.gz sample1_R2_001.fastq.gz
sample1_004: project1: sample1_R1_004.fastq.gz sample1_R2_004.fastq.gz
sample3_001: project3: sample3_R1_001.fastq.gz sample3_R2_001.fastq.gz
sample3_004: project3: sample3_R1_004.fastq.gz sample3_R2_004.fastq.gz
sample3_002: project3: sample3_R1_002.fastq.gz sample3_R2_002.fastq.gz
sample3_003: project3: sample3_R1_003.fastq.gz sample3_R2_003.fastq.gz
I figured it out, if instead of just jumping into the shell script with the triple quotes, you can start specifying the process execution script with "script:" then run Groovy using the process inputs
process alignment {
input:
val files
output:
stdout
script:
test = (files[1][0] =~ '.+/test/([^/]+)/.+').findAll()[0][1]
"""
echo $test
"""
Context:
We are working on migration of the driver, which is currently represented as a kernel extension, to the DriverKit framework.
The driver works with Thunderbolt RAID storage devices.
When connected through the Thunderbolt interface to the host, the device itself presents in the OS as a PCI device. The main function of our driver (.kext) is to create a "virtual" SCSI device in the OS for each virtual RAID array. So that the OS can work with these SCSI drives as usual disk storage.
We use https://developer.apple.com/documentation/scsicontrollerdriverkit to migrate this functionality in the dext version of the driver.
Current issue:
When a device is connected - the dext driver cannot create a SCSI drive in the OS.
Technically our dext tries to create a SCSI drive using the UserCreateTargetForID() method.
On this step the OS sends the first SCSI command "Test Unit Ready" to the device to check if it is a SCSI device.
We process this command in an additional thread separated from the main process of the dext (as it is recommended in the DriverKit documentation).
We can see in the logs that the device receives this command and responses but when our dext sends this response to the OS the process is stuck in the waiting mode. How can we understand why it happens and fix it?
More details:
We are migrating functionality of an already existing “.kext” driver. We checked logs of the kext driver of this step:
15:06:17.902539+0700 Target device try to create for idx:0
15:06:17.902704+0700 Send command 0 for target 0 len 0
15:06:18.161777+0700 Complete command: 0 for target: 0 Len: 0 status: 0 flags: 0
15:06:18.161884+0700 Send command 18 for target 0 len 6
15:06:18.161956+0700 Complete command: 18 for target: 0 Len: 6 status: 0 flags: 0
15:06:18.162010+0700 Send command 18 for target 0 len 44
15:06:18.172972+0700 Complete command: 18 for target: 0 Len: 44 status: 0 flags: 0
15:06:18.275501+0700 Send command 18 for target 0 len 36
15:06:18.275584+0700 Complete command: 18 for target: 0 Len: 36 status: 0 flags: 0
15:06:18.276257+0700 Target device created for idx:0
We can see a successful message “Target device created for idx:0”
In the the dext logs of the same step:
We do not see the “Send command 18 for target 0 len 6” as we have in the kext logs
no log of the successful result “Target device created for idx:0”
I'll add a thread name to each line of the dext log (CustomThread,DefaultQueue,SendCommandCustomThread,InterruptQueue):
15:54:10.903466+0700 Try to create target for 0 UUID 432421434863538456 - CustomThread
15:54:10.903633+0700 UserDoesHBAPerformAutoSense - DefaultQueue
15:54:10.903763+0700 UserInitializeTargetForID - DefaultQueue
15:54:10.903876+0700 UserDoesHBASupportMultiPathing DefaultQueue
15:54:10.904200+0700 UserProcessParallelTask start - DefaultQueue
15:54:10.904298+0700 Sent command : 0 len 0 for target 0 - SendCommandCustomThread
15:54:11.163003+0700 Disable interrupts - InterruptQueue
15:54:11.163077+0700 Complete cmd : 0 for target: 0 len: 0 status: 0 flags: 0 - InterruptQueue
15:54:11.163085+0700 Enable interrupts - InterruptQueue
Code for complete task
SCSIUserParallelResponse osRsp = {0};
osRsp.fControllerTaskIdentifier = osTask->taskId;
osRsp.fTargetID = osTask->targetId;
osRsp.fServiceResponse = kSCSIServiceResponse_TASK_COMPLETE;
osRsp.fCompletionStatus = (SCSITaskStatus) response->status;
// Transfer length computation.
osRsp.fBytesTransferred = transferLength; // === 0 for this case.
ParallelTaskCompletion(osTask->action, osRsp);
osTask->action->release();
Will appreciate any help
This is effectively a deadlock, which you seem to have already worked out. It's not 100% clear from your your question, but as I initially had the same problem, I assume you're calling UserCreateTargetForID from the driver's default queue. This won't work, you must call it from a non-default queue because SCSIControllerDriverKit assumes that your default queue is idle and ready to handle requests from the kernel while you are calling this function. The header docs are very ambiguous on this, though they do mention it:
The dext class should call this method to create a new target for the
targetID. The framework ensures that the new target is created before the call returns.
Note that this call to the framework runs on the Auxiliary queue.
SCSIControllerDriverKit expects your driver to use 3 different dispatch queues (default, auxiliary, and interrupt), although I think it can be done with 2 as well. I recommend you (re-)watch the relevant part of the WWDC2020 session video about how Apple wants you to use the 3 dispatch queues, exactly. The framework does not seem to be very flexible on this point.
Good luck with the rest of the driver port, I found this DriverKit framework even more fussy than the other ones.
Thanks to pmdj for direction of think. For my case answer is just add initialization for version field for response.
osRsp.version = kScsiUserParallelTaskResponseCurrentVersion1;
It looks obvious. But there are no any information in docs or WWDC2020 video about initialization version field.
My project is hardware raid 'user space driver' . My driver has now completed the io stress test. Your problem should be in the SCSI command with data transfer. And you want to send data to the system by your software driver to complete the SCSI ' inquiry ' command. I think you also used 'UserGetDataBuffer'. It seems to be some distance from iokit's function.
kern_return_t IMPL ( XXXXUserSpaceDriver, UserProcessParallelTask )
{
/*
**********************************************************************
** UserGetDataBuffer
**********************************************************************
*/
if(parallelTask.fCommandDescriptorBlock[0] == SCSI_CMD_INQUIRY)
{
IOBufferMemoryDescriptor *data_buffer_memory_descriptor = nullptr;
/*
******************************************************************************************************************************************
** virtual kern_return_t UserGetDataBuffer(SCSIDeviceIdentifier fTargetID, uint64_t fControllerTaskIdentifier, IOBufferMemoryDescriptor **buffer);
******************************************************************************************************************************************
*/
if((UserGetDataBuffer(parallelTask.fTargetID, parallelTask.fControllerTaskIdentifier, &data_buffer_memory_descriptor) == kIOReturnSuccess) && (data_buffer_memory_descriptor != NULL))
{
IOAddressSegment data_buffer_virtual_address_segment = {0};
if(data_buffer_memory_descriptor->GetAddressRange(&data_buffer_virtual_address_segment) == kIOReturnSuccess)
{
IOAddressSegment data_buffer_physical_address_segment = {0};
IODMACommandSpecification dmaSpecification;
IODMACommand *data_buffer_iodmacommand = {0};
bzero(&dmaSpecification, sizeof(dmaSpecification));
dmaSpecification.options = kIODMACommandSpecificationNoOptions;
dmaSpecification.maxAddressBits = 64;
if(IODMACommand::Create(ivars->pciDevice, kIODMACommandCreateNoOptions, &dmaSpecification, &data_buffer_iodmacommand) == kIOReturnSuccess)
{
uint64_t dmaFlags = kIOMemoryDirectionInOut;
uint32_t dmaSegmentCount = 1;
pCCB->data_buffer_iodmacommand = data_buffer_iodmacommand;
if(data_buffer_iodmacommand->PrepareForDMA(kIODMACommandPrepareForDMANoOptions, data_buffer_memory_descriptor, 0/*offset*/, parallelTask.fRequestedTransferCount/*length*/, &dmaFlags, &dmaSegmentCount, &data_buffer_physical_address_segment) == kIOReturnSuccess)
{
parallelTask.fBufferIOVMAddr = (uint64_t)data_buffer_physical_address_segment.address; /* data_buffer_physical_address: overwrite original fBufferIOVMAddr */
pCCB->OSDataBuffer = reinterpret_cast <uint8_t *> (data_buffer_virtual_address_segment.address);/* data_buffer_virtual_address */
}
}
}
}
}
}
response.fBytesTransferred = dataxferlen;
response.version = kScsiUserParallelTaskResponseCurrentVersion1;
response.fTargetID = TARGETLUN2SCSITARGET(TargetID, 0);
response.fControllerTaskIdentifier = pCCB->fControllerTaskIdentifier;
response.fCompletionStatus = taskStatus;
response.fServiceResponse = serviceResponse;
response.fSenseLength = taskStatus;
IOUserSCSIParallelInterfaceController::ParallelTaskCompletion(pCCB->completion, response);
pCCB->completion->release();
pCCB->completion = NULL;
pCCB->ccb_flags.start = 0;/*reset startdone for outstanding ccb check*/
if(pCCB->data_buffer_iodmacommand != NULL)
{
pCCB->data_buffer_iodmacommand->CompleteDMA(kIODMACommandCompleteDMANoOptions);
OSSafeReleaseNULL(pCCB->data_buffer_iodmacommand); // pCCB->data_buffer_iodmacommand->free(); pCCB->data_buffer_iodmacommand = NULL;
pCCB->OSDataBuffer = NULL;
}
I am trying to convert a webcam on a raspberry pi to x264, but keep running into an error about an " Unsupported profile constrained-baseline".
GST_DEBUG=3 /home/pi/gst-rtsp-server/examples/test-launch "( v4l2src device=/dev/video0 ! videoconvert ! omxh264enc ! h264parse ! rtph264pay name=pay0 )"
stream ready at rtsp://127.0.0.1:8554/test
0:00:03.043939441 10314 0x75c08350 WARN v4l2src gstv4l2src.c:692:gst_v4l2src_query:<v4l2src0> Can't give latency since framerate isn't fixated !
0:00:03.044207251 10314 0x7491de30 FIXME default gstutils.c:3981:gst_pad_create_stream_id_internal:<appsrc1:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:03.044211053 10314 0x7491de60 FIXME default gstutils.c:3981:gst_pad_create_stream_id_internal:<appsrc0:src> Creating random stream-id, consider implementing a deterministic way of creating a stream-id
0:00:03.087901354 10314 0x7491de90 ERROR omxh264enc gstomxh264enc.c:706:gst_omx_h264_enc_set_format:<omxh264enc-omxh264enc0> Unsupported profile constrained-baseline
0:00:03.087992083 10314 0x7491de90 ERROR omxvideoenc gstomxvideoenc.c:2239:gst_omx_video_enc_set_format:<omxh264enc-omxh264enc0> Subclass failed to set the new format
0:00:03.088080988 10314 0x7491de90 WARN videoencoder gstvideoencoder.c:678:gst_video_encoder_setcaps:<omxh264enc-omxh264enc0> rejected caps video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)5/1, pixel-aspect-ratio=(fraction)1/1, format=(string)I420, interlace-mode=(string)progressive
0:00:03.092800068 10314 0x7491de90 ERROR omxh264enc gstomxh264enc.c:706:gst_omx_h264_enc_set_format:<omxh264enc-omxh264enc0> Unsupported profile constrained-baseline
0:00:03.092867411 10314 0x7491de90 ERROR omxvideoenc gstomxvideoenc.c:2239:gst_omx_video_enc_set_format:<omxh264enc-omxh264enc0> Subclass failed to set the new format
0:00:03.092942775 10314 0x7491de90 WARN videoencoder gstvideoencoder.c:678:gst_video_encoder_setcaps:<omxh264enc-omxh264enc0> rejected caps video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)5/1, pixel-aspect-ratio=(fraction)1/1, format=(string)I420, interlace-mode=(string)progressive
0:00:03.092983764 10314 0x7491de90 WARN GST_PADS gstpad.c:4226:gst_pad_peer_query:<videoscale0:src> could not send sticky events
0:00:04.001816134 10314 0x7491de90 ERROR omxh264enc gstomxh264enc.c:706:gst_omx_h264_enc_set_format:<omxh264enc-omxh264enc0> Unsupported profile constrained-baseline
0:00:04.001956914 10314 0x7491de90 ERROR omxvideoenc gstomxvideoenc.c:2239:gst_omx_video_enc_set_format:<omxh264enc-omxh264enc0> Subclass failed to set the new format
0:00:04.002098111 10314 0x7491de90 WARN videoencoder gstvideoencoder.c:678:gst_video_encoder_setcaps:<omxh264enc-omxh264enc0> rejected caps video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)5/1, pixel-aspect-ratio=(fraction)1/1, format=(string)I420, interlace-mode=(string)progressive
0:00:04.037642275 10314 0x7491de90 ERROR omxh264enc gstomxh264enc.c:706:gst_omx_h264_enc_set_format:<omxh264enc-omxh264enc0> Unsupported profile constrained-baseline
0:00:04.037781284 10314 0x7491de90 ERROR omxvideoenc gstomxvideoenc.c:2239:gst_omx_video_enc_set_format:<omxh264enc-omxh264enc0> Subclass failed to set the new format
0:00:04.037959303 10314 0x7491de90 WARN videoencoder gstvideoencoder.c:678:gst_video_encoder_setcaps:<omxh264enc-omxh264enc0> rejected caps video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)5/1, pixel-aspect-ratio=(fraction)1/1, format=(string)I420, interlace-mode=(string)progressive
0:00:04.038154562 10314 0x7491de90 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop:<v4l2src0> error: Internal data stream error.
0:00:04.038222947 10314 0x7491de90 WARN basesrc gstbasesrc.c:3055:gst_base_src_loop:<v4l2src0> error: streaming stopped, reason not-negotiated (-4)
0:00:04.038854870 10314 0x75c08350 WARN rtspmedia rtsp-media.c:1834:default_handle_message: 0x75c4e120: got error Internal data stream error. (gstbasesrc.c(3055): gst_base_src_loop (): /GstPipeline:media-pipeline/GstBin:bin0/GstV4l2Src:v4l2src0:
streaming stopped, reason not-negotiated (-4))
0:00:04.039143357 10314 0x20b2490 WARN rtspmedia rtsp-media.c:2127:wait_preroll: failed to preroll pipeline
0:00:04.039219346 10314 0x20b2490 WARN rtspmedia rtsp-media.c:2384:gst_rtsp_media_prepare: failed to preroll pipeline
0:00:04.053306794 10314 0x7491de90 ERROR omxh264enc gstomxh264enc.c:706:gst_omx_h264_enc_set_format:<omxh264enc-omxh264enc0> Unsupported profile constrained-baseline
0:00:04.053442678 10314 0x7491de90 ERROR omxvideoenc gstomxvideoenc.c:2239:gst_omx_video_enc_set_format:<omxh264enc-omxh264enc0> Subclass failed to set the new format
0:00:04.053582781 10314 0x7491de90 WARN videoencoder gstvideoencoder.c:678:gst_video_encoder_setcaps:<omxh264enc-omxh264enc0> rejected caps video/x-raw, width=(int)1920, height=(int)1080, framerate=(fraction)5/1, pixel-aspect-ratio=(fraction)1/1, format=(string)I420, interlace-mode=(string)progressive
0:00:04.079457589 10314 0x20b2490 ERROR rtspclient rtsp-client.c:678:find_media: client 0x2010610: can't prepare media
0:00:04.081144660 10314 0x20b2490 ERROR rtspclient rtsp-client.c:2210:handle_describe_request: client 0x2010610: no media
There isn't anything in the docs for omxh264enc about profiles that I can find:
gst-inspect-1.0 omxh264enc
Factory Details:
Rank primary + 1 (257)
Long-name OpenMAX H.264 Video Encoder
Klass Codec/Encoder/Video
Description Encode H.264 video streams
Author Sebastian Dröge <sebastian.droege#collabora.co.uk>
Plugin Details:
Name omx
Description GStreamer OpenMAX Plug-ins
Filename /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/libgstomx.so
Version 1.14.4
License LGPL
Source module gst-omx
Source release date 2018-10-02
Binary package GStreamer OpenMAX Plug-ins source release
Origin URL Unknown package origin
GObject
+----GInitiallyUnowned
+----GstObject
+----GstElement
+----GstVideoEncoder
+----GstOMXVideoEnc
+----GstOMXH264Enc
+----GstOMXH264Enc-omxh264enc
Implemented Interfaces:
GstPreset
Pad Templates:
SRC template: 'src'
Availability: Always
Capabilities:
video/x-h264
width: [ 16, 4096 ]
height: [ 16, 4096 ]
SINK template: 'sink'
Availability: Always
Capabilities:
video/x-raw
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
Element has no clocking capabilities.
Element has no URI handling capabilities.
Pads:
SINK: 'sink'
Pad Template: 'sink'
SRC: 'src'
Pad Template: 'src'
Element Properties:
name : The name of the object
flags: readable, writable
String. Default: "omxh264enc-omxh264enc0"
parent : The parent of the object
flags: readable, writable
Object of type "GstObject"
qos : Handle Quality-of-Service events from downstream
flags: readable, writable
Boolean. Default: false
control-rate : Bitrate control method
flags: readable, writable, changeable only in NULL or READY state
Enum "GstOMXVideoEncControlRate" Default: -1, "default"
(0): disable - Disable
(1): variable - Variable
(2): constant - Constant
(3): variable-skip-frames - Variable Skip Frames
(4): constant-skip-frames - Constant Skip Frames
(-1): default - Component Default
target-bitrate : Target bitrate in bits per second (0xffffffff=component default)
flags: readable, writable, changeable in NULL, READY, PAUSED or PLAYING state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
quant-i-frames : Quantization parameter for I-frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
quant-p-frames : Quantization parameter for P-frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
quant-b-frames : Quantization parameter for B-frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
inline-header : Inline SPS/PPS header before IDR
flags: readable, writable, changeable only in NULL or READY state
Boolean. Default: true
periodicity-idr : Periodicity of IDR frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
periodicty-idr : Periodicity of IDR frames (0xffffffff=component default) DEPRECATED - only for backwards compat
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
interval-intraframes: Interval of coding Intra frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
b-frames : Number of B-frames between two consecutive I-frames (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Unsigned Integer. Range: 0 - 4294967295 Default: 4294967295
entropy-mode : Entropy mode for encoding process
flags: readable, writable, changeable only in NULL or READY state
Enum "GstOMXH264EncEntropyMode" Default: -1, "default"
(0): CAVLC - CAVLC entropy mode
(1): CABAC - CABAC entropy mode
(-1): default - Component Default
constrained-intra-prediction: If enabled, prediction only uses residual data and decoded samples from neighbouring coding blocks coded using intra prediction modes
flags: readable, writable, changeable only in NULL or READY state
Boolean. Default: false
loop-filter-mode : Enable or disable the deblocking filter (0xffffffff=component default)
flags: readable, writable, changeable only in NULL or READY state
Enum "GstOMXH264EncLoopFilter" Default: -1, "default"
(0): enable - Enable deblocking filter
(1): disable - Disable deblocking filter
(2): disable-slice-boundary - Disables deblocking filter on slice boundary
(-1): default - Component Default
I am new to gstreamer so I could be reading this all wrong, would appreciate any ideas or feedback! Thanks!
You can change that through the SRC cap, try e.g.:
v4l2src device=/dev/video0 ! videoconvert ! omxh264enc ! video/x-h264,profile=baseline ! h264parse ! rtph264pay name=pay0
I have the following pipeline :
v4l2src -> queue -> h264parse -> avdec_h264 -> identity ->
imagefreeze(added/removed dynamically) -> glupload -> glcolorconvert ->
gltransformation -> glimagesink
I have a added a probe on the element identity srcpad.
Based, on the user-input I add or remove dynamically the element imagefreeze
Here is the pseudo code :
#show live video on rendering window till no user input
#if user_input == 1:
insert_imagefreeze #analogous to image being displayed on rendering window
#if user_input == 2:
delete_imagefreeze #resume back showing live video as before
Inserting imagefreeze is no problem, it works fine. I can observe the results that I would want to with a imagefreeze
However, after the element imagefreeze is added, the element v4l2src task goes to a paused state. Here is the info log :
0:03:39.608226968 [333m29510[00m 0x1561c00 [36mINFO [00m [00m v4l2src gstv4l2src.c:949:gst_v4l2src_create:<source>[00m sync to 0:03:39.066664476 out ts 0:03:39.375180156
0:03:39.608449406 [333m29510[00m 0x1561c00 [36mINFO [00m [00m basesrc gstbasesrc.c:2965:gst_base_src_loop:<source>[00m pausing after gst_pad_push() = eos
0:03:39.608561724 [333m29510[00m 0x1561c00 [36mINFO [00m [00m task gsttask.c:316:gst_task_func:<source:src>[00m Task going to paused.
Can anyone explain, why the source element of pipeline goes to a paused state once a new element is added to the pipeline.
And snippets from actual code :
def add_delete(self):
if ui_input_cnt = 1 #updated based on user input
self.idsrcpad = self.identity.get_static_pad("src")
self.in_idle_probe = False
self.probeID = self.idsrcpad.add_probe(Gst.PadProbeType.IDLE,self.lengthen_pipeline)
if ui_input_cnt = 2
self.probeID2 = self.idsrcpad.add_probe(Gst.PadProbeType.IDLE,self.shorten_pipeline)
def lengthen_pipeline(self,pad,info):
print("entered callback")
global pipeline
#restrict only 1 call to this callback
if self.in_idle_probe == True:
print("callback for now restricted to one call per thread")
return Gst.PadProbeReturn.OK
if self.in_idle_probe == False:
self.in_idle_probe == True
#create image freze element
self.ifreeze = Gst.ElementFactory.make("imagefreeze","ifreeze")
# increment reference
self.ifreeze.ref()
#add imagefreze to pipeline
pipeline.add(self.ifreeze)
#sync image freeze state to main pipeline
self.ifreeze.sync_state_with_parent()
#unlink identity and upload
#1.get sink pad of upload and srcpad of identity
sinkpad = self.upload.get_static_pad("sink")
srcpad = self.identity.get_static_pad("src")
print("unlinking identit srcpad - uplaod sinkpad")
if self.check_and_unlink(srcpad,sinkpad):
#2.get sink pad of imagefreeze
sinkpad = self.ifreeze.get_static_pad("sink")
#3. link identity src pad to image freeze sinkpad
print("linking identity srcpad - ifreeze sinkpad")
self.check_and_link(srcpad,sinkpad)
#4. link imagefreeze src pad to upload sink pad
#get image freeze srcpad and sinkpad of upload
srcpad = self.ifreeze.get_static_pad("src")
sinkpad = self.upload.get_static_pad("sink")
print("linking ifreeze srcpad - upload sinkpad")
if self.check_and_link(srcpad,sinkpad):
return Gst.PadProbeReturn.REMOVE
else:
print("ERORR : unlinking")
return -1
The functions check_and_link(srcpad,sinkpad) and check_and_unlink(srcpad,sinkpad), does no more than checking the src and sink pads, and then linking and unlinking accordingly.
The sink sends a EOS event, when the imagefreeze is added dynamically. This makes the pipeline go into a PAUSED state. However, why the sink receives a EOS event is still unclear, and needs further investigation. More information of the observations are provided here.
I'm trying to run an Akka stream application, but get an exception when running on linux.
When I run it with Windows debugger it is working.
I tried both these commands:
java -jar ./myService.jar -Dconfig.resource=/opt/myservice/conf/application.conf
java -jar ./myService.jar -Dconfig.file=/opt/myService/conf/application.conf
But I get the following exception:
No configuration setting found for key 'akka.stream'
My application.conf file:
akka {
event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
loglevel = "DEBUG"
actor {
debug {
# enable function of LoggingReceive, which is to log any received message
at
# DEBUG level
receive = on
}
}
stream {
# Default materializer settings
materializer {
max-input-buffer-size = 16
dispatcher = ""
subscription-timeout {
mode = cancel
timeout = 5s
}
# Enable additional troubleshooting logging at DEBUG log level
debug-logging = off
# Maximum number of elements emitted in batch if downstream signals large demand
output-burst-limit = 1000
auto-fusing = on
# Those stream elements which have explicit buffers (like mapAsync, mapAsyncUnordered,
# buffer, flatMapMerge, Source.actorRef, Source.queue, etc.) will preallocate a fixed
# buffer upon stream materialization if the requested buffer size is less than this
max-fixed-buffer-size = 1000000000
sync-processing-limit = 1000
debug {
fuzzing-mode = off
}
}
blocking-io-dispatcher = "akka.stream.default-blocking-io-dispatcher"
default-blocking-io-dispatcher {
type = "Dispatcher"
executor = "thread-pool-executor"
throughput = 1
thread-pool-executor {
fixed-pool-size = 16
}
}
}
# configure overrides to ssl-configuration here (to be used by akka-streams,
and akka-http – i.e. when serving https connections)
ssl-config {
protocol = "TLSv1.2"
}
}
ssl-config {
logger = "com.typesafe.sslconfig.akka.util.AkkaLoggerBridge"
}
i've added:
println(system.settings.config)
but i get a result without stream section
Can you assist?
The syntax for the java command line is:
java [options] -jar filename [args]
This ordering matters: you must set any options before the -jar option.
So in your case:
java -Dconfig.file=/opt/myService/conf/application.conf -jar ./myService.jar