ENH: refine the timestamp when using P1P

the timestamp of mjpeg is not accurate
we simulate one

Change-Id: I9198f1ba930994cc4f86e8d3a3c778539d04ccb3
This commit is contained in:
lane.wei 2023-01-29 20:27:01 +08:00 committed by Lane.Wei
parent 3d378563b5
commit 6b15afc7b6
4 changed files with 81 additions and 53 deletions

View file

@ -23,11 +23,6 @@ extern "C" {
#ifndef __cplusplus #ifndef __cplusplus
#include <stdbool.h> #include <stdbool.h>
/* We need these workarounds since we're compiling C source, not C++. */
typedef enum Bambu_StreamType Bambu_StreamType;
typedef struct Bambu_StreamInfo Bambu_StreamInfo;
typedef struct Bambu_Sample Bambu_Sample;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -40,31 +35,33 @@ typedef void* Bambu_Tunnel;
typedef void (*Logger)(void * context, int level, tchar const* msg); typedef void (*Logger)(void * context, int level, tchar const* msg);
enum Bambu_StreamType typedef enum __Bambu_StreamType
{ {
VIDE, VIDE,
AUDI AUDI
}; } Bambu_StreamType;
enum Bambu_VideoSubType typedef enum __Bambu_VideoSubType
{ {
AVC1, AVC1,
}; MJPG,
} Bambu_VideoSubType;
enum Bambu_AudioSubType typedef enum __Bambu_AudioSubType
{ {
MP4A MP4A
}; } Bambu_AudioSubType;
enum Bambu_FormatType typedef enum __Bambu_FormatType
{ {
video_avc_packet, video_avc_packet,
video_avc_byte_stream, video_avc_byte_stream,
video_jpeg,
audio_raw, audio_raw,
audio_adts audio_adts
}; } Bambu_FormatType;
struct Bambu_StreamInfo typedef struct __Bambu_StreamInfo
{ {
Bambu_StreamType type; Bambu_StreamType type;
int sub_type; int sub_type;
@ -84,33 +81,34 @@ struct Bambu_StreamInfo
} format; } format;
int format_type; int format_type;
int format_size; int format_size;
int max_frame_size;
unsigned char const * format_buffer; unsigned char const * format_buffer;
}; } Bambu_StreamInfo;
enum Bambu_SampleFlag typedef enum __Bambu_SampleFlag
{ {
f_sync = 1 f_sync = 1
}; } Bambu_SampleFlag;
struct Bambu_Sample typedef struct __Bambu_Sample
{ {
int itrack; int itrack;
int size; int size;
int flags; int flags;
unsigned char const * buffer; unsigned char const * buffer;
unsigned long long decode_time; unsigned long long decode_time;
}; } Bambu_Sample;
enum Bambu_Error typedef enum __Bambu_Error
{ {
Bambu_success, Bambu_success,
Bambu_stream_end, Bambu_stream_end,
Bambu_would_block, Bambu_would_block,
Bambu_buffer_limit Bambu_buffer_limit
}; } Bambu_Error;
#ifdef BAMBU_DYNAMIC #ifdef BAMBU_DYNAMIC
struct BambuLib { typedef struct __BambuLib {
#endif #endif
BAMBU_EXPORT int BAMBU_FUNC(Bambu_Create)(Bambu_Tunnel* tunnel, char const* path); BAMBU_EXPORT int BAMBU_FUNC(Bambu_Create)(Bambu_Tunnel* tunnel, char const* path);
@ -148,7 +146,7 @@ BAMBU_EXPORT char const* BAMBU_FUNC(Bambu_GetLastErrorMsg)();
BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(tchar const* msg); BAMBU_EXPORT void BAMBU_FUNC(Bambu_FreeLogMsg)(tchar const* msg);
#ifdef BAMBU_DYNAMIC #ifdef BAMBU_DYNAMIC
}; } BambuLib;
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -895,7 +895,7 @@ StaticBambuLib &StaticBambuLib::get()
{ {
static StaticBambuLib lib; static StaticBambuLib lib;
// first load the library // first load the library
if (lib.Bambu_Open) if (lib.Bambu_Open)
return lib; return lib;
@ -910,6 +910,8 @@ StaticBambuLib &StaticBambuLib::get()
GET_FUNC(Bambu_Create); GET_FUNC(Bambu_Create);
GET_FUNC(Bambu_Open); GET_FUNC(Bambu_Open);
GET_FUNC(Bambu_StartStream); GET_FUNC(Bambu_StartStream);
GET_FUNC(Bambu_GetStreamCount);
GET_FUNC(Bambu_GetStreamInfo);
GET_FUNC(Bambu_SendMessage); GET_FUNC(Bambu_SendMessage);
GET_FUNC(Bambu_ReadSample); GET_FUNC(Bambu_ReadSample);
GET_FUNC(Bambu_Close); GET_FUNC(Bambu_Close);
@ -922,6 +924,6 @@ StaticBambuLib &StaticBambuLib::get()
return lib; return lib;
} }
extern "C" struct BambuLib *bambulib_get() { extern "C" BambuLib *bambulib_get() {
return &StaticBambuLib::get(); return &StaticBambuLib::get();
} }

