int AvxContext::OutputAudio() { FILE *sink; void *writeBuffer = NULL; sighandler_t old_sigpipe = signal(SIGPIPE, SIG_IGN); if (launchMPlayer) { char command[1024]; if (MPlayerCommandAudio(command)) return -1; AVXLOG_INFO("MPlayer command line: %s", command); sink = popen(command, "w"); if (!sink) { AVXLOG_ERROR("%s", "Error starting mplayer"); return -1; } } else { sink = stdout; } #define AUDIO_SAMPLES 1000 try { writeBuffer = malloc(vi.BytesPerAudioSample() * AUDIO_SAMPLES); if (!writeBuffer) { AVXLOG_ERROR("%s", "Unable to allocate memory"); goto fail; } for (__int64 i = 0; i < vi.num_audio_samples; i += AUDIO_SAMPLES) { if (launchMPlayer && (feof(sink) || ferror(sink))) { AVXLOG_ERROR("%s", "mplayer process exited"); break; } int read_samples; if (vi.num_audio_samples - AUDIO_SAMPLES < i) read_samples = vi.num_audio_samples - i; else read_samples = AUDIO_SAMPLES; clip->GetAudio(writeBuffer, i, read_samples, avx_library.env); fwrite(writeBuffer, vi.BytesPerAudioSample(), read_samples, sink); } } catch (AvisynthError &e) { AVXLOG_ERROR("AvisynthError: %s", e.msg); goto fail; } #undef AUDIO_SAMPLES free(writeBuffer); if (launchMPlayer) pclose(sink); signal(SIGPIPE, old_sigpipe); return 0; fail: if (writeBuffer) free(writeBuffer); if (launchMPlayer) pclose(sink); signal(SIGPIPE, old_sigpipe); return -1; }
/// @brief Read from environment /// @param _clip /// void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) { AVSValue script; // Check if it has audio VideoInfo vi = _clip.AsClip()->GetVideoInfo(); if (!vi.HasAudio()) throw agi::AudioDataNotFoundError("No audio found.", 0); IScriptEnvironment *env = avs_wrapper.GetEnv(); // Convert to one channel char buffer[1024]; strcpy(buffer,lagi_wxString(OPT_GET("Audio/Downmixer")->GetString()).mb_str(csConvLocal)); script = env->Invoke(buffer, _clip); // Convert to 16 bits per sample script = env->Invoke("ConvertAudioTo16bit", script); vi = script.AsClip()->GetVideoInfo(); // Convert sample rate int setsample = OPT_GET("Provider/Audio/AVS/Sample Rate")->GetInt(); if (vi.SamplesPerSecond() < 32000) setsample = 44100; if (setsample != 0) { AVSValue args[2] = { script, setsample }; script = env->Invoke("ResampleAudio", AVSValue(args,2)); } // Set clip PClip tempclip = script.AsClip(); vi = tempclip->GetVideoInfo(); // Read properties channels = vi.AudioChannels(); num_samples = vi.num_audio_samples; sample_rate = vi.SamplesPerSecond(); bytes_per_sample = vi.BytesPerAudioSample(); float_samples = false; clip = tempclip; }
int main(int argc, TCHAR* argv[]) { SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); printf("Usage: filmtester <avs filename> [duplicates_maxlength=2]\n"); printf("The program plays the AVS file and tests for frame duplicates\n\n"); int duplicates_maxlength = 2; if (argc < 2) { printf("No filename specified.\n\n"); return -1; } if (argc > 2) { duplicates_maxlength = _ttoi(argv[2]); printf("INFO: duplicates_maxlength set to %d\n", duplicates_maxlength); } IScriptEnvironment *env = CreateScriptEnvironment(); _tprintf(_T("Loading \"%s\" ...\n"), argv[1]); LPCSTR arg_names[1] = { nullptr }; AVSValue arg_vals[1] = { (LPCSTR)argv[1] }; clip = env->Invoke("import", AVSValue(arg_vals,1), arg_names).AsClip(); printf("AVS file loaded successfully.\n\n"); VideoInfo vi = clip->GetVideoInfo(); printf("VideoInfo:\n"); printf("-----------\n"); if (vi.HasVideo()) { printf("width x height: %dx%d\n", vi.width, vi.height); printf("num_frames: %d\n", vi.num_frames); printf("fps: %d/%d\n", vi.fps_numerator, vi.fps_denominator); std::string colorspace; if (vi.pixel_type & VideoInfo::CS_BGR) colorspace += "BGR, "; if (vi.pixel_type & VideoInfo::CS_YUV) colorspace += "YUV, "; if (vi.pixel_type & VideoInfo::CS_INTERLEAVED) colorspace += "INTERLEAVED, "; if (vi.pixel_type & VideoInfo::CS_PLANAR) colorspace += "PLANAR, "; if (colorspace.length() > 0) colorspace.erase(colorspace.length()-2); printf("colorspace: %s\n", colorspace.c_str()); std::string colorformat; if (vi.pixel_type & VideoInfo::CS_BGR24) colorformat += "BGR24, "; if (vi.pixel_type & VideoInfo::CS_BGR32) colorformat += "BGR32, "; if (vi.pixel_type & VideoInfo::CS_YUY2) colorformat += "YUY2, "; if (vi.pixel_type & VideoInfo::CS_YV12) colorformat += "YV12, "; if (vi.pixel_type & VideoInfo::CS_I420) colorformat += "I420 (IYUV), "; if (colorformat.length() > 0) colorformat.erase(colorformat.length()-2); else colorformat = "UNKNOWN"; printf("colorformat: %s\n", colorformat.c_str()); std::string imagetype; if (vi.image_type & VideoInfo::IT_BFF) imagetype += "BFF, "; if (vi.image_type & VideoInfo::IT_TFF) imagetype += "TFF, "; if (vi.image_type & VideoInfo::IT_FIELDBASED) imagetype += "FIELDBASED, "; if (imagetype.length() > 0) imagetype.erase(imagetype.length()-2); else imagetype = "UNKNOWN"; printf("image_type: %s\n", imagetype.c_str()); printf("bits per pixel: %d\n", vi.BitsPerPixel()); } else printf("NO VIDEO\n"); if (vi.HasAudio()) { printf("audio channels: %d\n", vi.nchannels); printf("sample_type: %x\n", vi.sample_type); printf("samples per second: %d\n", vi.audio_samples_per_second); printf("bytes per channel sample: %d\n", vi.BytesPerChannelSample()); printf("bytes per audio sample: %d\n", vi.BytesPerAudioSample()); printf("num_audio_samples: %lld\n", vi.num_audio_samples); } else printf("NO AUDIO\n"); printf("-----------\n\n"); if (!vi.HasVideo()) { printf("Can't start video playback for the sequence without video.\n\n"); return -1; } printf("Starting playback ...\n"); prev_frame = clip->GetFrame(0, env); int framesize = prev_frame->GetFrameBuffer()->GetDataSize(); printf("INFO: framesize = %d bytes.\n\n", framesize); InitializeCriticalSection(&cs); SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE); int error_count = 0; int dup_start_frame = 0; bool flag_dup = false; std::vector<std::pair<int, int>> duplicates; for(int i=1; i<vi.num_frames; ++i) { EnterCriticalSection(&cs); dst = clip->GetFrame(i, env); const BYTE *src_ptr = prev_frame->GetFrameBuffer()->GetReadPtr(); const BYTE *dst_ptr = dst->GetFrameBuffer()->GetReadPtr(); if (!memcmp(src_ptr, dst_ptr, framesize)) { if (!flag_dup) { flag_dup = true; dup_start_frame = i-1; } } else if (flag_dup) { int length = (i-1) - dup_start_frame; if (length >= duplicates_maxlength) { printf("\rfilmtester: duplication interval: %d..%d" SPACES "\n", dup_start_frame, i-1); duplicates.push_back(std::make_pair(dup_start_frame, i-1)); error_count++; } flag_dup = false; } prev_frame = dst; LeaveCriticalSection(&cs); printf("\r[%5.1f%%] [%d errors] %d/%d frame processing", (float)((i+1)*100)/vi.num_frames, error_count, i+1, vi.num_frames); } EnterCriticalSection(&cs); if (flag_dup) { int i = vi.num_frames; int length = (i-1) - dup_start_frame; if (length >= duplicates_maxlength) { printf("\rfilmtester: duplication interval: %d..%d" SPACES "\n", dup_start_frame, i-1); duplicates.push_back(std::make_pair(dup_start_frame, i-1)); error_count++; } flag_dup = false; } printf("\rProcessing completed." SPACES "\n\n"); printf("%d errors\n", error_count); printf("\n"); if (error_count > 0) { printf("Erroneous intervals (%d):\n", duplicates.size()); for(auto it = duplicates.begin(); it != duplicates.end(); ++it) printf("%5d .. %d\n", it->first, it->second); printf("\n"); } dst = nullptr; prev_frame = nullptr; clip = nullptr; LeaveCriticalSection(&cs); DeleteCriticalSection(&cs); return error_count; }
extern "C" HRESULT __stdcall get_stream_info(VF_FileHandle in, DWORD stream, void *out) { if (stream == VF_STREAM_VIDEO) { LPVF_StreamInfo_Video info = (LPVF_StreamInfo_Video)out; if (info == NULL) return VF_ERROR; if (info->dwSize != sizeof(VF_StreamInfo_Video)) return VF_ERROR; vfMI *i = (vfMI*)in; if (i->type == D2V_TYPE) { info->dwLengthL = i->vi->num_frames; if (i->vi->fps_denominator) info->dwRate = i->vi->fps_numerator; else info->dwRate = 0; info->dwScale = i->vi->fps_denominator; info->dwWidth = i->vi->width; info->dwHeight = i->vi->height; } else { const VideoInfo vit = (*i->clip)->GetVideoInfo(); info->dwLengthL = vit.num_frames; if (vit.fps_denominator) info->dwRate = vit.fps_numerator; else info->dwRate = 0; info->dwScale = vit.fps_denominator; info->dwWidth = vit.width; info->dwHeight = vit.height; } info->dwBitCount = 24; } else if (stream == VF_STREAM_AUDIO) { LPVF_StreamInfo_Audio info = (LPVF_StreamInfo_Audio)out; if (info == NULL) return VF_ERROR; if (info->dwSize != sizeof(VF_StreamInfo_Audio)) return VF_ERROR; vfMI *i = (vfMI*)in; if (i->type == D2V_TYPE) return VF_ERROR; else { const VideoInfo vit = (*i->clip)->GetVideoInfo(); if (!vit.HasAudio()) return VF_ERROR; info->dwLengthL = (unsigned long)vit.num_audio_samples; info->dwChannels = vit.nchannels; info->dwRate = vit.audio_samples_per_second * vit.BytesPerAudioSample(); info->dwScale = vit.BytesPerAudioSample(); info->dwBitsPerSample = vit.BytesPerChannelSample()*8; info->dwBlockAlign = vit.BytesPerAudioSample(); } } else return VF_ERROR; return VF_OK; }