📄 play_asf.c
字号:
err = apply_audio_decoder_options_onthefly(pProcessContext->dcc_info, &(pProcessContext->audio_opt[i])); if (RMFAILED(err)) { fprintf(stderr, "Error applying audio decoder options on the fly %d\n", err); } } pProcessContext->actions.cmdProcessed = TRUE; } if (incallback) { if ((dataType == RM_STREAM_AUDIO) && (PlaybackStatus != RM_PSM_Playing) && (PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Prebuffering) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "trickmode during audio callback\n")); if (!pProcessContext->sendAudioTrickmode) { RMDBGLOG((ENABLE, "ignoring audio payload\n")); pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_nojump_but_exit; } RMDBGLOG((ENABLE, "sending audio while in trickmodes\n")); } if (((PlaybackStatus == RM_PSM_IForward) || (PlaybackStatus == RM_PSM_IRewind)) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "iframe trick during callback\n")); pProcessContext->ignoreCallback = TRUE; return RMProcess_key_goto_nojump_but_exit; } if (((PlaybackStatus == RM_PSM_Slow) || (PlaybackStatus == RM_PSM_Fast)) && (pProcessContext->actions.cmdProcessed)) { RMDBGLOG((ENABLE, "trickmodes during callback\n")); pProcessContext->isTrickMode = TRUE; pProcessContext->ignoreCallback = FALSE; SyncTimerWithDecoderPTS(pProcessContext); } } pProcessContext->ignoreCallback = FALSE; if (pProcessContext->monitorFIFOs) monitorFIFO(pProcessContext, FALSE); // No goto request if (got_key) return RMProcess_key_goto_got_key_but_noaction; else return 0; }#define PROCESS_KEY(release, getkey)\do {\ enum RMProcess_key_goto exit_goto;\ RMuint8 from_callback;\ if (SendContext.gotoRequest > RMProcess_key_goto_nojump_but_exit)\ {\ RMDBGLOG((ENABLE, "pProcessContext->gotoRequest not null, asking for jump\n"));\ from_callback=TRUE;\ exit_goto = SendContext.gotoRequest;\ }\ else\ {\ from_callback=FALSE;\ exit_goto = process_key_sub(&SendContext,release, getkey,FALSE,0);\ }\ SendContext.gotoRequest = RMProcess_key_goto_none;\ switch (exit_goto)\ {\ case RMProcess_key_goto_none:\ case RMProcess_key_goto_got_key_but_noaction:\ case RMProcess_key_goto_nojump_but_exit:\ break;\ case RMProcess_key_goto_cleanup:\ RMDBGLOG((ENABLE, "Executing goto cleanup requested from %s process\n",from_callback?"callback":"main")); \ goto cleanup;\ case RMProcess_key_goto_mainloop_seek:\ RMDBGLOG((ENABLE, "Executing goto mainloop_seek requested from %s process\n",from_callback?"callback":"main")); \ goto mainloop_seek;\ case RMProcess_key_goto_wmapro_decoder_delete:\ RMDBGLOG((ENABLE, "Executing goto wmapro_decoder_delete requested from %s process\n",from_callback?"callback":"main")); \ goto wmapro_decoder_delete;\ }\} while (0)#define PROCESS_KEY_INCALLBACK(getkey,return_if_any_key)\do {\ if (pSendContext->gotoRequest <= RMProcess_key_goto_got_key_but_noaction)\ pSendContext->gotoRequest = process_key_sub(pSendContext,FALSE, getkey,TRUE,dataType);\ else\ RMDBGLOG((ENABLE, "GotoRequest already on the way (%d)\n",pSendContext->gotoRequest));\ if ( ((return_if_any_key)&&(pSendContext->gotoRequest > RMProcess_key_goto_none))\ ||((!return_if_any_key)&&(pSendContext->gotoRequest > RMProcess_key_goto_got_key_but_noaction))\ )\ {\ RMDBGLOG((ENABLE, "GotoRequest %d from callback process\n",pSendContext->gotoRequest));\ goto return_from_callback;\ }\} while (0)/* function implementation */static RMuint64 round_int_div(RMuint64 numerator, RMuint32 divisor) { RMuint64 temp; temp = numerator / divisor; if ((numerator % divisor) * 2 > divisor) temp++; return temp;}static RMstatus init_private_options(struct priv_cmdline *options){ options->dummy = 0; return RM_OK;}#ifndef WITH_MONOstatic void show_usage(char *progname){ show_playback_options(); show_display_options(); show_video_options(); show_audio_options(); fprintf(stderr, "DEBUG OPTIONS:\n" "\t-bypassDecryption: bypass payload decryption\n" "\t-linear_playback: perform linear playback, that is, avoids seeking\n" "\t-monitor: monitor fifos and xfer tasks status\n" "-------------------------------------------------------------------\n" "Minimum cmd line: %s -pv [video codec] -c [audio codec] <file name>\n" "-------------------------------------------------------------------\n", progname); exit(1);}static void parse_cmdline(struct asf_context *pSendContext, int argc, char *argv[]){ int i; RMstatus err; if (argc < 2) show_usage(argv[0]); i = 1; while ((argc > i)) { if (argv[i][0] != '-') { if (pSendContext->play_opt->filename == NULL) { pSendContext->play_opt->filename = argv[i]; i++; } else show_usage(argv[0]); } else { RMDBGLOG((ENABLE,"command = %s\n", argv[i])); if (! strcmp(argv[i], "-bypassDecryption")) { pSendContext->bypass_drm = TRUE; i++; continue; } if (! strcmp(argv[i], "-linear_playback")) { pSendContext->linear_playback = TRUE; i++; continue; } if (! strcmp(argv[i], "-monitor")) { pSendContext->monitorFIFOs = TRUE; i++; continue; } err = parse_playback_cmdline(argc, argv, &i, pSendContext->play_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_display_cmdline(argc, argv, &i, pSendContext->disp_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_video_cmdline(argc, argv, &i, pSendContext->video_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; err = parse_audio_cmdline2(argc, argv, &i, pSendContext->audio_opt, MAX_AUDIO_DECODER_INSTANCES, &pSendContext->audioInstances); if (RMFAILED(err)) show_usage(argv[0]); } } if (pSendContext->play_opt->filename == NULL) show_usage(argv[0]);}#endif // WITH_MONOstatic void print_GUID(void *context, unsigned char GUID[16], unsigned char *Name, unsigned char *Data, unsigned long long Partial_Size, unsigned long long Size) { char s[256]; sprintf(s, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", GUID[3], GUID[2], GUID[1], GUID[0], GUID[5], GUID[4], GUID[7], GUID[6], GUID[8], GUID[9], GUID[10], GUID[11], GUID[12], GUID[13], GUID[14], GUID[15]); RMDBGLOG((ENABLE, "Skipping %llu/%llu bytes (%s) (%s)\n", Partial_Size, Size, s, Name));}static void print_File_Properties(void *context, unsigned long long File_Size, unsigned long long Creation_Date, unsigned long long Data_Packets_Count, unsigned long long Play_Duration, unsigned long long Send_Duration, unsigned long long Preroll, unsigned long Minimum_Data_Packet_Size, unsigned long Maximum_Data_Packet_Size, unsigned long Maximum_Bitrate, unsigned char Broadcast, unsigned char Seekable) { RMuint64 duration; RMuint64 hour, min, sec, milisec; struct asf_context *pSendContext = (struct asf_context *) context; RMDBGLOG((ENABLE, " Send Duration = %llu ms\n", Send_Duration / 10000)); RMDBGLOG((ENABLE, " Preroll = %llu ms\n", Preroll)); RMDBGLOG((ENABLE, " Play Duration = %llu ms\n", (Play_Duration / 10000) - Preroll)); RMDBGLOG((ENABLE, " Maximum_Bitrate = %lu bits/s\n", Maximum_Bitrate)); RMDBGLOG((ENABLE, " Minimum_Data_Packet_Size = %lu, Maximum_Data_Packet_Size = %lu\n", Minimum_Data_Packet_Size, Maximum_Data_Packet_Size)); pSendContext->Preroll = Preroll; pSendContext->PrerollSET = FALSE; pSendContext->Duration = (Play_Duration / 10000) - Preroll; /* store the duration in play_opt */ pSendContext->play_opt->duration = pSendContext->Duration; pSendContext->filePropSET = TRUE; duration = pSendContext->Duration; hour = duration / (3600 * 1000); duration -= (hour * 3600 * 1000); min = duration / (60 * 1000); duration -= min * 60 * 1000; sec = duration / 1000; duration -= sec * 1000; milisec = duration; RMDBGLOG((ENABLE, ">>> Duration %ldh %ldm %lds %ldms\n", (RMuint32)hour, (RMuint32)min, (RMuint32)sec, (RMuint32)milisec)); fprintf(stderr, "duration %llu secs\n", pSendContext->Duration / 1000); RMDBGLOG((ENABLE, "\tCreation Data = %llu\n", Creation_Date)); RMDBGLOG((ENABLE, "\tFile Size = %llu %s %s\n", File_Size, ((Broadcast) ? "[Broadcast (play and send duration invalid!)]":""), ((Seekable) ? "[Seekable]":""))); RMDBGLOG((ENABLE, "\tData Packets Count = %llu\n", Data_Packets_Count)); }static void print_Stream_Bitrate_Properties(void *context, unsigned char Stream_Number, unsigned long Average_Bitrate) { RMDBGLOG((ENABLE, " Stream #%hu: %lu bits/second\n", Stream_Number, Average_Bitrate));}static RMbool parseVC1SeqHeader(struct asf_context *pSendContext, RMuint8 *buffer, RMuint32 size){ RMuint32 i; RMuint32 entryHeaderFound = 0; RMuint32 entryHeaderSize = 0; if (size < 3) return FALSE; for (i = 3; i < size; i++) { if ((entryHeaderFound) && (buffer[i-2] != 0) && (buffer[i-1] != 0) && (buffer[i] != 1)) entryHeaderSize++; if ((buffer[i-3] == 0) && (buffer[i-2] == 0) && (buffer[i-1] == 1) && (buffer[i] == 0xe)) { pSendContext->entryHeader = (buffer + i - 3); entryHeaderFound = i; } } pSendContext->entryHeaderSize = entryHeaderSize + 4; if (entryHeaderFound) { RMDBGLOG((ENABLE, "entryHeader found at i=%lu, size %lu\n", entryHeaderFound - 3, pSendContext->entryHeaderSize));#if 0 RMDBGLOG((ENABLE, "hacking it by clearing Broken_link and setting Closed_entry\n")); *(pSendContext->entryHeader + 4) = *(pSendContext->entryHeader + 4) | 0xC;#endif for (i = 0; i < pSendContext->entryHeaderSize; i++) fprintf(stderr, "0x%02X ", *(pSendContext->entryHeader + i)); fprintf(stderr, "\n"); return TRUE; } return FALSE;}static void print_Video_Stream_Properties(void *context, unsigned char Stream_Number, unsigned long Compression_ID, unsigned long Image_Width, unsigned long Image_Height, unsigned char *Codec_Specific_Data, unsigned long Partial_Codec_Specific_Data_Size, unsigned long Codec_Specific_Data_Size) { struct asf_context *pSendContext = (struct asf_context *) context;#ifdef _DEBUG int i, j;#endif RMstatus status; if (!pSendContext->SendVideoData) { RMDBGLOG((ENABLE, ">>> video disabled by cmdline, skip video detection\n")); return; } RMDBGLOG((ENABLE, "Stream #%hu - Video\n", Stream_Number)); if (pSendContext->VideoStreamFound) { RMDBGLOG((ENABLE, ">>> there's a video stream already setup, skip this one\n")); return; } if (Partial_Codec_Specific_Data_Size) { if(pSendContext->Video_Codec_Specific_Data_Received == 0) RMDBGLOG((ENABLE, " Video Codec Specific Data: (%lu bytes, partial size %lu)\n", Codec_Specific_Data_Size, Partial_Codec_Specific_Data_Size));#ifdef _DEBUG for(i = 0; i < (int)Partial_Codec_Specific_Data_Size; i++) { for(j = 7; j >= 0; j--) fprintf(stderr, "%c", (((*(Codec_Specific_Data + i)) >> j) & 1) + 48); } fprintf(stderr, "\n"); for(i = 0; i < (int)Partial_Codec_Specific_Data_Size; i++) { fprintf(stderr, "0x%02X ", *(Codec_Specific_Data + i)); }#endif pSendContext->Video_Codec_Specific_Data_Received += Partial_Codec_Specific_Data_Size;#ifdef _DEBUG if (pSendContext->Video_Codec_Specific_Data_Received == Codec_Specific_Data_Size) fprintf(stderr, "\n");#endif }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -