-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hello_pi: Add hello_mmal_encode example #349
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the patch - having an example is useful.
I haven't tried to run it, and my comments are generally minor.
@popcornmix Do we want a new directory for MMAL based examples? All of the IL based ones really ought to be ported to MMAL as well (yet another task).
Also hello_encode is for video_encode, so do we want to distinguish this image_encode test from that?
|
||
fprintf(stdout, "Encoding test image %s\n", filename); | ||
|
||
if (mmal_wrapper_create(&mmal, MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmal as a variable name is very ambiguous. "encoder" or "component"?
portIn = mmal->input[0]; | ||
mmal->status = MMAL_SUCCESS; | ||
|
||
if (portIn->is_enabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not aware of any way for components to have enabled ports this soon after creation. Redundant? Or is this copy/paste from other examples? (In which case they ought to be amended).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it doesn't seem to be necessary in this case. In general it might be though, if people are reconfiguring an existing encoder, so perhaps it would be good to show this. How about if the encoder is created in main(), then reconfigured for each encoding?
|
||
portOut = mmal->output[0]; | ||
|
||
if (portOut->is_enabled) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto - I don't see how this can happen.
|
||
// Send output buffers to be filled with encoded image. | ||
while (mmal_wrapper_buffer_get_empty(portOut, &out, 0) == MMAL_SUCCESS) { | ||
out->data = outBuf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds like it is going to be very bad if portOut->buffer_num > 1 as you'll use the same pointer for all the buffers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I've been lucky so far and it's only ever given me a single buffer!
For this example, would it be better to use MMAL_WRAPPER_FLAG_PAYLOAD_ALLOCATE on portOut and have mmal handle this?
I suggested the name for this, so I'm okay with it. |
:-) |
// Perform the encoding | ||
|
||
outBuf = malloc(portOut->buffer_size); | ||
outFile = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for using open() rather than fopen() ? Won't open() mean that the output is unbuffered?
outBuf = malloc(portOut->buffer_size); | ||
outFile = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); | ||
if (outFile < 0) { | ||
fprintf(stderr, "Failed to open file: %s\n", filename); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to print strerror(errno) here as well, to help people work out why it didn't succeed (same comment elsewhere).
|
||
// Send image to be encoded. | ||
if (!sent && mmal_wrapper_buffer_get_empty(portIn, &in, 0) == MMAL_SUCCESS) { | ||
fprintf(stdout, "- sending %u bytes to encoder\n", inBufSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps just printf() rather than fprintf(stdout,...) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments.
// Send image to be encoded. | ||
if (!sent && mmal_wrapper_buffer_get_empty(portIn, &in, 0) == MMAL_SUCCESS) { | ||
fprintf(stdout, "- sending %u bytes to encoder\n", inBufSize); | ||
memcpy(in->data, inBuf, inBufSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ending up copying all of the input stream? Is there any way to avoid that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could construct the test image directly in the in->data buffer.
I'm also assuming the size of this buffer is always going to be >= inBuffSize (which it does always seem to be), but not sure if this is guaranteed?
uint32_t BLUE = 0xff << 16; | ||
uint32_t ALPHA = 0xff << 24; | ||
|
||
VCOS_SEMAPHORE_T sem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be static?
{ | ||
MMAL_WRAPPER_T* mmal; | ||
unsigned int inBufSize; | ||
unsigned char* inBuf; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you made inBuf a void* then you wouldn't need the ugly casting later on.
Hi, thanks for all the comments. I've pushed a further commit which hopefully addresses these. |
Would you mind squashing those two commits together into one? I think it makes it easier to review. I haven't actually tried to run it yet, but it looks pretty convincing to me. But a few more comments (sorry!). Is the indentation intended to be just two spaces? In other code in the same directory it's 3 spaces (and either 4, or a hard tab would be my choice, but that's a flame war too far :-) But consistent with the rest of the code perhaps? Should this be renamed to something like hello_mmal_image_encode, in case anyone ever adds a video encode example? |
hello_mmal_encode: Updates following PR comments hello_mmal_encode: Change indent to match other examples
0b50650
to
e9d501d
Compare
Consistent would be good and appears to have been done. As you know, 3 was the Broadcom standard hence why it was applied to these files.
I already asked that question of popcornmix #349 (review) - he'd suggested the name :-) |
Many thanks @sconemad |
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=138290#p1052932 firmware: logging: Fix issue when logging end is at 1G firmware: hello_pi: Add hello_mmal_encode example See: raspberrypi/userland#349 firmware: IL ISP: Update to support opaque input firmware: IL ISP: Fix for opaque EOS and excessive finalise calls firmware: khronos: Use low 256M allocations for bin allocations
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=138290#p1052932 firmware: logging: Fix issue when logging end is at 1G firmware: hello_pi: Add hello_mmal_encode example See: raspberrypi/userland#349 firmware: IL ISP: Update to support opaque input firmware: IL ISP: Fix for opaque EOS and excessive finalise calls firmware: khronos: Use low 256M allocations for bin allocations
- firmware: isp: Add isp and isp_ilc to standard Pi variant as a cheap resize - firmware: MMAL: Add parameters to configure source pattern - firmware: IL Camera: Minor tidy up in RGB output handling - firmware: Video_render: Support YV12 and NV21 (YVU formats - firmware: IL Source: Add support for YV12 output (YVU420PackedPlanar) - firmware: IL ISP: Major updates - firmware: mmal_ril: Relay buffer alignment from RIL to MMAL - firmware: ldconfig: Increase line buffer length from 80 to 100 - firmware: h264: Fix skipping of SPSX in header bytes See: https://discourse.osmc.tv/t/video-does-not-work-with-hardware-acceleartion/6629/11 - firmware: display: Allow display blanking to affect DPI output See: #672 - firmware: Video_decode: Check licenced codecs at component create - firmware: dispmanx: Report transform or display as the display_rotate variable See: raspberrypi/userland#348 - firmware: arm_loader: Don't lose force_turbo when initial_turbo completes See: #667 - firmware: mmal: improvements to mmal_queue code - firmware: arm_dt: Silence system-supplied dtparams - firmware: vc_image: Remove obsolete processor support using _VC_VERSION - firmware: vc_image: Include colourspace in RGB to YUV conversions - firmware: OV5647/IMX219: Shutdown lines in reverse order to opening See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=138290#p1052932 - firmware: logging: Fix issue when logging end is at 1G - firmware: hello_pi: Add hello_mmal_encode example See: raspberrypi/userland#349 - firmware: IL ISP: Update to support opaque input - firmware: IL ISP: Fix for opaque EOS and excessive finalise calls - firmware: khronos: Use low 256M allocations for bin allocations - firmware: logging: Fix issue when logging end is at 1G part 2 - firmware: arm_loader: Ensure mbox failure paths return failure - firmware: arm_loader: Add options for setting shared buffers from kernel driver - firmware: vcdbg: Use dma driver to access gpu memory - firmware: dispmanx: Support framebuffer_aspect=-1 for ignore aspect ratio See: #638 - firmware: Raspistill: Only fail setting restart int if not 0 - firmware: RaspiVid: -sg option could try opening null file - firmware: RaspiVid: Segment PTS file too if set See: raspberrypi/userland#354 - firmware: RaspiVid: Add raw (YUV420, RGB or grayscale) video output See: raspberrypi/userland#342 - firmware: Add support for EGL images allocated by VCSM See: raspberrypi/userland#344 - firmware: egl_client: Avoid missing return value warning - firmware: debug_sym: Use pointer type for user address - firmware: Video_splitter: store and pass on frame rate information - firmware: TC358762: Fix broken backlight ratelimiting
See: https://www.raspberrypi.org/forums/viewtopic.php?f=43&t=138290#p1052932 firmware: logging: Fix issue when logging end is at 1G firmware: hello_pi: Add hello_mmal_encode example See: raspberrypi/userland#349 firmware: IL ISP: Update to support opaque input firmware: IL ISP: Fix for opaque EOS and excessive finalise calls firmware: khronos: Use low 256M allocations for bin allocations
An example showing how to use the image encoder via MMAL to encode a test image into various formats.