+#ifndef DTV_STREAM_ID
+#define DTV_STREAM_ID DTV_ISDBS_TS_ID
+#endif
+#define DVB_READ_BUFFER_SIZE 188 * 128
+#define DVB_WRITE_BUFFER_SIZE 1024 * 1024
+#define DMX_BUFFER_SIZE 1024 * 1024
+#define RING_BUFFER_SIZE 1024 * 1024 * 16
+
+typedef struct {
+ void* rb_ptr;
+ int rb_wt;
+ int rb_rt;
+ int rb_ab;
+ pthread_mutex_t rb_mtx;
+} mrb;
+
+typedef struct {
+ int fin;
+ int fout;
+ int rectime;
+ mrb rb;
+ bool done;
+} my_thread_arg;
+
+void * record_read(void * priv);
+void * record_write(void * priv);
+
+// TODO: switchable between VRB(virtual ring buffer) and MRB(My Ring Buffer)
+
+void mrb_init(mrb* rb, size_t size) {
+ rb->rb_ptr = malloc(size);
+ rb->rb_wt = rb->rb_rt = rb->rb_ab = 0;
+ pthread_mutex_init(&rb->rb_mtx, NULL);
+}
+
+void mrb_destroy(mrb* rb) {
+ free(rb->rb_ptr);
+ pthread_mutex_destroy(&rb->rb_mtx);
+}
+
+size_t mrb_data_len(mrb* rb) {
+ return rb->rb_ab;
+}
+
+bool mrb_put(mrb* rb, char *source, size_t size) {
+ int partial;
+
+ if ( rb->rb_ab + size > RING_BUFFER_SIZE ) {
+ // RingBuffer overflow.
+ return false;
+ }
+ if ( rb->rb_wt + size <= RING_BUFFER_SIZE ) {
+ // written bytes + newly added bytes <= buffer max size
+ memcpy(rb->rb_ptr + rb->rb_wt, source, size);
+ rb->rb_wt = rb->rb_wt + size;
+ }
+ else {
+ // written bytes + newly added bytes > buffer max size
+ // wrap around.
+ partial = RING_BUFFER_SIZE - rb->rb_wt;
+ memcpy(rb->rb_ptr + rb->rb_wt, source, partial);
+ memcpy(rb->rb_ptr, source + partial, size - partial);
+ rb->rb_wt = rb->rb_wt + size - RING_BUFFER_SIZE;
+ }
+ pthread_mutex_lock(&rb->rb_mtx);
+ rb->rb_ab += size;
+ pthread_mutex_unlock(&rb->rb_mtx);
+
+ return true;
+}
+
+bool mrb_get(mrb* rb, char *target, size_t size) {
+ int partial;
+
+ if ( rb->rb_ab < size ) {
+ // RingBuffer underflow.
+ return false;
+ }
+ if ( rb->rb_rt + size <= RING_BUFFER_SIZE ) {
+ // read bytes + newly taken bytes <= buffer max size
+ memcpy(target, rb->rb_ptr + rb->rb_rt, size);
+ rb->rb_rt = rb->rb_rt + size;
+ }
+ else {
+ // read bytes + newly taken bytes > buffer max size
+ // wrap around.
+ partial = RING_BUFFER_SIZE - rb->rb_rt;
+ memcpy(target, rb->rb_ptr + rb->rb_rt, partial);
+ memcpy(target + partial, rb->rb_ptr, size - partial);
+ rb->rb_rt = rb->rb_rt + size - RING_BUFFER_SIZE;
+ }
+ pthread_mutex_lock(&rb->rb_mtx);
+ rb->rb_ab -= size;
+ pthread_mutex_unlock(&rb->rb_mtx);
+
+ return true;
+}