Capturing JPEG images at full (allowed) resolution on DM36x platform

From RidgeRun Developer Connection

Revision as of 20:15, 21 November 2011 by Mmadrigal (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to:navigation, search

Contents

Introduction

This whitepaper shows how to configure the SDK to capture the maximum allowed image size on the LeopardBoard DM36x. When this document was wrote the maximum allowed resolution for still images was of 2176x1944 pixels.

Hardware used

Configuring the SDK to capture 2176x1944 still images

Our first goal is to get a simple raw data capture from the sensor with a fixed resolution of 2176x1944 pixels, so we can start with the following pipeline:

gst-launch --gst-debug=v4l2:5 v4l2src always-copy=false chain-ipipe=true num-buffers=1 ! \
'video/x-raw-yuv,format=(fourcc)UYVY, width=2176, height=1944' ! fakesink

On first run we should get a segmentation fault error like this:

/ # gst-launch -e v4l2src always-copy=false num-buffers=1 chain-ipipe=true ! 'vi
deo/x-raw-yuv,format=(fourcc)UYVY, width=2176, height=1944' ! dmaiaccel ! dmaien
c_jpeg ! filesink location=test_dmai_3.jpeg
Setting pipeline to PAUSED ...
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
vpfe-capture vpfe-capture: standard not supported
vpfe-capture vpfe-capture: dma_alloc_coherent size 8462336 failed
Segmentation fault

The line vpfe-capture vpfe-capture: dma_alloc_coherent size 8462336 failed indicates there is not enough space in the capture/input buffer.

Now if we run the same pipeline with a little bit more of debug we can see something like that:

gst_v4l2_object_probe_caps_for_format:<v4l2src0> done iterating discrete frame sizes
gst_v4l2_object_set_format:<v4l2src0> Setting format to 2176x1944, format UYVY
gst_v4l2_buffer_pool_new:<v4l2src0> STREAMING, requesting 2 MMAP buffers
gst_v4l2_buffer_pool_new:<v4l2src0>  count:  3
gst_v4l2_buffer_pool_new:<v4l2src0>  type:   1
gst_v4l2_buffer_pool_new:<v4l2src0>  memory: 1
gst_v4l2_buffer_pool_new:<v4l2src0> using 3 buffers instead
gst_v4l2_buffer_new:<v4l2src0> creating buffer 0, 0x2aac0 in pool 0x1ee70
gst_v4l2_buffer_new:<v4l2src0>   index:     0
gst_v4l2_buffer_new:<v4l2src0>   type:      1
gst_v4l2_buffer_new:<v4l2src0>   bytesused: 0
gst_v4l2_buffer_new:<v4l2src0>   flags:     00000000
gst_v4l2_buffer_new:<v4l2src0>   field:     0
gst_v4l2_buffer_new:<v4l2src0>   memory:    1
gst_v4l2_buffer_new:<v4l2src0>   MMAP offset:  0
gst_v4l2_buffer_new:<v4l2src0>   length:    8460288
gst_v4l2_buffer_new:<v4l2src0>   input:     0
gst_v4l2_buffer_new:<v4l2src0> creating buffer 1, 0x2aa20 in pool 0x1ee70
gst_v4l2_buffer_new:<v4l2src0>   index:     1
gst_v4l2_buffer_new:<v4l2src0>   type:      1
gst_v4l2_buffer_new:<v4l2src0>   bytesused: 0
gst_v4l2_buffer_new:<v4l2src0>   flags:     00000000
gst_v4l2_buffer_new:<v4l2src0>   field:     0
gst_v4l2_buffer_new:<v4l2src0>   memory:    1
gst_v4l2_buffer_new:<v4l2src0>   MMAP offset:  8462336
gst_v4l2_buffer_new:<v4l2src0>   length:    8460288
gst_v4l2_buffer_new:<v4l2src0>   input:     0
gst_v4l2_buffer_new: Failed to mmap: Cannot allocate memory
gst_v4l2_buffer_finalize:<v4l2src0> finalizing buffer 0x2aa20 1
gst_v4l2_buffer_finalize:<v4l2src0> the pool is shutting down
gst_v4l2_buffer_finalize:<v4l2src0> buffer 0x2aa20 (data (nil), len 8460288) not recovered, unmapping

As we can see it is not possible to allocated the 3 required buffers, where each one have a size equal to:

BUFF_SIZE = W*H*2

In theory we just need to increase the capture buffer size to 3 times this value, but in practice it was found that we require the double of memory space:

CAPTURE_BUFF_SIZE = W*H*2*6 = 2176*1944*2*6 = 50761728

We can set this value on

 -> Architecture configurations
    -> Maximum Video Input Buffer Size

setting this option to Other (enter buffer size) and setting the Buffer size for v4l2 input field to this value.

Now, once we rebuild out SDK we got the following output when running the pipeline:

/ # gst-launch v4l2src always-copy=false chain-ipipe=true num-buffers=1 ! 'video
/x-raw-yuv,format=(fourcc)UYVY, width=2176, height=1944' ! fakesink 
Setting pipeline to PAUSED ...
davinci_resizer davinci_resizer.2: RSZ_G_CONFIG:0:1:124
vpfe-capture vpfe-capture: IPIPE Chained
vpfe-capture vpfe-capture: Resizer present
vpfe-capture vpfe-capture: standard not supported
Pipeline is live and does not need PREROLL ...
WARNING: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Failed to set norm for device '/dev/video0'.
Additional debug info:
../../../src/sys/v4l2/v4l2_calls.c(743): gst_v4l2_set_norm (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
system error: Invalid argument
WARNING: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Video input device did not accept new frame rate setting.
Additional debug info:
../../../src/sys/v4l2/v4l2src_calls.c(342): gst_v4l2src_set_capture (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
system error: Invalid argument
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Got EOS from element "pipeline0".
Execution ended after 84000331 ns.
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
/ # 

Which represents a correct output. If we run this pipeline with debug options we should be able to see a section like this:

gst_v4l2_object_probe_caps_for_format:<v4l2src0> done iterating discrete frame sizes
gst_v4l2_object_set_format:<v4l2src0> Setting format to 2176x1944, format UYVY
gst_v4l2_buffer_pool_new:<v4l2src0> STREAMING, requesting 2 MMAP buffers
gst_v4l2_buffer_pool_new:<v4l2src0>  count:  3
gst_v4l2_buffer_pool_new:<v4l2src0>  type:   1
gst_v4l2_buffer_pool_new:<v4l2src0>  memory: 1
gst_v4l2_buffer_pool_new:<v4l2src0> using 3 buffers instead
gst_v4l2_buffer_new:<v4l2src0> creating buffer 0, 0x2aac0 in pool 0x1ee70
gst_v4l2_buffer_new:<v4l2src0>   index:     0
gst_v4l2_buffer_new:<v4l2src0>   type:      1
gst_v4l2_buffer_new:<v4l2src0>   bytesused: 0
gst_v4l2_buffer_new:<v4l2src0>   flags:     00000000
gst_v4l2_buffer_new:<v4l2src0>   field:     0
gst_v4l2_buffer_new:<v4l2src0>   memory:    1
gst_v4l2_buffer_new:<v4l2src0>   MMAP offset:  0
gst_v4l2_buffer_new:<v4l2src0>   length:    8460288
gst_v4l2_buffer_new:<v4l2src0>   input:     0
gst_v4l2_buffer_new:<v4l2src0> creating buffer 1, 0x2aa20 in pool 0x1ee70
gst_v4l2_buffer_new:<v4l2src0>   index:     1
gst_v4l2_buffer_new:<v4l2src0>   type:      1
gst_v4l2_buffer_new:<v4l2src0>   bytesused: 0
gst_v4l2_buffer_new:<v4l2src0>   flags:     00000000
gst_v4l2_buffer_new:<v4l2src0>   field:     0
gst_v4l2_buffer_new:<v4l2src0>   memory:    1
gst_v4l2_buffer_new:<v4l2src0>   MMAP offset:  8462336
gst_v4l2_buffer_new:<v4l2src0>   length:    8460288
gst_v4l2_buffer_new:<v4l2src0>   input:     0
gst_v4l2_buffer_new:<v4l2src0> creating buffer 2, 0x2a980 in pool 0x1ee70
gst_v4l2_buffer_new:<v4l2src0>   index:     2
gst_v4l2_buffer_new:<v4l2src0>   type:      1
gst_v4l2_buffer_new:<v4l2src0>   bytesused: 0
gst_v4l2_buffer_new:<v4l2src0>   flags:     00000000
gst_v4l2_buffer_new:<v4l2src0>   field:     0
gst_v4l2_buffer_new:<v4l2src0>   memory:    1
gst_v4l2_buffer_new:<v4l2src0>   MMAP offset:  16924672
gst_v4l2_buffer_new:<v4l2src0>   length:    8460288
gst_v4l2_buffer_new:<v4l2src0>   input:     0
gst_v4l2_buffer_pool_qbuf:<v4l2src0> enqueue pool buffer 0
gst_v4l2_buffer_pool_qbuf:<v4l2src0> num_live_buffers--: 2
gst_v4l2_buffer_pool_qbuf:<v4l2src0> enqueue pool buffer 1
gst_v4l2_buffer_pool_qbuf:<v4l2src0> num_live_buffers--: 1
gst_v4l2_buffer_pool_qbuf:<v4l2src0> enqueue pool buffer 2
gst_v4l2_buffer_pool_qbuf:<v4l2src0> num_live_buffers--: 0
Pipeline is live and does not need PREROLL ...

Here we can see how this time it was possible to allocated the 3 buffers.

Adding encoding stage

Navigation
Toolbox