/** * Process preview buffers. * * Dequeue each available preview buffer in order and call current redraw * function. If no new buffers are available then the render function is * invoked anyway. * @param state The GL preview window state. * @return Zero if successful. */ static int preview_process_returned_bufs(RASPITEX_STATE* state) { MMAL_BUFFER_HEADER_T *buf; int new_frame = 0; int rc = 0; while ((buf = mmal_queue_get(state->preview_queue)) != NULL) { if (state->preview_stop == 0) { new_frame = 1; rc = raspitex_draw(state, buf); if (rc != 0) { vcos_log_error("%s: Error drawing frame. Stopping.", VCOS_FUNCTION); state->preview_stop = 1; return rc; } } } /* If there were no new frames then redraw the scene again with the previous * texture. Otherwise, go round the loop again to see if any new buffers * are returned. */ if (! new_frame) rc = raspitex_draw(state, NULL); return rc; }
static int preview_process_returned_bufs(RASPITEX_STATE* state) { MMAL_BUFFER_HEADER_T *buf; int rc = 0; while ((buf = mmal_queue_get(state->preview_queue)) != NULL) { if (state->preview_stop == 0) { if (state->m_nGetData) { rc = raspitex_draw(state, buf); // block complete chain!!! if (rc != 0) { vcos_log_error("%s: Error drawing frame. Stopping.", VCOS_FUNCTION); state->preview_stop = 1; return rc; } } else { //Now return the PREVIOUS MMAL buffer header back to the camera preview. if (state->preview_buf) mmal_buffer_header_release(state->preview_buf); state->preview_buf = buf; } } } /* If there were no new frames then redraw the scene again with the previous * texture. Otherwise, go round the loop again to see if any new buffers * are returned. */ /*if (! new_frame) { //vcos_log_info("%s: no new frame - redraw previous.", VCOS_FUNCTION); rc = raspitex_draw(state, NULL); }*/ return rc; }
/** Preview worker thread. * Ensures camera preview is supplied with buffers and sends preview frames to GL. * @param arg Pointer to state. * @return NULL always. */ static void *preview_worker(void *arg) { RASPITEX_STATE* state = arg; MMAL_PORT_T *preview_port = state->preview_port; MMAL_BUFFER_HEADER_T *buf; MMAL_STATUS_T st; int rc; vcos_log_trace("%s: port %p", VCOS_FUNCTION, preview_port); rc = state->ops.create_native_window(state); if (rc != 0) goto end; else vcos_log_info("%s: create_native_window=%d", VCOS_FUNCTION, rc); rc = state->ops.gl_init(state); if (rc != 0) goto end; else vcos_log_info("%s: gl_init=%d", VCOS_FUNCTION, rc); // ------------------------------------------------------------------------------------- /* Send empty buffers to camera preview port */ while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL) { st = mmal_port_send_buffer(preview_port, buf); if (st != MMAL_SUCCESS) { vcos_log_error("Failed to send buffer to %s", preview_port->name); } } // ------------------------------------------------------------------------------------- //S_COPY_FRAME_DATA rec_frame_data; while (state->preview_stop == 0) { /* Send empty buffers to camera preview port */ /*while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL) { st = mmal_port_send_buffer(preview_port, buf); if (st != MMAL_SUCCESS) { vcos_log_info("Failed to send buffer to %s", preview_port->name); } }*/ //int nLen = mmal_queue_length( state->preview_queue ); //vcos_log_info("SHIT!!! - LEN=%d", nLen ); //while ((buf = mmal_queue_get(state->preview_pool->queue)) != NULL) //if (buf) int nExistBufferInQueue = 0; while ((buf = mmal_queue_get(state->preview_queue)) != NULL) { nExistBufferInQueue = 1; //vcos_log_info("DATA READ!!!" ); rc = raspitex_draw(state, buf); // block complete chain!!! if (rc != 0) { vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION); state->preview_stop = 1; } st = mmal_port_send_buffer(preview_port, buf); if (st != MMAL_SUCCESS) { vcos_log_info("Failed to send buffer to %s", preview_port->name); } // ------------------------------------------------------------------------------------- //vcos_sleep( 100 ); // now is main chain already free - now can block this thread // rc = state->ops.safe_redraw(state); if (rc != 0) { vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION); state->preview_stop = 1; } else { update_fps( ); } // ------------------------------------------------------------------------------------- break; } if (!nExistBufferInQueue) // slow down while cycle otherwise 100% CPU { vcos_sleep( 10 ); } /*if (preview_process_returned_bufs(state) != 0) { vcos_log_info("SHIT!!!" ); } else { vcos_log_info("DATA READ!!!" ); }*/ /*if (begin_read_frame( state->preview_pool->queue, &rec_frame_data )) { vcos_log_info("DATA READ!!!" ); //if (state->m_nGetData) { rc = raspitex_draw(state, buf); // block complete chain!!! if (rc != 0) { vcos_log_info("%s: Error drawing frame. Stopping.", VCOS_FUNCTION); state->preview_stop = 1; } } end_read_frame( preview_port, state->preview_pool, &rec_frame_data ); } else { vcos_log_info("SHIT!!!" ); }*/ //vcos_sleep( 500 ); /* Process returned buffers */ /*if (preview_process_returned_bufs(state) != 0) { vcos_log_error("Preview error. Exiting."); state->preview_stop = 1; } else { }*/ } // ------------------------------------------------------------------------------------- end: /* Make sure all buffers are returned on exit */ while ((buf = mmal_queue_get(state->preview_queue)) != NULL) mmal_buffer_header_release(buf); /* Tear down GL */ state->ops.gl_term(state); vcos_log_trace("Exiting preview worker"); return NULL; }