我创建了一个实时连续的 mjpeg 流。粗略的插图是这样的
....[image (jpeg)]->[text "content-length"]->[image (jpeg)]->[text "content-length"]->....
如您所见,我从 gstreamer 媒体管道接收数据,其中包含图像和我自己注入(inject)的文本 (注:虽然我用的是Gstreamer,但我的问题只涉及C++原理。)
为了解析这个实时数据,我正在尝试接收并将其插入队列。随后我打算在队列包含一定数量的数据包后解析“content-length”一词的数据。
我的代码如下所示:
void clear( std::queue<char> &q )
{
std::queue<char> empty;
std::swap( q, empty );
}
static GstFlowReturn new_buffer (GstAppSink *app_sink, gpointer user_data)
{
GstBuffer* buffer = gst_app_sink_pull_buffer(app_sink);
//create queue
std::queue<char> q;
g_print("The input buffer contents are\n");
gint i=0;
for(i=0; buffer->data[i];i++)
{
//g_print("\n%d",i);
q.push(buffer->data[i]);
}
//g_print("\nsize of inbuf is %d\n",GST_BUFFER_SIZE(buffer));
g_print("\n");
gst_buffer_unref(buffer);
//#####################
//parsing method here???
//#####################
clear(q);
return GST_FLOW_OK;
}
我以前在 C/C++ 中使用过循环队列/环形缓冲区。那是最好的选择吗?还是 C++ STL 队列更适合上述场景?
最佳答案
我最终使用了 ringbuffer 类
在头文件中声明
//queue size
enum { rb_size = 5 }; // ---->element1 -> element2 -> .... -> elementN -> gap ->
// ^ |
// | |
// <--------------------<------------------<-------------V
typedef struct
{
char * data[rb_size];
int head, tail;
} ring_buffer_struct;
namespace myspace{
class ring_buffer{
private:
protected:
public:
//========= constructor ============
ring_buffer()
{
//If necessary initialization can happen here.
}
//========== destructor =============
virtual ~ring_buffer()
{
}
//===================================
virtual void rb_start(ring_buffer_struct *b);
virtual bool rb_empty(ring_buffer_struct const *b);
virtual char * rb_front(ring_buffer_struct const *b);
virtual char * rb_rear(ring_buffer_struct const *b);
virtual void rb_pop_front(ring_buffer_struct *b);
virtual ring_buffer_struct* rb_push_back(ring_buffer_struct *b);
}; //end of class
}
在cpp文件中
//start
void myspace::ring_buffer::rb_start(ring_buffer_struct *b)
{
b->head = 0; b->tail = 0;
}
//clear
bool myspace::ring_buffer::rb_empty(ring_buffer_struct const *b)
{
return b->head == b->tail;
}
//front element
char * myspace::ring_buffer::rb_front(ring_buffer_struct const *b)
{
return b->data[b->head]; //data gets popped
}
//rear element
char * myspace::ring_buffer::rb_rear(ring_buffer_struct const *b)
{
return b->data[b->tail]; //data gets pushed
}
//pop out front element
void myspace::ring_buffer::rb_pop_front(ring_buffer_struct *b)
{
if(b->head < b->tail)
{
++b->head;
}
if(b->head > b->tail)
{
b->head = 0;
}
}
//push in rear element
ring_buffer_struct* myspace::ring_buffer::rb_push_back(ring_buffer_struct *b)
{
int new_tail = b->tail;
if (++new_tail >= rb_size)
{ //beginning of the queue
new_tail = 0;
}
if (new_tail != b->head)
{
//middle of the queue
b->tail = new_tail;
}
if (new_tail <= b->head)
{
b->tail = 0;
}
return b;
}
并在 main() 中使用
...
char element1[10] = "abcdefghi";
char element2[10] = "bcdefghij";
char element3[10] = "cdefghijk";
ring_buffer_struct rb;
myspace::ring_buffer q;
q.rb_empty(&rb); //make sure empty
q.rb_start(&rb); //start - initialize
//initialize
uint16_t i;
for(i=0;i<rb_size;i++)
{
rb.data[rb.tail] = (char *)"000000000";
q.rb_push_back(&rb);
}
rb.data[rb.tail] = element1;
q.rb_push_back(&rb);
q.rb_pop_front(&rb); //now parse
rb.data[rb.tail] = element2;
q.rb_push_back(&rb);
q.rb_pop_front(&rb); //now parse
...
对于解析:我看了这篇文章
关于c++ - 在 C++ 中解析从文本内容缓冲区接收的实时 char* 数据的最佳技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7285663/