View file

@ -2,7 +2,7 @@
* integration with proprietary Bambu Lab blob for getting raw h.264 video * integration with proprietary Bambu Lab blob for getting raw h.264 video
* *
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech> * Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation * to deal in the Software without restriction, including without limitation
@ -62,10 +62,10 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
#else #else
extern extern
#endif #endif
struct BambuLib *bambulib_get(); BambuLib *bambulib_get();
static struct BambuLib *_lib = NULL; BambuLib *_lib = NULL;
#define BAMBULIB(x) (_lib->x) #define BAMBULIB(x) (_lib->x)
#else #else
@ -265,22 +265,22 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
GstBambuSrc *src; GstBambuSrc *src;
src = GST_BAMBUSRC (psrc); src = GST_BAMBUSRC (psrc);
(void) src; (void) src;
GST_DEBUG_OBJECT (src, "create()"); GST_DEBUG_OBJECT (src, "create()");
int rv; int rv;
struct Bambu_Sample sample; Bambu_Sample sample;
if (!src->tnl) { if (!src->tnl) {
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) { while ((rv = BAMBULIB(Bambu_ReadSample)(src->tnl, &sample)) == Bambu_would_block) {
GST_DEBUG_OBJECT(src, "create would block"); GST_DEBUG_OBJECT(src, "create would block");
usleep(33333); /* 30Hz */ usleep(33333); /* 30Hz */
} }
if (rv == Bambu_stream_end) { if (rv == Bambu_stream_end) {
return GST_FLOW_EOS; return GST_FLOW_EOS;
} }
@ -288,7 +288,7 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
if (rv != Bambu_success) { if (rv != Bambu_success) {
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
#if GLIB_CHECK_VERSION(2,68,0) #if GLIB_CHECK_VERSION(2,68,0)
gpointer sbuf = g_memdup2(sample.buffer, sample.size); gpointer sbuf = g_memdup2(sample.buffer, sample.size);
#else #else
@ -300,12 +300,24 @@ gst_bambusrc_create (GstPushSrc * psrc, GstBuffer ** outbuf)
* need to feed this in too -- otherwise the GStreamer pipeline gets upset * need to feed this in too -- otherwise the GStreamer pipeline gets upset
* and starts triggering QoS events. * and starts triggering QoS events.
*/ */
if (!src->sttime) { if (src->video_type == AVC1) {
src->sttime = sample.decode_time * 100ULL; if (!src->sttime) {
src->sttime = sample.decode_time * 100ULL;
}
GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime;
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
}
else {
if (!src->sttime) {
src->sttime = gst_element_get_current_clock_time((GstElement *)psrc);
//if (GST_CLOCK_TIME_NONE == src->sttime)
// src->sttime
}
GST_BUFFER_DTS(*outbuf) = gst_element_get_current_clock_time((GstElement *)psrc) - src->sttime;
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
} }
GST_BUFFER_DTS(*outbuf) = sample.decode_time * 100ULL - src->sttime;
GST_BUFFER_PTS(*outbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION(*outbuf) = GST_CLOCK_TIME_NONE;
return GST_FLOW_OK; return GST_FLOW_OK;
} }
@ -322,13 +334,13 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
GstBambuSrc *src = GST_BAMBUSRC (bsrc); GstBambuSrc *src = GST_BAMBUSRC (bsrc);
GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location); GST_DEBUG_OBJECT (src, "start(\"%s\")", src->location);
if (src->tnl) { if (src->tnl) {
BAMBULIB(Bambu_Close)(src->tnl); BAMBULIB(Bambu_Close)(src->tnl);
BAMBULIB(Bambu_Destroy)(src->tnl); BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL; src->tnl = NULL;
} }
#ifdef BAMBU_DYNAMIC #ifdef BAMBU_DYNAMIC
if (!_lib) { if (!_lib) {
_lib = bambulib_get(); _lib = bambulib_get();
@ -340,15 +352,15 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) { if (BAMBULIB(Bambu_Create)(&src->tnl, src->location) != Bambu_success) {
return FALSE; return FALSE;
} }
BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src); BAMBULIB(Bambu_SetLogger)(src->tnl, _log, (void *)src);
if (BAMBULIB(Bambu_Open)(src->tnl) != Bambu_success) { if (BAMBULIB(Bambu_Open)(src->tnl) != Bambu_success) {
BAMBULIB(Bambu_Destroy)(src->tnl); BAMBULIB(Bambu_Destroy)(src->tnl);
src->tnl = NULL; src->tnl = NULL;
return FALSE; return FALSE;
} }
int rv; int rv, n = 0;
while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) { while ((rv = BAMBULIB(Bambu_StartStream)(src->tnl, 1 /* video */)) == Bambu_would_block) {
usleep(100000); usleep(100000);
} }
@ -359,6 +371,21 @@ gst_bambusrc_start (GstBaseSrc * bsrc)
return FALSE; return FALSE;
} }
src->video_type = AVC1;
n = BAMBULIB(Bambu_GetStreamCount)(src->tnl);
GST_INFO_OBJECT (src, "Bambu_GetStreamCount returned stream count=%d",n);
for (int i = 0; i < n; ++i) {
Bambu_StreamInfo info;
BAMBULIB(Bambu_GetStreamInfo)(src->tnl, i, &info);
GST_INFO_OBJECT (src, "stream %d type=%d, sub_type=%d", i, info.type, info.sub_type);
if (info.type == VIDE) {
src->video_type = info.sub_type;
GST_INFO_OBJECT (src, " width %d height=%d, frame_rate=%d",
info.format.video.width, info.format.video.height, info.format.video.frame_rate);
}
}
src->sttime = 0; src->sttime = 0;
return TRUE; return TRUE;
} }
@ -384,9 +411,9 @@ gst_bambusrc_change_state (GstElement * element, GstStateChange transition)
{ {
GstStateChangeReturn ret; GstStateChangeReturn ret;
GstBambuSrc *src; GstBambuSrc *src;
src = GST_BAMBUSRC (element); src = GST_BAMBUSRC (element);
(void) src; (void) src;
switch (transition) { switch (transition) {
@ -430,7 +457,7 @@ static gboolean
gst_bambusrc_is_seekable (GstBaseSrc * bsrc) gst_bambusrc_is_seekable (GstBaseSrc * bsrc)
{ {
GstBambuSrc *src = GST_BAMBUSRC (bsrc); GstBambuSrc *src = GST_BAMBUSRC (bsrc);
(void) src; (void) src;
return FALSE; return FALSE;
@ -523,7 +550,7 @@ static void
gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data) gst_bambusrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
{ {
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface; GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_bambusrc_uri_get_type; iface->get_type = gst_bambusrc_uri_get_type;
iface->get_protocols = gst_bambusrc_uri_get_protocols; iface->get_protocols = gst_bambusrc_uri_get_protocols;
iface->get_uri = gst_bambusrc_uri_get_uri; iface->get_uri = gst_bambusrc_uri_get_uri;
@ -544,7 +571,7 @@ void gstbambusrc_register()
if (did_register) if (did_register)
return; return;
did_register = 1; did_register = 1;
gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio"); gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bambusrc", "Bambu Lab source", gstbambusrc_init, "0.0.1", "GPL", "BambuStudio", "BambuStudio", "https://github.com/bambulab/BambuStudio");
} }

View file

@ -2,7 +2,7 @@
* integration with proprietary Bambu Lab blob for getting raw h.264 video * integration with proprietary Bambu Lab blob for getting raw h.264 video
* *
* Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech> * Copyright (C) 2023 Joshua Wise <joshua@accelerated.tech>
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation * to deal in the Software without restriction, including without limitation
@ -64,6 +64,7 @@ struct _GstBambuSrc
gchar *location; gchar *location;
Bambu_Tunnel tnl; Bambu_Tunnel tnl;
GstClockTime sttime; GstClockTime sttime;
int video_type;
}; };
extern void gstbambusrc_register(); extern void gstbambusrc_register();