📄 watermark.c
字号:
dmabuffer_index ++; if (dmabuffer_index + context.play_opt->disk_ctrl_low_level >= context.play_opt->dmapool_count) { if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_RUN) == RM_OK) context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_RUNNING; } goto get_buffer; } fill_buffer: if ((!trickSizeToSend) && (dcc_info.seek_supported)) { trickSizeToSend = (RMuint32) (context.fileSize / (context.play_opt->duration / 500)); //there are roughly 2 iframes per second trickBuffersToSend = trickSizeToSend >> context.play_opt->dmapool_log2size; RMDBGLOG((ENABLE, "size %llu, duration %lu s, iframeSize %lu, buffers %lu (of %lu bytes)\n", context.fileSize, (RMuint32)(context.play_opt->duration / 1000), trickSizeToSend, trickBuffersToSend, (1 << context.play_opt->dmapool_log2size))); } #if STORE_SEQ_HEADER_LOCALLY /* if we have to resend the sequence header, we copy it into the buffer before sending it to the video decoder and then read from the file till filling the buffer, otherwise, we just read the file into the buffer. */ if (resendheader == TRUE && headerread == TRUE) { RMint32 i; for (i = 0; i < HeaderSize ; i++) { *(buf+i) = header[i]; } status = RMReadFile(file, buf+HeaderSize, (1 << context.play_opt->dmapool_log2size)-(HeaderSize), &count); resendheader = FALSE; } else {#endif //STORE_SEQ_HEADER_LOCALLY if (context.highSpeedIFrameMode) { RMint64 position; RMuint64 seekto; if (trickBuffersSent >= trickBuffersToSend) trickBuffersSent = 0; if (trickBuffersSent == 0) { RMGetCurrentPositionOfFile(file, &position); seekto = position + (RMuint64) context.highSpeedIFrameSpeed * trickBuffersToSend * (1<<(context.play_opt->dmapool_log2size)); RMDBGLOG((DISABLE, "pos %llu, seekto %llu\n", position, seekto)); status = RMSeekFile(file, seekto, RM_FILE_SEEK_START); if (status != RM_OK) { perror("error seeking in fwd trickmode, assume EOS\n"); if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } break; } } status = RMReadFile(file, buf, (1 << context.play_opt->dmapool_log2size), &count); trickBuffersSent++; RMDBGLOG((ENABLE, "sent buffer %lu, speed %lux\n", trickBuffersSent, context.highSpeedIFrameSpeed)); } else { if (context.video_opt->MSflag) { RMint64 position; RMuint64 dummy; RMuint8 *buffer = (RMuint8*)&dummy; RMGetCurrentPositionOfFile (file, &position); status = RMReadFile(file, buffer, sizeof(RMuint64), &count); if (status == RM_ERRORENDOFFILE) { if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } break; } else if ((status != RM_OK) || (count != sizeof(RMuint64))) { fprintf(stderr, "read error while reading pts!\n"); if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } goto cleanup; } MSPts = RMleBufToUint64(buffer); status = RMReadFile(file, buffer, sizeof(RMuint32), &count); if (status == RM_ERRORENDOFFILE) { if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } break; } else if ((status != RM_OK) || (count != sizeof(RMuint32))) { fprintf(stderr, "read error while reading frame length!\n"); if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } goto cleanup; } MSLength = RMleBufToUint32(buffer); RMDBGLOG((DISABLE, "pos %llu (%llx); MSLength= %ld ; MSPts = %lld (bufferSize %ld) \n", position, position, MSLength, MSPts, (RMuint32)(1 << context.play_opt->dmapool_log2size) )); //MSPts *= 90000; //MSPts /= 1000; if (MSLength > (RMuint32)(1 << context.play_opt->dmapool_log2size)) { RMDBGLOG((ENABLE, "Buffer overflow!\n")); if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } goto cleanup; } status = RMReadFile(file, buf, MSLength, &count); } else { status = RMReadFile(file, buf, (1 << context.play_opt->dmapool_log2size), &count); } }#if STORE_SEQ_HEADER_LOCALLY }#endif //STORE_SEQ_HEADER_LOCALLY if (status == RM_ERRORREADFILE) { RMDBGLOG((ENABLE, "reading file")); if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } goto cleanup; } if (status == RM_ERRORENDOFFILE) { if (buf != NULL) { RUAReleaseBuffer(pDMA, buf); buf = NULL; } break; } #if STORE_SEQ_HEADER_LOCALLY /* parse the buffer and store the header */ if (headerread == FALSE) { headerread = StoreHeader(&context, buf, header, &HeaderSize, (1 << context.play_opt->dmapool_log2size)); if (headerread) RMDBGLOG((ENABLE, "stored SeqHeader, %lu bytes\n", HeaderSize)); }#endif //STORE_SEQ_HEADER_LOCALLY /* fast forward may have been too fast for the decoder. Must set the STC to the current picture in display to avoid skipping frames to catch STC */ if (context.byte_counter == 0) { /* set the VopInfo property */ if (context.video_opt->MSflag == TRUE) { RMuint32 timeScale; DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale); DCCSTCSetTime(dcc_info.pStcSource, context.play_opt->send_video_pts ? MSPts : 0, timeScale); } else { DCCSTCSetTime(dcc_info.pStcSource, context.play_opt->STC_initial_value, 90000); Info.ValidFields = 0; /* Info.TimeStamp = 0; */ /* one shouldn't admit that first decoded picture has a PTS equal to 0 */ /* for instance, closed gops starting with IB...BP (B frames only have backward references) */ /* give decoding order B....B I P */ /* where I is the first decoded picture AND however doesn't have PTS = 0 */ } } else if ((context.ResyncTimer) && (!context.FirstPTS)) { RMuint64 stc; RMuint32 timeScale; RMuint64 currentSTC; err = RUAGetProperty(dcc_info.pRUA, dcc_info.SurfaceID, RMGenericPropertyID_CurrentDisplayPTS, &stc, sizeof(stc)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot get video PTS\n")); } DCCSTCGetTimeResolution(dcc_info.pStcSource, DCC_Video, &timeScale); if (timeScale == 90000) stc *= 2; DCCSTCGetTime(dcc_info.pStcSource, ¤tSTC, timeScale); RMDBGLOG((ENABLE, "resync STC(%llu) to %llu, timeScale %lu\n", currentSTC, stc, timeScale)); DCCSTCSetTime(dcc_info.pStcSource, stc, timeScale); context.ResyncTimer = FALSE; } else if (context.FirstPTS) { //after a seek RMDBGLOG((ENABLE, "first pts %lu\n", context.FirstPTS)); DCCSTCSetTime(dcc_info.pStcSource, context.FirstPTS, 90000); Info.ValidFields = TIME_STAMP_INFO; Info.TimeStamp = context.FirstPTS; context.FirstPTS = 0; context.FirstSystemTimeStamp = FALSE; } else { Info.ValidFields = 0; Info.TimeStamp = 0; } if (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Prebuffering) { RMDBGPRINT((ENABLE, ".")); } if (context.video_opt->MSflag == TRUE) { if ((RMint64) MSPts != -1) { Info.ValidFields = context.play_opt->send_video_pts ? TIME_STAMP_INFO:0; Info.TimeStamp = MSPts; } else Info.ValidFields = 0; RMDBGLOG((DISABLE, "MSPts = %lld (0x%llx) pts= %lld (0x%llx) (valid %lu) byte_counter=0x%lx\n", MSPts, MSPts, Info.TimeStamp, Info.TimeStamp, Info.ValidFields, context.byte_counter)); } RMDBGLOG((SENDDBG, "sending %lu bytes, pts %llu, valid %lu\n", count, Info.TimeStamp, (RMuint32)Info.ValidFields)); if (Info.ValidFields) context.last_video_pts = Info.TimeStamp; while (RUASendData(dcc_info.pRUA, dcc_info.video_decoder, pDMA, buf, count, &Info, sizeof(Info)) != RM_OK) { struct RUAEvent e; /* see previous comment on RUAGetBuffer */ check_prebuf_state(&context, 0); PROCESS_KEY(TRUE, TRUE); e.ModuleID = dcc_info.video_decoder; e.Mask = RUAEVENT_XFER_FIFO_READY; RUAWaitForMultipleEvents(dcc_info.pRUA, &e, 1, COMMON_TIMEOUT_US, NULL); } context.bitrate += count * 8; context.byte_counter += count; /* sendind data may fill-up the xfer fifo, so we reset the event */ { struct RUAEvent e; e.ModuleID = dcc_info.video_decoder; e.Mask = RUAEVENT_XFER_FIFO_READY; RUAResetEvent(dcc_info.pRUA, &e); } RUAReleaseBuffer(pDMA, buf); buf = NULL; } //while(1) check_prebuf_state(&context, 0); switch (context.play_opt->disk_ctrl_state) { case DISK_CONTROL_STATE_DISABLE: case DISK_CONTROL_STATE_SLEEPING: break; case DISK_CONTROL_STATE_RUNNING: if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_SLEEP) == RM_OK) context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_SLEEPING; break; } if(0){ /* don't wait for eos, won't work well with ppf yet */ err = WaitForEOS(&context, &actions); { RMuint64 stc; DCCSTCGetTime(dcc_info.pStcSource, &stc, 90000); RMDBGLOG((ENABLE, "Timer duration %llu s\n", stc/90000)); } if (err == RM_KEY_WHILE_WAITING_EOS) { RMDBGLOG((ENABLE, "command while waiting for EOS\n")); err = RM_OK; PROCESS_KEY(FALSE, FALSE); } else {#ifdef WITH_MONO /* callback to signal EOS to curacao/mono */ RMEOSCallback(); break;#else break; // EOS#endif } } else break; } // additional while if (context.play_opt->loop_count > 0) context.play_opt->loop_count --; /* if there is another loop, stop devices */ if ((context.play_opt->loop_count > 0) || (context.play_opt->waitexit != TRUE) || (context.play_opt->infinite_loop)) Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC); } while ((context.play_opt->loop_count > 0) || (context.play_opt->infinite_loop)); cleanup: if (file) RMCloseFile(file); if( context.play_opt->waitexit ) { RMascii key; Stop(&context, RM_DEVICES_STC); fprintf(stderr, "press q key again if you really want to stop & quit\n"); while ( !(RMGetKeyNoWait(&key) && ((key == 'q') || (key =='Q'))) ); Stop(&context, RM_DEVICES_VIDEO | RM_DEVICES_STC); }#ifndef WITH_MONO RMTermExit();#endif if (dmabuffer_index) { RMuint32 i; for (i = 0; i < dmabuffer_index; i++) { RUAReleaseBuffer(pDMA, dmabuffer_array[i]); RMDBGLOG((ENABLE, "released buffer[%lu] @ 0x%08lx\n", i, dmabuffer_array[i])); } RMFree(dmabuffer_array); } if (dcc_info.pStcSource) { Stop(&context, RM_DEVICES_STC); RMDBGLOG((DEBUG, "Closing STC...\n")); err = DCCSTCClose(dcc_info.pStcSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error cannot close STC %d\n", err)); } RMDBGLOG((DEBUG, "Done closing STC.\n")); } if (pVideoSource) { RMDBGLOG((DEBUG, "Stopping video source...\n")); err = DCCStopVideoSource(pVideoSource, DCCStopMode_LastFrame); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot stop video decoder %d\n", err)); } RMDBGLOG((DEBUG, "Done stopping video source.\n")); RMDBGLOG((DEBUG, "Closing video source...\n")); err = DCCCloseVideoSource(pVideoSource); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error cannot close video decoder %d\n", err)); } RMDBGLOG((DEBUG, "Done closing video source.\n"));#ifndef WITH_MONO clear_display_options(&dcc_info, context.disp_opt);#endif /*WITH_MONO*/ } clear_video_options(&dcc_info, context.video_opt); if (pDMA) { RMDBGLOG((DEBUG, "Closing RUA DMA pool...\n")); err = RUAClosePool(pDMA); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error cannot close dmapool %d\n", err)); } RMDBGLOG((DEBUG, "Done closing RUA DMA pool.\n")); }#ifndef WITH_MONO err = DCCClose(dcc_info.pDCC); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot close DCC %d\n", err)); } err = RUADestroyInstance(dcc_info.pRUA); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Cannot destroy RUA instance %d\n", err)); return -1; }#endif /*WITH_MONO*/ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -