static int ddc_receive_frame(void* data, int streamId, unsigned char* buffer, unsigned int bufferSize) { DVDecodeStreamConnect* connect = (DVDecodeStreamConnect*)data; int status; int result = 1; if (connect->sourceStreamId != streamId) { ml_log_error("Received frame for unknown source stream %d in copy connect\n", streamId); return 0; } /* signal to ddc_sync at later time that we have received a frame to decode and send */ connect->frameWasReceived = 1; if (!connect->useWorkerThread) { result = decode_and_send(connect); } else { /* check that the worker isn't busy */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); if (connect->workerIsBusy) { ml_log_error("DV connect worker thread is still busy, and therefore cannot receive a new frame\n"); result = 0; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); if (result != 1) { return result; } /* signal worker that a new frame is ready */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); connect->frameIsReady = 1; status = pthread_cond_signal(&connect->frameIsReadyCond); if (status != 0) { ml_log_error("DV connect worker thread failed to send frame is ready condition signal\n"); result = 0; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); } return result; }
/************************************************* * Convert some data from hex format * *************************************************/ void Hex_Decoder::write(const byte input[], u32bit length) { for(u32bit j = 0; j != length; ++j) { if(is_valid(input[j])) in[position++] = input[j]; else handle_bad_char(input[j]); if(position == in.size()) { decode_and_send(in, in.size()); position = 0; } } }
static void* worker_thread(void* arg) { DVDecodeStreamConnect* connect = (DVDecodeStreamConnect*)arg; int status; int workerResult; int doneWaiting; while (!connect->stopped) { /* wait until a frame is ready */ doneWaiting = 0; while (!doneWaiting && !connect->stopped) { /* wait for a frame */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); if (!connect->frameIsReady) { status = pthread_cond_wait(&connect->frameIsReadyCond, &connect->workerMutex); if (status != 0) { ml_log_error("DV connect worker thread failed to wait for condition\n"); /* TODO: don't try again? */ } } /* done waiting if there is a frame ready for processing */ if (connect->frameIsReady) { /* worker will now be busy */ connect->workerIsBusy = 1; connect->workerResult = 0; connect->frameIsReady = 0; doneWaiting = 1; } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); } /* no more work */ if (connect->stopped) { break; } /* decode and send frame to sink */ workerResult = decode_and_send(connect); /* signal that we are done with the frame */ PTHREAD_MUTEX_LOCK(&connect->workerMutex); connect->workerResult = workerResult; connect->workerIsBusy = 0; status = pthread_cond_signal(&connect->workerIsBusyCond); if (status != 0) { ml_log_error("DV connect worker thread failed to send worker busy condition signal\n"); } PTHREAD_MUTEX_UNLOCK(&connect->workerMutex); } pthread_exit((void*) 0); }
/************************************************* * Flush buffers * *************************************************/ void Hex_Decoder::end_msg() { decode_and_send(in, position); position = 0; }