This is MPEGThread.m in view mode; [Download] [Up]
// MPEGThread.m #import <mach/mach.h> // post_allocate() #import <mach/mach_error.h> #import <dpsclient/dpsNeXT.h> // DPSAddPort() #import <objc/NXBundle.h> #import <appkit/Application.h> #import <appkit/Panel.h> // local objects #import "MPEGView.h" #import "MPEGThread.h" #define SEND_FCODE(x) \ pkt.fcode = x; \ mr = msg_send((msg_header_t *)&pkt, MSG_OPTION_NONE, 0); \ if (SEND_SUCCESS != mr) \ fprintf(stderr, "msg_send() failed with error %d\n", mr); @implementation MPEGThread /*** Initialization methods ***/ - initSize:(int)size forView:anObject { kern_return_t kr; if (![super init]) return nil; frameSize = size; view = anObject; controller = [NXApp delegate]; if (KERN_SUCCESS != (kr = port_allocate(task_self(), &mpegPort))) { mach_error("port_allocate() failed in -initSize:forView:", kr); return [self free]; } DPSAddPort(mpegPort, (DPSPortProc)receive_fcode, sizeof(mpegPacket), (void *)self, NX_MODALRESPTHRESHOLD + 1); return self; } - free { kern_return_t kr; [self abortDecode]; DPSRemovePort(mpegPort); if (KERN_SUCCESS != (kr = port_deallocate(task_self(), mpegPort))) mach_error("port_deallocate() failed in -free", kr); return [super free]; } /*** Instance methods and Standard C wrapper functions ***/ void receive_fcode(mpegPacket *pkt, id self) { [self receiveFcode:pkt]; } - receiveFcode:(mpegPacket *)pkt { switch (pkt->fcode) { case FCODE_ABORT: [self abortDecode]; break; case FCODE_END: [view setAddress:(char *)address len:(int)len maxlen:(int)maxlen]; [view runAgain]; [self endDecode]; break; default: if ([controller respondsTo:@selector(setFrameNumber:)]) [controller setFrameNumber:pkt->fcode]; break; } return self; } - decodeFile:(const char *)mpegFile { char *pchAlertTitle = "Error in MPEGThread method -decodeFile:"; char command[256]; // check for NULL pointer or empty string if (!mpegFile || !*mpegFile) { NXRunAlertPanel(pchAlertTitle, "No filename was specified.", gpchOK, NULL, NULL); return nil; } sprintf(command, "exec %s/mpegDecode %s", [[NXBundle mainBundle] directory], mpegFile); if (NULL == (ifp = popen(command, "r"))) { NXRunAlertPanel(pchAlertTitle, "Could not create MPEG Decode process. Command:%s", gpchOK, NULL, NULL, command); return nil; } if (NULL == (buffer = malloc(frameSize))) { NXRunAlertPanel(pchAlertTitle, "Could not allocate memory.", gpchOK, NULL, NULL); pclose(ifp); return nil; } // REVIEW: check the following for errors returned? pStream = NXOpenFile(fileno(ifp), O_RDONLY); mStream = NXOpenMemory(NULL, 0, NX_WRITEONLY); [controller setFrameNumber:0]; cthreadMain = cthread_fork(mpeg_thread, self); cthread_detach(cthreadMain); return self; } any_t mpeg_thread(any_t self) { [(MPEGThread *)self mpegThread]; return self; } - mpegThread { mpegPacket pkt; int frameNumber; msg_return_t mr; pkt.h.msg_remote_port = mpegPort; pkt.h.msg_simple = TRUE; pkt.h.msg_size = sizeof(mpegPacket); pkt.h.msg_local_port = PORT_NULL; pkt.h.msg_type = MSG_TYPE_NORMAL; pkt.t.msg_type_name = MSG_TYPE_INTEGER_32; pkt.t.msg_type_size = 32; pkt.t.msg_type_number = FP_NUM_INT_DATA; pkt.t.msg_type_inline = TRUE; pkt.t.msg_type_longform = FALSE; pkt.t.msg_type_deallocate = FALSE; for (frameNumber = 1; 1; frameNumber++) { int bytes = frameSize; if (!(bytes = NXRead(pStream, buffer, bytes))) break; if (NXWrite(mStream, buffer, bytes) != bytes) { SEND_FCODE(FCODE_ABORT); fprintf(stderr, "NXWrite() failed in -mpegThread\n"); return nil; } SEND_FCODE(frameNumber); } NXFlush(mStream); NXGetMemoryBuffer(mStream, &address, &len, &maxlen); NXCloseMemory(mStream, NX_SAVEBUFFER); mStream = NULL; SEND_FCODE(FCODE_END); return self; } - endDecode { kern_return_t kr; id result = self; if (cthreadMain) { if (KERN_SUCCESS != (kr = thread_suspend(cthread_thread(cthreadMain)))) { result = nil; // error suspending thread mach_error("thread_suspend() failed in -endDecode", kr); } if (KERN_SUCCESS != (kr = cthread_abort(cthreadMain))) { result = nil; // error aborting thread mach_error("cthread_abort() failed in -endDecode", kr); } else cthreadMain = 0; } if (buffer) free(buffer); buffer = NULL; if (pStream) NXClose(pStream); pStream = NULL; if (ifp) pclose(ifp); ifp = NULL; return result; } - abortDecode { [self endDecode]; if (mStream) NXCloseMemory(mStream, NX_FREEBUFFER); address = NULL, len = maxlen = 0; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.