int eDVBRecordFileThread::asyncWrite(int len) { #ifdef SHOW_WRITE_TIME struct timeval starttime; struct timeval now; suseconds_t diff; gettimeofday(&starttime, NULL); #endif m_ts_parser.parseData(m_current_offset, m_buffer, len); #ifdef SHOW_WRITE_TIME gettimeofday(&now, NULL); diff = (1000000 * (now.tv_sec - starttime.tv_sec)) + now.tv_usec - starttime.tv_usec; eDebug("[eFilePushThreadRecorder] m_ts_parser.parseData: %9u us", (unsigned int)diff); gettimeofday(&starttime, NULL); #endif int r = m_current_buffer->start(m_fd_dest, m_current_offset, len, m_buffer); if (r < 0) { eDebug("[eDVBRecordFileThread] aio_write failed: %m"); return r; } m_current_offset += len; #ifdef SHOW_WRITE_TIME gettimeofday(&now, NULL); diff = (1000000 * (now.tv_sec - starttime.tv_sec)) + now.tv_usec - starttime.tv_usec; eDebug("[eFilePushThreadRecorder] aio_write: %9u us", (unsigned int)diff); #endif // Count how many buffers are still "busy". Move backwards from current, // because they can reasonably be expected to finish in that order. AsyncIOvector::iterator i = m_current_buffer; r = i->poll(); int busy_count = 0; while (r > 0) { ++busy_count; if (i == m_aio.begin()) i = m_aio.end(); --i; if (i == m_current_buffer) { eDebug("[eFilePushThreadRecorder] Warning: All write buffers busy"); break; } r = i->poll(); if (r < 0) return r; } ++m_buffer_use_histogram[busy_count]; ++m_current_buffer; if (m_current_buffer == m_aio.end()) m_current_buffer = m_aio.begin(); m_buffer = m_current_buffer->buffer; return len; }
int eDVBRecordFileThread::filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining) { m_ts_parser.parseData(m_current_offset, data, len); m_current_offset += len; return len; }
int eDVBRecordFileThread::writeData(int len) { #ifdef SHOW_WRITE_TIME struct timeval starttime; struct timeval now; suseconds_t diff; gettimeofday(&starttime, NULL); #endif const unsigned char* data = m_buffer; m_ts_parser.parseData(m_current_offset, data, len); #ifdef SHOW_WRITE_TIME gettimeofday(&now, NULL); diff = (1000000 * (now.tv_sec - starttime.tv_sec)) + now.tv_usec - starttime.tv_usec; eDebug("[eFilePushThreadRecorder] m_ts_parser.parseData: %9u us", (unsigned int)diff); gettimeofday(&starttime, NULL); #endif int r = m_aio[m_current_buffer].start(m_fd_dest, m_current_offset, len, m_buffer); if (r < 0) { eDebug("[eDVBRecordFileThread] aio_write failed: %m"); return r; } m_current_offset += len; #ifdef SHOW_WRITE_TIME gettimeofday(&now, NULL); diff = (1000000 * (now.tv_sec - starttime.tv_sec)) + now.tv_usec - starttime.tv_usec; eDebug("[eFilePushThreadRecorder] aio_write: %9u us", (unsigned int)diff); #endif // do the flush thing if the user wanted it if (flushSize != 0) { written_since_last_sync += len; if (written_since_last_sync > flushSize) { int pr; pr = syscall(SYS_fadvise64, m_fd_dest, offset_last_sync, 0, 0, 0, POSIX_FADV_DONTNEED); if (pr != 0) { eDebug("[eDVBRecordFileThread] POSIX_FADV_DONTNEED returned %d", pr); } offset_last_sync += written_since_last_sync; written_since_last_sync = 0; } } // Count how many buffers are still "busy". Move backwards from current, // because they can reasonably be expected to finish in that order. int i = m_current_buffer; r = m_aio[i].poll(); int busy_count = 0; while (r > 0) { ++busy_count; if (i == 0) i = recordingBufferCount - 1; else --i; if (i == m_current_buffer) { eDebug("[eFilePushThreadRecorder] Warning: All write buffers busy"); break; } r = m_aio[i].poll(); if (r < 0) return r; } ++m_buffer_use_histogram[busy_count]; #ifdef SHOW_WRITE_TIME gettimeofday(&starttime, NULL); #endif m_current_buffer = (m_current_buffer + 1) % recordingBufferCount; m_buffer = m_allocated_buffer + (m_current_buffer * m_buffersize); // Wait for previous aio to complete on this buffer before returning r = m_aio[m_current_buffer].wait(); if (r < 0) return -1; #ifdef SHOW_WRITE_TIME gettimeofday(&now, NULL); diff = (1000000 * (now.tv_sec - starttime.tv_sec)) + now.tv_usec - starttime.tv_usec; eDebug("[eFilePushThreadRecorder] wait_for_aio: %9u us", (unsigned int)diff); #endif return len; }