/*static*/ int StreamBase::_Read(void* cookie, uint8* buffer, int bufferSize) { StreamBase* stream = reinterpret_cast<StreamBase*>(cookie); BAutolock _(stream->fSourceLock); TRACE_IO("StreamBase::_Read(%p, %p, %d) position: %lld/%lld\n", cookie, buffer, bufferSize, stream->fPosition, stream->fSource->Position()); if (stream->fPosition != stream->fSource->Position()) { off_t position = stream->fSource->Seek(stream->fPosition, SEEK_SET); if (position != stream->fPosition) return -1; } ssize_t read = stream->fSource->Read(buffer, bufferSize); if (read > 0) stream->fPosition += read; TRACE_IO(" read: %ld\n", read); return (int)read; }
/*static*/ off_t AVFormatWriter::_Seek(void* cookie, off_t offset, int whence) { TRACE_IO("AVFormatWriter::_Seek(%p, %lld, %d)\n", cookie, offset, whence); AVFormatWriter* writer = reinterpret_cast<AVFormatWriter*>(cookie); BPositionIO* positionIO = dynamic_cast<BPositionIO*>(writer->fTarget); if (positionIO == NULL) return -1; // Support for special file size retrieval API without seeking anywhere: if (whence == AVSEEK_SIZE) { off_t size; if (positionIO->GetSize(&size) == B_OK) return size; return -1; } off_t position = positionIO->Seek(offset, whence); TRACE_IO(" position: %lld\n", position); if (position < 0) return -1; return position; }
/*----< ncmpio_close_files() >-----------------------------------------------*/ int ncmpio_close_files(NC *ncp, int doUnlink) { int mpireturn; assert(ncp != NULL); /* this should never occur */ if (ncp->independent_fh != MPI_FILE_NULL) { TRACE_IO(MPI_File_close)(&ncp->independent_fh); if (mpireturn != MPI_SUCCESS) return ncmpii_error_mpi2nc(mpireturn, "MPI_File_close"); } if (ncp->collective_fh != MPI_FILE_NULL) { TRACE_IO(MPI_File_close)(&ncp->collective_fh); if (mpireturn != MPI_SUCCESS) return ncmpii_error_mpi2nc(mpireturn, "MPI_File_close"); } if (doUnlink) { /* called from ncmpi_abort, if the file is being created and is still * in define mode, the file is deleted */ TRACE_IO(MPI_File_delete)((char *)ncp->path, ncp->mpiinfo); if (mpireturn != MPI_SUCCESS) return ncmpii_error_mpi2nc(mpireturn, "MPI_File_delete"); } return NC_NOERR; }
/*static*/ int AVFormatWriter::_Write(void* cookie, uint8* buffer, int bufferSize) { TRACE_IO("AVFormatWriter::_Write(%p, %p, %d)\n", cookie, buffer, bufferSize); AVFormatWriter* writer = reinterpret_cast<AVFormatWriter*>(cookie); ssize_t written = writer->fTarget->Write(buffer, bufferSize); TRACE_IO(" written: %ld\n", written); return (int)written; }
/*static*/ off_t StreamBase::_Seek(void* cookie, off_t offset, int whence) { TRACE_IO("StreamBase::_Seek(%p, %lld, %d)\n", cookie, offset, whence); StreamBase* stream = reinterpret_cast<StreamBase*>(cookie); BAutolock _(stream->fSourceLock); // Support for special file size retrieval API without seeking // anywhere: if (whence == AVSEEK_SIZE) { off_t size; if (stream->fSource->GetSize(&size) == B_OK) return size; return -1; } // If not requested to seek to an absolute position, we need to // confirm that the stream is currently at the position that we // think it is. if (whence != SEEK_SET && stream->fPosition != stream->fSource->Position()) { off_t position = stream->fSource->Seek(stream->fPosition, SEEK_SET); if (position != stream->fPosition) return -1; } off_t position = stream->fSource->Seek(offset, whence); TRACE_IO(" position: %lld\n", position); if (position < 0) return -1; stream->fPosition = position; return position; }
status_t AVCodecEncoder::_EncodeVideo(const void* buffer, int64 frameCount, media_encode_info* info) { TRACE_IO("AVCodecEncoder::_EncodeVideo(%p, %lld, %p)\n", buffer, frameCount, info); if (fChunkBuffer == NULL) return B_NO_MEMORY; status_t ret = B_OK; while (frameCount > 0) { size_t bpr = fInputFormat.u.raw_video.display.bytes_per_row; size_t bufferSize = fInputFormat.u.raw_video.display.line_count * bpr; // We should always get chunky bitmaps, so this code should be safe. fSrcFrame.data[0] = (uint8_t*)buffer; fSrcFrame.linesize[0] = bpr; // Run the pixel format conversion sws_scale(fSwsContext, fSrcFrame.data, fSrcFrame.linesize, 0, fInputFormat.u.raw_video.display.line_count, fDstFrame.data, fDstFrame.linesize); // Encode one video chunk/frame. int usedBytes = avcodec_encode_video(fContext, fChunkBuffer, kDefaultChunkBufferSize, fFrame); // avcodec.h says we need to set it. fFrame->pts++; if (usedBytes < 0) { TRACE(" avcodec_encode_video() failed: %d\n", usedBytes); return B_ERROR; } // Maybe we need to use this PTS to calculate start_time: if (fContext->coded_frame->pts != kNoPTSValue) { TRACE(" codec frame PTS: %lld (codec time_base: %d/%d)\n", fContext->coded_frame->pts, fContext->time_base.num, fContext->time_base.den); } else { TRACE(" codec frame PTS: N/A (codec time_base: %d/%d)\n", fContext->time_base.num, fContext->time_base.den); } // Setup media_encode_info, most important is the time stamp. info->start_time = (bigtime_t)(fFramesWritten * 1000000LL / fInputFormat.u.raw_video.field_rate); info->flags = 0; if (fContext->coded_frame->key_frame) info->flags |= B_MEDIA_KEY_FRAME; // Write the chunk ret = WriteChunk(fChunkBuffer, usedBytes, info); if (ret != B_OK) { TRACE(" error writing chunk: %s\n", strerror(ret)); break; } // Skip to the next frame (but usually, there is only one to encode // for video). frameCount--; fFramesWritten++; buffer = (const void*)((const uint8*)buffer + bufferSize); } return ret; }