void YKDumpFile::Init() { if (m_pCrashHandler) return; #if YK_OS == YK_OS_WINDOWS_NT m_pCrashHandler = new google_breakpad::ExceptionHandler(GetDumpPath().c_str(), YK_NULL, onMinidumpDumped, YK_NULL, google_breakpad::ExceptionHandler::HANDLER_ALL, MINIDUMP_TYPE::MiniDumpNormal, (HANDLE)YK_NULL, YK_NULL); #elif YK_OS == YK_OS_LINUX_ google_breakpad::MinidumpDescriptor descriptor("."); m_pCrashHandler = new google_breakpad::ExceptionHandler(descriptor, NULL, onMinidumpDumped, NULL, true, -1); #endif }
bool AVIDump::CreateVideoFile() { const std::string& format = g_Config.sDumpFormat; const std::string dump_path = GetDumpPath(format); if (dump_path.empty()) return false; File::CreateFullPath(dump_path); AVOutputFormat* output_format = av_guess_format(format.c_str(), dump_path.c_str(), nullptr); if (!output_format) { ERROR_LOG(VIDEO, "Invalid format %s", format.c_str()); return false; } if (avformat_alloc_output_context2(&s_format_context, output_format, nullptr, dump_path.c_str()) < 0) { ERROR_LOG(VIDEO, "Could not allocate output context"); return false; } const std::string& codec_name = g_Config.bUseFFV1 ? "ffv1" : g_Config.sDumpCodec; AVCodecID codec_id = output_format->video_codec; if (!codec_name.empty()) { const AVCodecDescriptor* codec_desc = avcodec_descriptor_get_by_name(codec_name.c_str()); if (codec_desc) codec_id = codec_desc->id; else WARN_LOG(VIDEO, "Invalid codec %s", codec_name.c_str()); } const AVCodec* codec = nullptr; if (!g_Config.sDumpEncoder.empty()) { codec = avcodec_find_encoder_by_name(g_Config.sDumpEncoder.c_str()); if (!codec) WARN_LOG(VIDEO, "Invalid encoder %s", g_Config.sDumpEncoder.c_str()); } if (!codec) codec = avcodec_find_encoder(codec_id); s_codec_context = avcodec_alloc_context3(codec); if (!codec || !s_codec_context) { ERROR_LOG(VIDEO, "Could not find encoder or allocate codec context"); return false; } // Force XVID FourCC for better compatibility if (codec->id == AV_CODEC_ID_MPEG4) s_codec_context->codec_tag = MKTAG('X', 'V', 'I', 'D'); s_codec_context->codec_type = AVMEDIA_TYPE_VIDEO; s_codec_context->bit_rate = g_Config.iBitrateKbps * 1000; s_codec_context->width = s_width; s_codec_context->height = s_height; s_codec_context->time_base.num = 1; s_codec_context->time_base.den = VideoInterface::GetTargetRefreshRate(); s_codec_context->gop_size = 12; s_codec_context->pix_fmt = g_Config.bUseFFV1 ? AV_PIX_FMT_BGRA : AV_PIX_FMT_YUV420P; if (output_format->flags & AVFMT_GLOBALHEADER) s_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; if (avcodec_open2(s_codec_context, codec, nullptr) < 0) { ERROR_LOG(VIDEO, "Could not open codec"); return false; } s_src_frame = av_frame_alloc(); s_scaled_frame = av_frame_alloc(); s_scaled_frame->format = s_codec_context->pix_fmt; s_scaled_frame->width = s_width; s_scaled_frame->height = s_height; #if LIBAVCODEC_VERSION_MAJOR >= 55 if (av_frame_get_buffer(s_scaled_frame, 1)) return false; #else if (avcodec_default_get_buffer(s_codec_context, s_scaled_frame)) return false; #endif s_stream = avformat_new_stream(s_format_context, codec); if (!s_stream || !AVStreamCopyContext(s_stream, s_codec_context)) { ERROR_LOG(VIDEO, "Could not create stream"); return false; } NOTICE_LOG(VIDEO, "Opening file %s for dumping", s_format_context->filename); if (avio_open(&s_format_context->pb, s_format_context->filename, AVIO_FLAG_WRITE) < 0 || avformat_write_header(s_format_context, nullptr)) { ERROR_LOG(VIDEO, "Could not open %s", s_format_context->filename); return false; } OSD::AddMessage(StringFromFormat("Dumping Frames to \"%s\" (%dx%d)", s_format_context->filename, s_width, s_height)); return true; }