[libcamera-devel] [PATCH] qcam: Add JPEG format support

Kieran Bingham kieran.bingham at ideasonboard.com
Fri Mar 29 16:39:57 CET 2019


Hi Laurent,

Thank you for this - with a [small hack]* this brings me the ability to
view my UVC web camera using LibCamera and QCam on my laptop.

*small hack: UVC Pipeline handler requires updating to support MJPEG.

On 29/03/2019 15:27, Laurent Pinchart wrote:
> When the camera provides MJPEG, use the QImage JPEG decompression code
> to convert that to RGB.


Tested-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>

> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
>  src/qcam/format_converter.cpp | 16 +++++++++++++++-
>  src/qcam/format_converter.h   |  9 ++++++++-
>  src/qcam/main_window.cpp      |  2 +-
>  src/qcam/viewfinder.cpp       |  4 ++--
>  src/qcam/viewfinder.h         |  2 +-
>  5 files changed, 27 insertions(+), 6 deletions(-)
> 
> diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
> index 6979a054c0ca..bda9057e17b6 100644
> --- a/src/qcam/format_converter.cpp
> +++ b/src/qcam/format_converter.cpp
> @@ -9,6 +9,8 @@
>  
>  #include <linux/videodev2.h>
>  
> +#include <QImage>
> +
>  #include "format_converter.h"
>  
>  #define RGBSHIFT		8
> @@ -45,16 +47,28 @@ int FormatConverter::configure(unsigned int format, unsigned int width,
>  		y_pos_ = 0;
>  		cb_pos_ = 1;
>  		break;
> +	case V4L2_PIX_FMT_MJPEG:
> +		break;
>  	default:
>  		return -EINVAL;
>  	};
>  
> +	format_ = format;
>  	width_ = width;
>  	height_ = height;
>  
>  	return 0;
>  }
>  
> +void FormatConverter::convert(const unsigned char *src, size_t size,
> +			      QImage *dst)
> +{
> +	if (format_ == V4L2_PIX_FMT_MJPEG)
> +		dst->loadFromData(src, size, "JPEG");
> +	else
> +		convertYUV(src, dst->bits());
> +}
> +
>  static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
>  {
>  	int c = y - 16;
> @@ -65,7 +79,7 @@ static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
>  	*b = CLIP(( 298 * c + 516 * d           + 128) >> RGBSHIFT);
>  }
>  
> -void FormatConverter::convert(const unsigned char *src, unsigned char *dst)
> +void FormatConverter::convertYUV(const unsigned char *src, unsigned char *dst)
>  {
>  	unsigned int src_x, src_y, dst_x, dst_y;
>  	unsigned int src_stride;
> diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
> index 196064c74f65..396d0bea116a 100644
> --- a/src/qcam/format_converter.h
> +++ b/src/qcam/format_converter.h
> @@ -7,15 +7,22 @@
>  #ifndef __QCAM_FORMAT_CONVERTER_H__
>  #define __QCAM_FORMAT_CONVERTER_H__
>  
> +#include <stddef.h>
> +
> +class QImage;
> +
>  class FormatConverter
>  {
>  public:
>  	int configure(unsigned int format, unsigned int width,
>  		      unsigned int height);
>  
> -	void convert(const unsigned char *src, unsigned char *dst);
> +	void convert(const unsigned char *src, size_t size, QImage *dst);
>  
>  private:
> +	void convertYUV(const unsigned char *src, unsigned char *dst);
> +
> +	unsigned int format_;
>  	unsigned int width_;
>  	unsigned int height_;
>  	unsigned int y_pos_;
> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
> index a148aa4d117f..fea701422015 100644
> --- a/src/qcam/main_window.cpp
> +++ b/src/qcam/main_window.cpp
> @@ -222,7 +222,7 @@ int MainWindow::display(Buffer *buffer)
>  
>  	Plane &plane = buffer->planes().front();
>  	unsigned char *raw = static_cast<unsigned char *>(plane.mem());
> -	viewfinder_->display(raw);
> +	viewfinder_->display(raw, buffer->bytesused());
>  
>  	return 0;
>  }
> diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp
> index 5841dc032967..224a227ddd5b 100644
> --- a/src/qcam/viewfinder.cpp
> +++ b/src/qcam/viewfinder.cpp
> @@ -16,9 +16,9 @@ ViewFinder::ViewFinder(QWidget *parent)
>  {
>  }
>  
> -void ViewFinder::display(const unsigned char *raw)
> +void ViewFinder::display(const unsigned char *raw, size_t size)
>  {
> -	converter_.convert(raw, image_->bits());
> +	converter_.convert(raw, size, image_);
>  
>  	QPixmap pixmap = QPixmap::fromImage(*image_);
>  	setPixmap(pixmap);
> diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h
> index df4901699a14..c9ca98913e05 100644
> --- a/src/qcam/viewfinder.h
> +++ b/src/qcam/viewfinder.h
> @@ -20,7 +20,7 @@ public:
>  
>  	int setFormat(unsigned int format, unsigned int width,
>  		      unsigned int height);
> -	void display(const unsigned char *rgb);
> +	void display(const unsigned char *rgb, size_t size);
>  
>  private:
>  	unsigned int format_;
> 

-- 
Regards
--
Kieran


More information about the libcamera-devel mailing list