Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions libcam/libcam_v4l2core/frame_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ int alloc_v4l2_frames(v4l2_dev_t *vd)
/*frame queue*/
for(i=0; i<vd->frame_queue_size; ++i)
{
vd->frame_queue[i].yuv_frame_max_size = (size_t) framesizeIn;
vd->frame_queue[i].yuv_frame = calloc((size_t) framesizeIn, sizeof(uint8_t));
if(vd->frame_queue[i].yuv_frame == NULL)
{
Expand Down Expand Up @@ -346,6 +347,7 @@ void clean_v4l2_frames(v4l2_dev_t *vd)
free(vd->frame_queue[i].yuv_frame);
vd->frame_queue[i].yuv_frame = NULL;
}
vd->frame_queue[i].yuv_frame_max_size = 0;
}

if(vd->h264_last_IDR)
Expand Down Expand Up @@ -828,6 +830,44 @@ int decode_v4l2_frame(v4l2_dev_t *vd, v4l2_frame_buff_t *frame)
//}
if(verbosity > 3)
fprintf(stderr, "V4L2_CORE: (jpeg decoder) decode frame of size %i\n", ret);
if (ret >= 0)
{
int real_w = 0;
int real_h = 0;
if (jpeg_get_decoded_size(&real_w, &real_h) == 0 &&
real_w > 0 && real_h > 0 &&
(real_w != frame->width || real_h != frame->height))
{
if(verbosity > 0)
fprintf(stderr, "V4L2_CORE: (jpeg decoder) frame size %dx%d != negotiated %dx%d, using real size\n",
real_w, real_h, frame->width, frame->height);
frame->width = real_w;
frame->height = real_h;
}

if (real_w > 0 && real_h > 0)
{
size_t need = (size_t)real_w * (size_t)real_h * 3 / 2;
if (need > 0 && need != frame->yuv_frame_max_size)
{
uint8_t *p = (uint8_t *)realloc(frame->yuv_frame, need);
if (p)
{
frame->yuv_frame = p;
frame->yuv_frame_max_size = need;
if(verbosity > 0)
fprintf(stderr, "V4L2_CORE: (jpeg decoder) yuv_frame trimmed %dx%d (%zu bytes)\n",
real_w, real_h, need);
}
else
{
if(verbosity > 0)
fprintf(stderr, "V4L2_CORE: (jpeg decoder) realloc failed for yuv_frame, keep old size\n");
return E_ALLOC_ERR;
}
}
}
}
ret = E_OK;
break;

Expand Down
1 change: 1 addition & 0 deletions libcam/libcam_v4l2core/gviewv4l2core.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ typedef struct _v4l2_frame_buff_t {
uint64_t timestamp; // captured frame timestamp

uint8_t *raw_frame; // pointer to raw frame
size_t yuv_frame_max_size; //maximum size for decoded yuv frame (bytes); MJPG is trimmed to real decoded size after 1st frame
uint8_t *yuv_frame; // pointer to decoded yuv frame
uint8_t *h264_frame; // pointer to regular or demultiplexed h264 frame
uint8_t *tmp_buffer; //temporary buffer used in decoding
Expand Down
69 changes: 61 additions & 8 deletions libcam/libcam_v4l2core/jpeg_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,8 +1430,6 @@ int jpeg_init_decoder(int width, int height)
}

codec_data->context->pix_fmt = AV_PIX_FMT_YUV422P;
codec_data->context->width = width;
codec_data->context->height = height;
//jpeg_ctx->context->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);

