#include "../../src/mixframemanager.h"
gboolean stop_thread = FALSE;
GCond* data_cond = NULL;
GMutex* data_mutex = NULL;
void *deque_function(void *data) {
MixFrameManager *fm = (MixFrameManager *) data;
MIX_RESULT mixresult;
MixVideoFrame *mvf = NULL;
guint64 pts;
while(!stop_thread) {
g_mutex_lock (data_mutex);
mixresult = mix_framemanager_dequeue(fm, &mvf);
if(mixresult == MIX_RESULT_SUCCESS) {
mixresult = mix_videoframe_get_timestamp(mvf, &pts);
g_print("dequeued timestamp = %"G_GINT64_FORMAT"\n", pts);
/* mix_videoframe_unref(mvf); */
} else if(mixresult == MIX_RESULT_FRAME_NOTAVAIL) {
g_print("mixresult == MIX_RESULT_FRAME_NOTAVAIL\n");
g_cond_wait (data_cond, data_mutex);
}
g_mutex_unlock (data_mutex);
}
}
void shuffle(GPtrArray *list) {
guint idx, jdx;
guint len = list->len;
for (idx = 0; idx < len - 1; idx++) {
jdx = rand() % len;
if (idx != jdx) {
gpointer tmp = g_ptr_array_index(list, jdx);
g_ptr_array_index(list, jdx) = g_ptr_array_index(list, idx);
g_ptr_array_index(list, idx) = tmp;
}
}
}
int main() {
MIX_RESULT mixresult;
gint fps_n = 24000;
gint fps_d = 1001;
/*
gint fps_n = 2500000;
gint fps_d = 104297;
*/
GPtrArray *fa = NULL;
MixFrameManager *fm = NULL;
MixVideoFrame *mvf = NULL;
MixVideoFrame *mvf_1st = NULL;
gint idx = 0;
guint64 pts = 0;
GThread *deque_thread = NULL;
GError *deque_thread_error = NULL;
/* first ting first */
g_type_init();
/* create frame manager */
fm = mix_framemanager_new();
if (!fm) {
goto cleanup;
}
/* initialize frame manager */
mixresult = mix_framemanager_initialize(fm,
MIX_FRAMEORDER_MODE_DISPLAYORDER, fps_n, fps_d);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
/* create frame_array */
fa = g_ptr_array_sized_new(64);
if (!fa) {
goto cleanup;
}
for (idx = 0; idx < 16; idx++) {
/* generate MixVideoFrame */
mvf = mix_videoframe_new();
if (!mvf) {
goto cleanup;
}
pts = idx * G_USEC_PER_SEC * G_GINT64_CONSTANT(1000) * fps_d / fps_n;
mixresult = mix_videoframe_set_timestamp(mvf, pts);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
g_print("original timestamp = %"G_GINT64_FORMAT"\n", pts);
if (idx == 0) {
mvf_1st = mvf;
} else {
g_ptr_array_add(fa, (gpointer) mvf);
}
}
/* shuffle the array */
shuffle( fa);
data_mutex = g_mutex_new ();
if(!data_mutex) {
goto cleanup;
}
data_cond = g_cond_new();
if(!data_cond) {
goto cleanup;
}
/* create another thread to dequeue */
deque_thread = g_thread_create((GThreadFunc) deque_function, (void *) fm,
TRUE, &deque_thread_error);
if (!deque_thread) {
goto cleanup;
}
/* enqueue */
mixresult = mix_framemanager_enqueue(fm, mvf_1st);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
mixresult = mix_videoframe_get_timestamp(mvf_1st, &pts);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
g_print("shuffled timestamp = %"G_GINT64_FORMAT"\n", pts);
for (idx = 0; idx < fa->len; idx++) {
g_mutex_lock (data_mutex);
/* wait for 100ms to enqueue another frame */
g_usleep(G_USEC_PER_SEC / 10 );
mvf = (MixVideoFrame *) g_ptr_array_index(fa, idx);
mixresult = mix_framemanager_enqueue(fm, mvf);
/* wake up deque thread */
g_cond_signal (data_cond);
g_mutex_unlock (data_mutex);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
mixresult = mix_videoframe_get_timestamp(mvf, &pts);
if (mixresult != MIX_RESULT_SUCCESS) {
goto cleanup;
}
g_print("shuffled timestamp = %"G_GINT64_FORMAT"\n", pts);
}
getchar();
stop_thread = TRUE;
/* wake up deque thread */
g_cond_signal (data_cond);
g_thread_join(deque_thread);
cleanup:
if(data_mutex) {
g_mutex_free(data_mutex);
}
if(data_cond) {
g_cond_free(data_cond);
}
if (fm) {
mix_framemanager_unref(fm);
}
if (fa) {
g_ptr_array_free(fa, TRUE);
}
return 0;
}