Skip to content

Commit

Permalink
(shmif/decode) enable h264 passthrough in uvc
Browse files Browse the repository at this point in the history
This follows the previous passthrough commit with its implementation
in uvc-support for decode. Shmif-server is also modified slightly to
revert to uncompressed frame if the fourcc gets unset for a frame in
order to support transitioning back without an explicit synch pass.

My camera is acting up so fairly untested still and the _RESET event
is still not respected meaning that the harder test case:

  1. hook up through afsrv_decode (no passthrough)
  2. force-redirect to arcan-net -s test (while camera active)
  3. reset-camera feed and swap to passthrough.
  4. redirect-back and disable passthrough.

is still not handled.
  • Loading branch information
letoram committed May 20, 2023
1 parent aeb71b5 commit fd6f24d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 10 deletions.
62 changes: 53 additions & 9 deletions src/frameserver/decode/default/uvc_support.c
Expand Up @@ -32,6 +32,7 @@
#include <math.h>

static int video_buffer_count = 1;
static bool h264_passthrough = false;

/* should also have the option to convert to GPU texture here and pass
* onwards rather than paying the conversion proce like this */
Expand Down Expand Up @@ -123,9 +124,18 @@ static void frame_ffmpeg(
static AVFrame* frame;
static AVPacket* packet;

/* missing:
* - test shmif for the ability to tunnel raw h264 (important for a12)
*/
/* use to free / reset parser context */
if (!uvc){
if (decode)
avcodec_free_context(&decode);
if (parser)
parser = (av_parser_close(parser), NULL);
if (packet)
av_packet_free(&packet);
if (frame)
av_frame_free(&frame);
return;
}

/* this is the same code used in a12/a12_decode.c */
if (!codec){
Expand Down Expand Up @@ -224,11 +234,42 @@ static void callback(uvc_frame_t* frame, void* tag)
/* guarantee dimensions */
if (cont->w != frame->width || cont->h != frame->height){
if (!arcan_shmif_resize_ext(cont, frame->width, frame->height,
(struct shmif_resize_ext){.vbuf_cnt = video_buffer_count})){
(struct shmif_resize_ext){
.vbuf_cnt = video_buffer_count,
.meta = h264_passthrough ? SHMIF_META_VENC : 0
})){
return;
}
}

if (h264_passthrough && frame->frame_format == UVC_FRAME_FORMAT_H264){
struct arcan_shmif_venc* venc =
arcan_shmif_substruct(cont, SHMIF_META_VENC).venc;
if (!venc){
h264_passthrough = false;
LOG("status=feature:h264_passthrough=false");
}
/* sanity-check fail, revert to normal */
else {
if (frame->data_bytes > cont->w * cont->h * sizeof(shmif_pixel)){
venc->fourcc[0] = 0;
h264_passthrough = false;
}
else {
venc->fourcc[0] = 'H';
venc->fourcc[1] = '2';
venc->fourcc[2] = '6';
venc->fourcc[3] = '4';

venc->framesize = frame->data_bytes;
LOG("status=frame:h264_passthrough=true:size=%zu", (size_t) frame->data_bytes);
memcpy(cont->vidb, frame->data, venc->framesize);
arcan_shmif_signal(cont, SHMIF_SIGVID);
return;
}
}
}

/* conversion / repack */
switch(frame->frame_format){
/* 'actually YUY2 is also called YUYV which is YUV420' (what a mess)
Expand Down Expand Up @@ -525,17 +566,20 @@ bool uvc_support_activate(
goto out;
}

if (fmt == UVC_FRAME_FORMAT_H264 && !arg_lookup(args, "no_pass", 0, NULL)){
h264_passthrough = true;
}

int rv = uvc_start_streaming(devh, &ctrl, callback, cont, 0);
if (rv < 0){
arcan_shmif_last_words(cont, "uvc- error when streaming");
goto out;
}

/* this one is a bit special, optimally we'd want to check cont and
* see if we have GPU access - if there is one, we should try and get
* the camera native format, upload that to a texture and repack /
* convert there - for now just set RGBX and hope that uvc can unpack
* without further conversion */
/* this one is a bit special, optimally we'd want to check cont and see if we
* have GPU access - if there is one, we should try and get the camera native
* format, upload that to a texture and repack / convert there - for now just
* set RGBX and hope that uvc can unpack without further conversion */
arcan_shmif_privsep(cont, "minimal", NULL, 0);

struct arcan_event ev;
Expand Down
2 changes: 1 addition & 1 deletion src/shmif/arcan_shmif_server.c
Expand Up @@ -479,7 +479,7 @@ struct shmifsrv_vbuffer shmifsrv_video(struct shmifsrv_client* cl)
memcpy(res.fourcc, cl->con->desc.aext.venc->fourcc, 4);
res.buffer_sz = cl->con->desc.aext.venc->framesize;
}
res.flags.compressed = true;
res.flags.compressed = res.fourcc[0] != 0;
}

return res;
Expand Down

0 comments on commit fd6f24d

Please sign in to comment.