// Initialize hardware device context (VA-API)
Expand Down Expand Up @@ -1582,9 +1580,26 @@ int jpeg_decode(uint8_t *out_buf, uint8_t *in_buf, int size)
printf(" - %s\n", getAvutil()->m_av_get_pix_fmt_name((enum AVPixelFormat)AV_PIX_FMT_YUV420P));
}
#if LIBAVUTIL_VER_AT_LEAST(54,6)
getAvutil()->m_av_image_copy_to_buffer(jpeg_ctx->tmp_frame, jpeg_ctx->pic_size,
(const uint8_t * const*) sw_frame->data, sw_frame->linesize,
sw_frame->format, jpeg_ctx->width, jpeg_ctx->height, 1);
{
int dec_w = sw_frame->width;
int dec_h = sw_frame->height;
int need = getAvutil()->m_av_image_get_buffer_size(sw_frame->format, dec_w, dec_h, 1);
if (need > 0 && (size_t)need > (size_t)jpeg_ctx->pic_size) {
uint8_t *p = realloc(jpeg_ctx->tmp_frame, (size_t)need);
if (!p) {
fprintf(stderr, "V4L2_CORE: (jpeg decoder) realloc failed for tmp_frame\n");
getAvutil()->m_av_frame_free(&sw_frame);
return -1;
}
jpeg_ctx->tmp_frame = p;
jpeg_ctx->pic_size = need;
}
jpeg_ctx->width = dec_w;
jpeg_ctx->height = dec_h;
getAvutil()->m_av_image_copy_to_buffer(jpeg_ctx->tmp_frame, jpeg_ctx->pic_size,
(const uint8_t * const*) sw_frame->data, sw_frame->linesize,
sw_frame->format, dec_w, dec_h, 1);
}
if (sw_frame->format == AV_PIX_FMT_NV12) {
nv12_to_yu12(out_buf, jpeg_ctx->tmp_frame, jpeg_ctx->width, jpeg_ctx->height);
getAvutil()->m_av_frame_free(&sw_frame);
Expand All @@ -1609,9 +1624,26 @@ int jpeg_decode(uint8_t *out_buf, uint8_t *in_buf, int size)
}
decodeCount++;
}
getAvutil()->m_av_image_copy_to_buffer(jpeg_ctx->tmp_frame, jpeg_ctx->pic_size,
(const uint8_t * const*) codec_data->picture->data, codec_data->picture->linesize,
codec_data->context->pix_fmt, jpeg_ctx->width, jpeg_ctx->height, 1);
{
int dec_w = codec_data->picture->width;
int dec_h = codec_data->picture->height;
enum AVPixelFormat dec_fmt = codec_data->picture->format;
int need = getAvutil()->m_av_image_get_buffer_size(dec_fmt, dec_w, dec_h, 1);
if (need > 0 && (size_t)need > (size_t)jpeg_ctx->pic_size) {
uint8_t *p = realloc(jpeg_ctx->tmp_frame, (size_t)need);
if (!p) {
fprintf(stderr, "V4L2_CORE: (jpeg decoder) realloc failed for tmp_frame\n");
return -1;
}
jpeg_ctx->tmp_frame = p;
jpeg_ctx->pic_size = need;
}
jpeg_ctx->width = dec_w;
jpeg_ctx->height = dec_h;
getAvutil()->m_av_image_copy_to_buffer(jpeg_ctx->tmp_frame, jpeg_ctx->pic_size,
(const uint8_t * const*) codec_data->picture->data, codec_data->picture->linesize,
dec_fmt, dec_w, dec_h, 1);
}
#else
avpicture_layout((AVPicture *) codec_data->picture, codec_data->dec_ctx->pix_fmt,
jpeg_ctx->width, jpeg_ctx->height, jpeg_ctx->tmp_frame, jpeg_ctx->pic_size);
Expand Down Expand Up @@ -1640,6 +1672,27 @@ int jpeg_decode(uint8_t *out_buf, uint8_t *in_buf, int size)

}

/*
* get real (decoded) frame size
* args:
* out_w - pointer to receive real decoded width (may be NULL)
* out_h - pointer to receive real decoded height (may be NULL)
*
* asserts:
* none
*
* returns: 0 on success (valid size available); negative if not initialized
* or not decoded yet
*/
int jpeg_get_decoded_size(int *out_w, int *out_h)
{
if (jpeg_ctx == NULL || jpeg_ctx->width <= 0 || jpeg_ctx->height <= 0)
return -1;
if (out_w) *out_w = jpeg_ctx->width;
if (out_h) *out_h = jpeg_ctx->height;
return 0;
}

/*
* close (m)jpeg decoder context
* args:
Expand Down
10 changes: 10 additions & 0 deletions libcam/libcam_v4l2core/jpeg_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ int jpeg_init_decoder(int width, int height);
*/
int jpeg_decode(uint8_t *out_buf, uint8_t *in_buf, int size);

/*
* get real (decoded) frame size after jpeg_decode()
* args:
* out_w - pointer to receive real decoded width (may be NULL)
* out_h - pointer to receive real decoded height (may be NULL)
*
* returns: 0 - OK; negative - not initialized or not decoded yet
*/
int jpeg_get_decoded_size(int *out_w, int *out_h);

/*
* close (m)jpeg decoder context
* args:
Expand Down
Loading